Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API hub product, with resource ApiHubInstance #12499

Merged
merged 8 commits into from
Jan 17, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions mmv1/products/apihub/ApiHubInstance.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

---
name: ApiHubInstance
description: |-
An ApiHubInstance represents the instance resources of the API Hub.
Currently, only one ApiHub instance is allowed for each project.
Currently, updation/deletion of ApiHub instance is not allowed.
base_url: projects/{{project}}/locations/{{location}}/apiHubInstances
immutable: true
self_link: '{{name}}'
create_url: projects/{{project}}/locations/{{location}}/apiHubInstances?apiHubInstanceId={{api_hub_instance_id}}
id_format: '{{name}}'
import_format:
- projects/{{project}}/locations/{{location}}/apiHubInstances/{{api_hub_instance_id}}
custom_code:
custom_import: 'templates/terraform/custom_import/apihub_api_hub_instance_set_id.go.tmpl'
examples:
- name: apihub_api_hub_instance_basic
primary_resource_id: apihub-instance-without-search
vars:
instance_id: test-instance-basic
exclude_test: true
- name: apihub_api_hub_instance_full
primary_resource_id: apihub-instance-search
vars:
instance_id: test-instance-full
exclude_test: true
autogen_async: true
exclude_delete: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is slightly surprising, can the instance not be deleted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, currently we do not support delete for this resource.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if I'm understanding, only one of these resources can be created per project, it is immutable, and it cannot be deleted, meaning that once an instance is created for a particular project, you can never change it, and you can't touch the Terraform config unless project is changed (because TF will attempt a re-creation, which won't work).

Is this the intended behavior? It seems a little confusing to a user to not be able to adjust their config, so perhaps we want to mention that a new project must be used somewhere in the documentation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the description of the resource, mentioning that the resource cannot be deleted/updated as of now.

async:
operation:
timeouts:
insert_minutes: 20
update_minutes: 20
delete_minutes: 20
base_url: '{{op_id}}'
actions:
- create
- delete
- update
type: OpAsync
result:
resource_inside_response: true
error: {}
include_project: false
autogen_status: QXBpSHViSW5zdGFuY2U=
parameters:
- name: location
type: String
description: Resource ID segment making up resource `name`. It identifies the resource within its parent collection as described in https://google.aip.dev/122.
immutable: true
url_param_only: true
required: true
- name: apiHubInstanceId
type: String
description: |-
Optional. Identifier to assign to the Api Hub instance. Must be unique within
scope of the parent resource. If the field is not provided,
system generated id will be used.

This value should be 4-40 characters, and valid characters
are `/a-z[0-9]-_/`.
immutable: true
url_param_only: true
properties:
- name: description
type: String
description: Optional. Description of the ApiHub instance.
- name: name
type: String
description: |-
Identifier. Format:
`projects/{project}/locations/{location}/apiHubInstances/{apiHubInstance}`.
output: true
- name: createTime
type: String
description: Output only. Creation timestamp.
output: true
- name: updateTime
type: String
description: Output only. Last update timestamp.
output: true
- name: state
type: String
description: |-
Output only. The current state of the ApiHub instance.
Possible values:
STATE_UNSPECIFIED
INACTIVE
CREATING
ACTIVE
UPDATING
DELETING
FAILED
output: true
- name: stateMessage
type: String
description: |-
Output only. Extra information about ApiHub instance state. Currently the message
would be populated when state is `FAILED`.
output: true
- name: config
type: NestedObject
description: Available configurations to provision an ApiHub Instance.
required: true
properties:
- name: encryptionType
type: String
default_from_api: true
description: |-
Optional. Encryption type for the region. If the encryption type is CMEK, the
cmek_key_name must be provided. If no encryption type is provided,
GMEK will be used.
Possible values:
ENCRYPTION_TYPE_UNSPECIFIED
GMEK
CMEK
- name: cmekKeyName
type: String
description: |-
Optional. The Customer Managed Encryption Key (CMEK) used for data encryption.
The CMEK name should follow the format of
`projects/([^/]+)/locations/([^/]+)/keyRings/([^/]+)/cryptoKeys/([^/]+)`,
where the location must match the instance location.
If the CMEK is not provided, a GMEK will be created for the instance.
- name: disableSearch
type: Boolean
description: |-
Optional. If true, the search will be disabled for the instance. The default value
is false.
- name: vertexLocation
type: String
description: Optional. The name of the Vertex AI location where the data store is stored.
- name: labels
type: KeyValueLabels
description: |-
Optional. Instance labels to represent user-provided metadata.
Refer to cloud documentation on labels for more details.
https://cloud.google.com/compute/docs/labeling-resources
21 changes: 21 additions & 0 deletions mmv1/products/apihub/product.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

---
name: Apihub
display_name: API hub
scopes:
- https://www.googleapis.com/auth/cloud-platform
versions:
- base_url: https://apihub.googleapis.com/v1/
name: ga
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
config := meta.(*transport_tpg.Config)
if err := tpgresource.ParseImportId([]string{
"^projects/(?P<project>[^/]+)/locations/(?P<location>[^/]+)/apiHubInstances/(?P<api_hub_instance_id>[^/]+)$",
"^(?P<project>[^/]+)/(?P<location>[^/]+)/(?P<api_hub_instance_id>[^/]+)$",
"^(?P<location>[^/]+)/(?P<api_hub_instance_id>[^/]+)$",
}, d, config); err != nil {
return nil, err
}

// Set name based on the components
if err := d.Set("name", "projects/{{"{{"}}project{{"}}"}}/locations/{{"{{"}}location{{"}}"}}/apiHubInstances/{{"{{"}}api_hub_instance_id{{"}}"}}"); err != nil {
return nil, fmt.Errorf("Error setting name: %s", err)
}

// Replace import id for the resource id
id, err := tpgresource.ReplaceVars(d, config, d.Get("name").(string))
if err != nil {
return nil, fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

return []*schema.ResourceData{d}, nil
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "google_apihub_api_hub_instance" "{{$.PrimaryResourceId}}"{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need some more tests to check the range of config that can be provided (see https://googlecloudplatform.github.io/magic-modules/test/test/):

  • Since this test should be minimal, is config {} valid?
  • You'll need an "update" test to confirm fields that are mutable can be updated in-place, like description and config
  • You'll need to use each field in at least one test (you can do this with the update test, or add an explicit *_full.tf.tmpl example with every possible field specified)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • config{} wont be valid. One of disable_search or vertex_location would need to be provided. Default value of disable_search would be false. But in that scenario, vertex_location would need to be provided in the config.
  • Currently update is also not supported for this resource
  • Currently only one resource/project can be provisioned. And since delete and update is not supported for this resource, was not able to add further test in the same flow. Do you have any suggestions for this scenario.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a test with all possible fields, which will be provisioned in a separate project. Hope that is fine?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For both tests, could you create a separate project for the instance? Otherwise our test environments will become polluted in a way we seemingly cannot clean up. Ie.:

resource "google_project" "project" {
  name       = "{{index $.Vars "project_id"}}"
  project_id = "{{index $.Vars "project_id"}}"
  org_id     = "{{index $.TestEnvVars "org_id"}}"
  deletion_policy = "DELETE"
}

And in the examples blocks:

    vars:
      project_id: 'apihub-proj'
    test_env_vars:
      org_id: 'ORG_ID'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, currently using exclude_test. Have created a separate bug and once one of the pre-requisite bug is competed, will remove this flag.

location = "us-central1"
config {
disable_search = true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
resource "google_apihub_api_hub_instance" "{{$.PrimaryResourceId}}"{
project = "my-project"
api_hub_instance_id = "{{index $.Vars "instance_id"}}"
description = "Test API hub instance"
location = "us-central1"
config {
encryption_type = "CMEK"
cmek_key_name = "projects/my-project/locations/us-central1/keyRings/apihub/cryptoKeys/apihub-key"
disable_search = false
vertex_location = "us"
}
labels = {
environment = "dev"
}
}
Original file line number Diff line number Diff line change
@@ -46,6 +46,11 @@ var ServicesListBeta = mapOf(
"displayName" to "Apigee",
"path" to "./google-beta/services/apigee"
),
"apihub" to mapOf(
"name" to "apihub",
"displayName" to "Apihub",
"path" to "./google-beta/services/apihub"
),
"apikeys" to mapOf(
"name" to "apikeys",
"displayName" to "Apikeys",
Original file line number Diff line number Diff line change
@@ -46,6 +46,11 @@ var ServicesListGa = mapOf(
"displayName" to "Apigee",
"path" to "./google/services/apigee"
),
"apihub" to mapOf(
"name" to "apihub",
"displayName" to "Apihub",
"path" to "./google/services/apihub"
),
"apikeys" to mapOf(
"name" to "apikeys",
"displayName" to "Apikeys",