Skip to content

Commit 2a7aab7

Browse files
akspiAkshay Pai
authored andcommitted
Add ControlPlaneAccess support for Apigee (GoogleCloudPlatform#12825)
Co-authored-by: Akshay Pai <[email protected]>
1 parent f502a52 commit 2a7aab7

File tree

3 files changed

+249
-0
lines changed

3 files changed

+249
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Copyright 2024 Google Inc.
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
---
15+
name: 'ControlPlaneAccess'
16+
description: |
17+
Authorize the Runtime components to access directly with Apigee Control Plane.
18+
references:
19+
guides:
20+
'Enable ControlPlane access': 'https://cloud.google.com/apigee/docs/hybrid/v1.14/install-enable-control-plane-access'
21+
api: 'https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations/updateControlPlaneAccess'
22+
docs:
23+
id_format: 'organizations/{{name}}/controlPlaneAccess'
24+
base_url: ''
25+
self_link: 'organizations/{{name}}/controlPlaneAccess'
26+
create_verb: 'PATCH'
27+
update_verb: 'PATCH'
28+
async:
29+
actions: ['create', 'update']
30+
type: 'OpAsync'
31+
operation:
32+
base_url: '{{op_id}}'
33+
result:
34+
resource_inside_response: true
35+
autogen_async: true
36+
update_mask: true
37+
exclude_delete: true
38+
import_format:
39+
- 'organizations/{{name}}/controlPlaneAccess'
40+
timeouts:
41+
insert_minutes: 20
42+
update_minutes: 20
43+
delete_minutes: 20
44+
custom_code:
45+
examples:
46+
- name: 'apigee_control_plane_access_basic_test'
47+
primary_resource_id: 'apigee_control_plane_access'
48+
vars:
49+
account_id: 'my-account'
50+
project_id: 'my-project'
51+
test_env_vars:
52+
org_id: 'ORG_ID'
53+
billing_account: 'BILLING_ACCT'
54+
parameters:
55+
- name: 'name'
56+
type: String
57+
description: |
58+
Name of the Apigee organization.
59+
url_param_only: true
60+
required: true
61+
immutable: true
62+
properties:
63+
- name: 'synchronizerIdentities'
64+
type: Array
65+
description: |
66+
Array of service accounts to grant access to control plane resources (for the Synchronizer component), each specified using the following format: `serviceAccount:service-account-name`.
67+
68+
The `service-account-name` is formatted like an email address. For example: serviceAccount@my_project_id.iam.gserviceaccount.com
69+
70+
You might specify multiple service accounts, for example, if you have multiple environments and wish to assign a unique service account to each one.
71+
72+
The service accounts must have **Apigee Synchronizer Manager** role. See also [Create service accounts](https://cloud.google.com/apigee/docs/hybrid/v1.8/sa-about#create-the-service-accounts).
73+
send_empty_value: true
74+
item_type:
75+
type: String
76+
- name: 'analyticsPublisherIdentities'
77+
type: Array
78+
description: |
79+
Array of service accounts authorized to publish analytics data to the control plane, each specified using the following format: `serviceAccount:service-account-name`.
80+
81+
The `service-account-name` is formatted like an email address. For example: serviceAccount@my_project_id.iam.gserviceaccount.com
82+
83+
You might specify multiple service accounts, for example, if you have multiple environments and wish to assign a unique service account to each one.
84+
send_empty_value: true
85+
item_type:
86+
type: String
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
resource "google_project" "project" {
2+
project_id = "{{index $.Vars "project_id"}}"
3+
name = "{{index $.Vars "project_id"}}"
4+
org_id = "{{index $.TestEnvVars "org_id"}}"
5+
billing_account = "{{index $.TestEnvVars "billing_account"}}"
6+
deletion_policy = "DELETE"
7+
}
8+
9+
resource "google_project_service" "apigee" {
10+
project = google_project.project.project_id
11+
service = "apigee.googleapis.com"
12+
}
13+
14+
resource "google_apigee_organization" "apigee_org" {
15+
analytics_region = "us-central1"
16+
project_id = google_project.project.project_id
17+
18+
runtime_type = "HYBRID"
19+
depends_on = [google_project_service.apigee]
20+
}
21+
22+
resource "google_service_account" "service_account" {
23+
account_id = "{{index $.Vars "account_id"}}"
24+
display_name = "Service Account"
25+
}
26+
27+
resource "google_project_iam_member" "synchronizer-iam" {
28+
project = google_project.project.project_id
29+
role = "roles/apigee.synchronizerManager"
30+
member = "serviceAccount:${google_service_account.service_account.email}"
31+
}
32+
33+
resource "google_apigee_control_plane_access" "{{$.PrimaryResourceId}}" {
34+
name = google_apigee_organization.apigee_org.name
35+
synchronizer_identities = [
36+
"serviceAccount:${google_service_account.service_account.email}",
37+
]
38+
analytics_publisher_identities = [
39+
"serviceAccount:${google_service_account.service_account.email}",
40+
]
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package apigee_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
7+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
8+
9+
"github.com/hashicorp/terraform-provider-google/google/acctest"
10+
"github.com/hashicorp/terraform-provider-google/google/envvar"
11+
)
12+
13+
func TestAccApigeeControlPlaneAccess_update(t *testing.T) {
14+
t.Parallel()
15+
16+
context := map[string]interface{}{
17+
"billing_account": envvar.GetTestBillingAccountFromEnv(t),
18+
"org_id": envvar.GetTestOrgFromEnv(t),
19+
"random_suffix": acctest.RandString(t, 10),
20+
}
21+
22+
acctest.VcrTest(t, resource.TestCase{
23+
PreCheck: func() { acctest.AccTestPreCheck(t) },
24+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
25+
Steps: []resource.TestStep{
26+
{
27+
Config: testAccApigeeControlPlaneAccess_full(context),
28+
},
29+
{
30+
ResourceName: "google_apigee_control_plane_access.apigee_control_plane_access",
31+
ImportState: true,
32+
ImportStateVerify: true,
33+
ImportStateVerifyIgnore: []string{"name"},
34+
},
35+
{
36+
Config: testAccApigeeControlPlaneAccess_update(context),
37+
ConfigPlanChecks: resource.ConfigPlanChecks{
38+
PreApply: []plancheck.PlanCheck{
39+
plancheck.ExpectResourceAction("google_apigee_control_plane_access.apigee_control_plane_access", plancheck.ResourceActionUpdate),
40+
},
41+
},
42+
},
43+
{
44+
ResourceName: "google_apigee_control_plane_access.apigee_control_plane_access",
45+
ImportState: true,
46+
ImportStateVerify: true,
47+
ImportStateVerifyIgnore: []string{"name"},
48+
},
49+
},
50+
})
51+
}
52+
53+
func testAccApigeeControlPlaneAccess_full(context map[string]interface{}) string {
54+
return acctest.Nprintf(`
55+
resource "google_project" "project" {
56+
project_id = "tf-test-my-project%{random_suffix}"
57+
name = "tf-test-my-project%{random_suffix}"
58+
org_id = "%{org_id}"
59+
billing_account = "%{billing_account}"
60+
deletion_policy = "DELETE"
61+
}
62+
63+
resource "google_project_service" "apigee" {
64+
project = google_project.project.project_id
65+
service = "apigee.googleapis.com"
66+
}
67+
68+
resource "google_apigee_organization" "apigee_org" {
69+
analytics_region = "us-central1"
70+
project_id = google_project.project.project_id
71+
72+
runtime_type = "HYBRID"
73+
depends_on = [google_project_service.apigee]
74+
}
75+
76+
resource "google_service_account" "service_account" {
77+
account_id = "sa-%{random_suffix}"
78+
display_name = "Service Account"
79+
}
80+
81+
resource "google_apigee_control_plane_access" "apigee_control_plane_access" {
82+
name = google_apigee_organization.apigee_org.name
83+
synchronizer_identities = [
84+
"serviceAccount:${google_service_account.service_account.email}",
85+
]
86+
analytics_publisher_identities = [
87+
"serviceAccount:${google_service_account.service_account.email}",
88+
]
89+
}
90+
`, context)
91+
}
92+
93+
func testAccApigeeControlPlaneAccess_update(context map[string]interface{}) string {
94+
return acctest.Nprintf(`
95+
resource "google_project" "project" {
96+
project_id = "tf-test-my-project%{random_suffix}"
97+
name = "tf-test-my-project%{random_suffix}"
98+
org_id = "%{org_id}"
99+
billing_account = "%{billing_account}"
100+
deletion_policy = "DELETE"
101+
}
102+
103+
resource "google_project_service" "apigee" {
104+
project = google_project.project.project_id
105+
service = "apigee.googleapis.com"
106+
}
107+
108+
resource "google_apigee_organization" "apigee_org" {
109+
analytics_region = "us-central1"
110+
project_id = google_project.project.project_id
111+
112+
runtime_type = "HYBRID"
113+
depends_on = [google_project_service.apigee]
114+
}
115+
116+
resource "google_apigee_control_plane_access" "apigee_control_plane_access" {
117+
name = google_apigee_organization.apigee_org.name
118+
synchronizer_identities = []
119+
analytics_publisher_identities = []
120+
}
121+
`, context)
122+
}

0 commit comments

Comments
 (0)