diff --git a/mmv1/products/monitoring/api.yaml b/mmv1/products/monitoring/api.yaml index e134ff8353f8..e979e0a2330a 100644 --- a/mmv1/products/monitoring/api.yaml +++ b/mmv1/products/monitoring/api.yaml @@ -1084,6 +1084,86 @@ objects: The full name of the resource that defines this service. Formatted as described in https://cloud.google.com/apis/design/resource_names. + + - !ruby/object:Api::Resource + name: GenericService + base_url: v3/projects/{{project}}/services + create_url: v3/projects/{{project}}/services?serviceId={{service_id}} + self_link: "v3/projects/{{project}}/services/{{service_id}}" + update_verb: :PATCH + update_mask: true + description: | + A Service is a discrete, autonomous, and network-accessible unit, + designed to solve an individual concern (Wikipedia). In Cloud Monitoring, + a Service acts as the root resource under which operational aspects of + the service are accessible + references: !ruby/object:Api::Resource::ReferenceLinks + guides: + 'Service Monitoring': 'https://cloud.google.com/monitoring/service-monitoring' + 'Monitoring API Documentation': 'https://cloud.google.com/monitoring/api/v3/' + api: 'https://cloud.google.com/monitoring/api/ref_v3/rest/v3/services' + parameters: + - !ruby/object:Api::Type::String + name: serviceId + description: | + An optional service ID to use. If not given, the server will generate a + service ID. + input: true + required: true + url_param_only: true + properties: + - !ruby/object:Api::Type::String + name: name + description: | + The full resource name for this service. The syntax is: + projects/[PROJECT_ID]/services/[SERVICE_ID]. + output: true + - !ruby/object:Api::Type::String + name: displayName + description: | + Name used for UI elements listing this Service. + - !ruby/object:Api::Type::KeyValuePairs + name: 'userLabels' + description: | + Labels which have been used to annotate the service. Label keys must start + with a letter. Label keys and values may contain lowercase letters, + numbers, underscores, and dashes. Label keys and values have a maximum + length of 63 characters, and must be less than 128 bytes in size. Up to 64 + label entries may be stored. For labels which do not have a semantic value, + the empty string may be supplied for the label value. + send_empty_value: true + - !ruby/object:Api::Type::NestedObject + name: telemetry + description: | + Configuration for how to query telemetry on a Service. + # Non custom service have non-editable telemetry + output: true + properties: + - !ruby/object:Api::Type::String + name: resourceName + description: | + The full name of the resource that defines this service. + Formatted as described in + https://cloud.google.com/apis/design/resource_names. + - !ruby/object:Api::Type::NestedObject + name: basicService + description: | + A well-known service type, defined by its service type and service labels. + # BasicService info can be set on creation but is then immutable. + input: true + properties: + - !ruby/object:Api::Type::String + name: serviceType + description: | + The type of service that this basic service defines, e.g. + APP_ENGINE service type + - !ruby/object:Api::Type::KeyValuePairs + name: serviceLabels + input: true + description: | + Labels that specify the resource that emits the monitoring data + which is used for SLO reporting of this `Service`. + - !ruby/object:Api::Resource name: Slo diff --git a/mmv1/products/monitoring/terraform.yaml b/mmv1/products/monitoring/terraform.yaml index 742f227a531b..a7961dbc3450 100644 --- a/mmv1/products/monitoring/terraform.yaml +++ b/mmv1/products/monitoring/terraform.yaml @@ -155,6 +155,18 @@ overrides: !ruby/object:Overrides::ResourceOverrides custom_import: templates/terraform/custom_import/self_link_as_name.erb encoder: templates/terraform/encoders/monitoring_service.go.erb + GenericService: !ruby/object:Overrides::Terraform::ResourceOverride + legacy_name: 'google_monitoring_service' + id_format: "projects/{{project}}/services/{{service_id}}" + import_format: ["projects/{{project}}/services/{{service_id}}"] + error_retry_predicates: ["isMonitoringConcurrentEditError"] + examples: + - !ruby/object:Provider::Terraform::Examples + name: "monitoring_service_example" + primary_resource_id: "my_service" + vars: + service_id: "my-service" + Slo: !ruby/object:Overrides::Terraform::ResourceOverride id_format: "{{name}}" import_format: ["{{name}}"] diff --git a/mmv1/templates/terraform/examples/monitoring_service_example.tf.erb b/mmv1/templates/terraform/examples/monitoring_service_example.tf.erb new file mode 100644 index 000000000000..2e84d2c0235e --- /dev/null +++ b/mmv1/templates/terraform/examples/monitoring_service_example.tf.erb @@ -0,0 +1,16 @@ +resource "google_monitoring_service" "<%= ctx[:primary_resource_id] -%>" { + service_id = "<%= ctx[:vars]['service_id'] -%>" + display_name = "My Service <%= ctx[:vars]['service_id'] -%>" + + user_labels = { + my_key = "my_value" + my_other_key = "my_other_value" + } + + basic_service { + service_type = "APP_ENGINE" + service_labels = { + module_id = "another-module-id" + } + } +} diff --git a/mmv1/third_party/terraform/tests/resource_monitoring_service_test.go b/mmv1/third_party/terraform/tests/resource_monitoring_service_test.go new file mode 100644 index 000000000000..59096315d9be --- /dev/null +++ b/mmv1/third_party/terraform/tests/resource_monitoring_service_test.go @@ -0,0 +1,52 @@ +package google + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccMonitoringService_basic(t *testing.T) { + t.Parallel() + + randomSuffix := randString(t, 10) + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckMonitoringServiceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccMonitoringSlo_cloudEndpoints(randomSuffix, "an-endpoint"), + }, + { + ResourceName: "google_monitoring_service.srv", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccMonitoringSlo_cloudEndpoints(randomSuffix, "another-endpoint"), + }, + { + ResourceName: "google_monitoring_service.srv", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccMonitoringSlo_cloudEndpoints(randSuffix, endpoint string) string { + return fmt.Sprintf(` +resource "google_monitoring_service" "srv" { + service_id = "tf-test-srv-%s" + display_name = "My Basic CloudEnpoints Service" + basic_service { + service_type = "CLOUD_ENDPOINTS" + service_labels = { + service = "%s" + } + } +} +`, randSuffix, endpoint) +} diff --git a/mmv1/third_party/terraform/tests/resource_monitoring_slo_test.go b/mmv1/third_party/terraform/tests/resource_monitoring_slo_test.go index dcbcaaa7f938..85bbbca35230 100644 --- a/mmv1/third_party/terraform/tests/resource_monitoring_slo_test.go +++ b/mmv1/third_party/terraform/tests/resource_monitoring_slo_test.go @@ -410,6 +410,30 @@ func TestAccMonitoringSlo_windowBasedMetricSumRangeSlis(t *testing.T) { }) } +func TestAccMonitoringSlo_genericService(t *testing.T) { + t.Parallel() + + randomSuffix := randString(t, 10) + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckMonitoringSloDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccMonitoringSlo_generic(randomSuffix), + }, + { + ResourceName: "google_monitoring_slo.primary", + ImportState: true, + ImportStateVerify: true, + // Ignore input-only field for import + ImportStateVerifyIgnore: []string{"service"}, + }, + }, + }) +} + func testAccMonitoringSlo_basic() string { return ` data "google_monitoring_app_engine_service" "ae" { @@ -457,6 +481,34 @@ resource "google_monitoring_slo" "primary" { ` } +func testAccMonitoringSlo_generic(randSuffix string) string { + return fmt.Sprintf(` +resource "google_monitoring_service" "srv" { + service_id = "tf-test-srv-%s" + display_name = "My Basic CloudEnpoints Service" + basic_service { + service_type = "CLOUD_ENDPOINTS" + service_labels = { + service = "another-endpoint" + } + } +} + + +resource "google_monitoring_slo" "primary" { + service = google_monitoring_service.srv.service_id + + goal = 0.9 + rolling_period_days = 1 + + basic_sli { + availability { + } + } +} +`, randSuffix) +} + func testAccMonitoringSlo_availabilitySli() string { return ` data "google_monitoring_app_engine_service" "ae" {