diff --git a/mmv1/products/apphub/Application.yaml b/mmv1/products/apphub/Application.yaml new file mode 100644 index 000000000000..fbac56d6ba63 --- /dev/null +++ b/mmv1/products/apphub/Application.yaml @@ -0,0 +1,189 @@ +# 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. + +--- !ruby/object:Api::Resource +base_url: projects/{{project}}/locations/{{location}}/applications +create_url: projects/{{project}}/locations/{{location}}/applications?applicationId={{application_id}} +self_link: projects/{{project}}/locations/{{location}}/applications/{{application_id}} +id_format: projects/{{project}}/locations/{{location}}/applications/{{application_id}} +import_format: + - projects/{{project}}/locations/{{location}}/applications/{{application_id}} +name: Application +description: 'Application is a functional grouping of Services and Workloads that helps achieve a desired end-to-end business functionality. + Services and Workloads are owned by the Application.' +autogen_async: true +examples: + - !ruby/object:Provider::Terraform::Examples + name: "application_basic" + primary_resource_id: "example" + config_path: "templates/terraform/examples/apphub_application_basic.tf.erb" + vars: + application_id: "example-application" + - !ruby/object:Provider::Terraform::Examples + name: "application_full" + primary_resource_id: "example2" + config_path: "templates/terraform/examples/apphub_application_full.tf.erb" + vars: + application_id: "example-application" + display_name: "Application Full" + description: "Application for testing" + business_name: "Alice" + business_email: "alice@google.com" + developer_name: "Bob" + developer_email: "bob@google.com" + operator_name: "Charlie" + operator_email: "charlie@google.com" +properties: + - !ruby/object:Api::Type::String + name: name + output: true + description: "Identifier. The resource name of an Application. Format:\n\"projects/{host-project-id}/locations/{location}/applications/{application-id}\" " + - !ruby/object:Api::Type::String + name: displayName + description: 'Optional. User-defined name for the Application. ' + - !ruby/object:Api::Type::String + name: description + description: 'Optional. User-defined description of an Application. ' + - !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::Enum + name: type + description: 'Criticality type. ' + required: true + values: + - :MISSION_CRITICAL + - :HIGH + - :MEDIUM + - :LOW + name: criticality + description: 'Criticality of the Application, Service, or Workload ' + - !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::Enum + name: type + description: 'Environment type. ' + required: true + values: + - :PRODUCTION + - :STAGING + - :TEST + - :DEVELOPMENT + name: environment + description: 'Environment of the Application, Service, or Workload ' + - !ruby/object:Api::Type::Array + name: developerOwners + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: displayName + description: 'Optional. Contact''s name. ' + - !ruby/object:Api::Type::String + name: email + required: true + description: 'Required. Email address of the contacts. ' + description: 'Optional. Developer team that owns development and coding. ' + - !ruby/object:Api::Type::Array + name: operatorOwners + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: displayName + description: 'Optional. Contact''s name. ' + - !ruby/object:Api::Type::String + name: email + required: true + description: 'Required. Email address of the contacts. ' + description: 'Optional. Operator team that ensures runtime and operations. ' + - !ruby/object:Api::Type::Array + name: businessOwners + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: displayName + description: 'Optional. Contact''s name. ' + - !ruby/object:Api::Type::String + name: email + required: true + description: 'Required. Email address of the contacts. ' + description: 'Optional. Business team that ensures user needs are met and value + is delivered ' + name: attributes + description: 'Consumer provided attributes. ' + - !ruby/object:Api::Type::String + name: createTime + description: 'Output only. Create time. ' + output: true + - !ruby/object:Api::Type::String + name: updateTime + description: 'Output only. Update time. ' + output: true + - !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::Enum + name: type + description: "Required. Scope Type. \n Possible values:\nREGIONAL" + required: true + values: + - :REGIONAL + name: scope + description: 'Scope of an application. ' + required: true + - !ruby/object:Api::Type::String + name: uid + description: 'Output only. A universally unique identifier (in UUID4 format) for + the `Application`. ' + output: true + - !ruby/object:Api::Type::Enum + name: state + description: "Output only. Application state. \n Possible values:\n STATE_UNSPECIFIED\nCREATING\nACTIVE\nDELETING" + output: true + values: + - :STATE_UNSPECIFIED + - :CREATING + - :ACTIVE + - :DELETING +parameters: + - !ruby/object:Api::Type::String + name: location + description: 'Part of `parent`. See documentation of `projectsId`. ' + url_param_only: true + required: true + immutable: true + - !ruby/object:Api::Type::String + name: applicationId + description: 'Required. The Application identifier. ' + url_param_only: true + required: true + immutable: true +async: !ruby/object:Api::OpAsync + operation: !ruby/object:Api::OpAsync::Operation + path: name + base_url: "{{op_id}}" + wait_ms: 1000 + timeouts: + result: !ruby/object:Api::OpAsync::Result + path: response + resource_inside_response: true + status: !ruby/object:Api::OpAsync::Status + path: done + complete: true + allowed: + - true + - false + error: !ruby/object:Api::OpAsync::Error + path: error + message: message +update_verb: :PATCH +update_mask: true diff --git a/mmv1/products/apphub/product.yaml b/mmv1/products/apphub/product.yaml new file mode 100644 index 000000000000..4df439355736 --- /dev/null +++ b/mmv1/products/apphub/product.yaml @@ -0,0 +1,23 @@ +# 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. + + +--- !ruby/object:Api::Product +name: Apphub +display_name: App Hub +versions: + - !ruby/object:Api::Product::Version + name: ga + base_url: https://apphub.googleapis.com/v1/ +scopes: + - https://www.googleapis.com/auth/cloud-platform diff --git a/mmv1/templates/terraform/examples/apphub_application_basic.tf.erb b/mmv1/templates/terraform/examples/apphub_application_basic.tf.erb new file mode 100644 index 000000000000..7b7c50231dca --- /dev/null +++ b/mmv1/templates/terraform/examples/apphub_application_basic.tf.erb @@ -0,0 +1,7 @@ +resource "google_apphub_application" "<%= ctx[:primary_resource_id] %>" { + location = "us-east1" + application_id = "<%= ctx[:vars]['application_id'] %>" + scope { + type = "REGIONAL" + } +} diff --git a/mmv1/templates/terraform/examples/apphub_application_full.tf.erb b/mmv1/templates/terraform/examples/apphub_application_full.tf.erb new file mode 100644 index 000000000000..42d9de520464 --- /dev/null +++ b/mmv1/templates/terraform/examples/apphub_application_full.tf.erb @@ -0,0 +1,29 @@ +resource "google_apphub_application" "<%= ctx[:primary_resource_id] %>" { + location = "us-east1" + application_id = "<%= ctx[:vars]['application_id'] %>" + display_name = "<%= ctx[:vars]['display_name'] %>" + scope { + type = "REGIONAL" + } + description = "<%= ctx[:vars]['description'] %>" + attributes { + environment { + type = "STAGING" + } + criticality { + type = "MISSION_CRITICAL" + } + business_owners { + display_name = "<%= ctx[:vars]['business_name'] %>" + email = "<%= ctx[:vars]['business_email'] %>" + } + developer_owners { + display_name = "<%= ctx[:vars]['developer_name'] %>" + email = "<%= ctx[:vars]['developer_email'] %>" + } + operator_owners { + display_name = "<%= ctx[:vars]['operator_name'] %>" + email = "<%= ctx[:vars]['operator_email'] %>" + } + } +} diff --git a/mmv1/third_party/terraform/.teamcity/components/inputs/services_beta.kt b/mmv1/third_party/terraform/.teamcity/components/inputs/services_beta.kt index 27550dabce13..443987885a6f 100644 --- a/mmv1/third_party/terraform/.teamcity/components/inputs/services_beta.kt +++ b/mmv1/third_party/terraform/.teamcity/components/inputs/services_beta.kt @@ -48,6 +48,11 @@ var ServicesListBeta = mapOf( "displayName" to "Appengine", "path" to "./google-beta/services/appengine" ), + "apphub" to mapOf( + "name" to "apphub", + "displayName" to "Apphub", + "path" to "./google-beta/services/apphub" + ), "artifactregistry" to mapOf( "name" to "artifactregistry", "displayName" to "Artifactregistry", diff --git a/mmv1/third_party/terraform/.teamcity/components/inputs/services_ga.kt b/mmv1/third_party/terraform/.teamcity/components/inputs/services_ga.kt index 51f98ed08a05..08ce6c2ee82f 100644 --- a/mmv1/third_party/terraform/.teamcity/components/inputs/services_ga.kt +++ b/mmv1/third_party/terraform/.teamcity/components/inputs/services_ga.kt @@ -48,6 +48,11 @@ var ServicesListGa = mapOf( "displayName" to "Appengine", "path" to "./google/services/appengine" ), + "apphub" to mapOf( + "name" to "apphub", + "displayName" to "Apphub", + "path" to "./google/services/apphub" + ), "artifactregistry" to mapOf( "name" to "artifactregistry", "displayName" to "Artifactregistry", diff --git a/mmv1/third_party/terraform/services/apphub/resource_apphub_application_test.go b/mmv1/third_party/terraform/services/apphub/resource_apphub_application_test.go new file mode 100644 index 000000000000..3e68916cc73e --- /dev/null +++ b/mmv1/third_party/terraform/services/apphub/resource_apphub_application_test.go @@ -0,0 +1,210 @@ +package apphub_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccApphubApplication_applicationUpdateFull(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckApphubApplicationDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccApphubApplication_applicationFullExample(context), + }, + { + ResourceName: "google_apphub_application.example2", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "application_id"}, + }, + { + Config: testAccApphubApplication_applicationUpdateDisplayName(context), + }, + { + ResourceName: "google_apphub_application.example2", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "application_id"}, + }, + { + Config: testAccApphubApplication_applicationUpdateEnvironment(context), + }, + { + ResourceName: "google_apphub_application.example2", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "application_id"}, + }, + { + Config: testAccApphubApplication_applicationUpdateCriticality(context), + }, + { + ResourceName: "google_apphub_application.example2", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "application_id"}, + }, + { + Config: testAccApphubApplication_applicationUpdateOwners(context), + }, + { + ResourceName: "google_apphub_application.example2", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "application_id"}, + }, + }, + }) +} + +func testAccApphubApplication_applicationUpdateDisplayName(context map[string]interface{}) string { + return acctest.Nprintf(` + +resource "google_apphub_application" "example2" { + location = "us-east1" + application_id = "tf-test-example-application%{random_suffix}" + display_name = "Application Full New%{random_suffix}" + scope { + type = "REGIONAL" + } + attributes { + environment { + type = "STAGING" + } + criticality { + type = "MISSION_CRITICAL" + } + business_owners { + display_name = "Alice%{random_suffix}" + email = "alice@google.com%{random_suffix}" + } + developer_owners { + display_name = "Bob%{random_suffix}" + email = "bob@google.com%{random_suffix}" + } + operator_owners { + display_name = "Charlie%{random_suffix}" + email = "charlie@google.com%{random_suffix}" + } + } +} +`, context) +} + +func testAccApphubApplication_applicationUpdateEnvironment(context map[string]interface{}) string { + return acctest.Nprintf(` + +resource "google_apphub_application" "example2" { + location = "us-east1" + application_id = "tf-test-example-application%{random_suffix}" + display_name = "Application Full New%{random_suffix}" + scope { + type = "REGIONAL" + } + attributes { + environment { + type = "TEST" + } + criticality { + type = "MISSION_CRITICAL" + } + business_owners { + display_name = "Alice%{random_suffix}" + email = "alice@google.com%{random_suffix}" + } + developer_owners { + display_name = "Bob%{random_suffix}" + email = "bob@google.com%{random_suffix}" + } + operator_owners { + display_name = "Charlie%{random_suffix}" + email = "charlie@google.com%{random_suffix}" + } + } +} +`, context) +} + +func testAccApphubApplication_applicationUpdateCriticality(context map[string]interface{}) string { + return acctest.Nprintf(` + +resource "google_apphub_application" "example2" { + location = "us-east1" + application_id = "tf-test-example-application%{random_suffix}" + display_name = "Application Full New%{random_suffix}" + scope { + type = "REGIONAL" + } + attributes { + environment { + type = "TEST" + } + criticality { + type = "MEDIUM" + } + business_owners { + display_name = "Alice%{random_suffix}" + email = "alice@google.com%{random_suffix}" + } + developer_owners { + display_name = "Bob%{random_suffix}" + email = "bob@google.com%{random_suffix}" + } + operator_owners { + display_name = "Charlie%{random_suffix}" + email = "charlie@google.com%{random_suffix}" + } + } +} +`, context) +} + +func testAccApphubApplication_applicationUpdateOwners(context map[string]interface{}) string { + return acctest.Nprintf(` + +resource "google_apphub_application" "example2" { + location = "us-east1" + application_id = "tf-test-example-application%{random_suffix}" + display_name = "Application Full New%{random_suffix}" + scope { + type = "REGIONAL" + } + attributes { + environment { + type = "TEST" + } + criticality { + type = "MEDIUM" + } + business_owners { + display_name = "Alice%{random_suffix}" + email = "alice@google.com%{random_suffix}" + } + developer_owners { + display_name = "Bob%{random_suffix}" + email = "bob@google.com%{random_suffix}" + } + developer_owners { + display_name = "Derek%{random_suffix}" + email = "derek@google.com%{random_suffix}" + } + operator_owners { + display_name = "Charlie%{random_suffix}" + email = "charlie@google.com%{random_suffix}" + } + } +} +`, context) +}