1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package allowlist
16
17 import (
18 "fmt"
19 "strings"
20
21 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/core/v1alpha1"
22 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
23 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/text"
24 )
25
26 var (
27
28
29
30
31 alphaAllowlist = []string{
32 "access_context_manager/google_access_context_manager_access_level_condition",
33 "access_context_manager/google_access_context_manager_gcp_user_access_binding",
34 "access_context_manager/google_access_context_manager_service_perimeter_resource",
35 "alloydb/google_alloydb_backup",
36 "alloydb/google_alloydb_cluster",
37 "alloydb/google_alloydb_instance",
38 "api_gateway/google_api_gateway_api",
39 "api_gateway/google_api_gateway_api_config",
40 "api_gateway/google_api_gateway_gateway",
41 "apigee/google_apigee_addons_config",
42 "apigee/google_apigee_endpoint_attachment",
43 "apigee/google_apigee_envgroup",
44 "apigee/google_apigee_envgroup_attachment",
45 "apigee/google_apigee_instance",
46 "apigee/google_apigee_instance_attachment",
47 "apigee/google_apigee_nat_address",
48 "apigee/google_apigee_sync_authorization",
49 "app_engine/google_app_engine_domain_mapping",
50 "app_engine/google_app_engine_firewall_rule",
51 "app_engine/google_app_engine_flexible_app_version",
52 "app_engine/google_app_engine_service_split_traffic",
53 "app_engine/google_app_engine_standard_app_version",
54 "beyondcorp/google_beyondcorp_app_connection",
55 "beyondcorp/google_beyondcorp_app_connector",
56 "beyondcorp/google_beyondcorp_app_gateway",
57 "bigquery/google_bigquery_dataset_access",
58 "bigquery_analytics_hub/google_bigquery_analytics_hub_data_exchange",
59 "bigquery_analytics_hub/google_bigquery_analytics_hub_listing",
60 "bigquery_connection/google_bigquery_connection",
61 "bigquery_datapolicy/google_bigquery_datapolicy_data_policy",
62 "bigquery_data_transfer/google_bigquery_data_transfer_config",
63 "bigquery_reservation/google_bigquery_reservation",
64 "certificate_manager/google_certificate_manager_certificate",
65 "certificate_manager/google_certificate_manager_certificate_map",
66 "certificate_manager/google_certificate_manager_certificate_map_entry",
67 "certificate_manager/google_certificate_manager_dns_authorization",
68 "cloud_asset/google_cloud_asset_folder_feed",
69 "cloud_asset/google_cloud_asset_organization_feed",
70 "cloud_asset/google_cloud_asset_project_feed",
71 "cloudfunctions2/google_cloudfunctions2_function",
72 "cloud_ids/google_cloud_ids_endpoint",
73 "cloudiot/google_cloudiot_device",
74 "cloud_tasks/google_cloud_tasks_queue",
75 "compute/google_compute_autoscaler",
76 "compute/google_compute_backend_bucket_signed_url_key",
77 "compute/google_compute_backend_service_signed_url_key",
78 "compute/google_compute_disk_resource_policy_attachment",
79 "compute/google_compute_global_network_endpoint",
80 "compute/google_compute_global_network_endpoint_group",
81 "compute/google_compute_instance_group_named_port",
82 "compute/google_compute_machine_image",
83 "compute/google_compute_managed_ssl_certificate",
84 "compute/google_compute_network_endpoint",
85 "compute/google_compute_network_peering_routes_config",
86 "compute/google_compute_organization_security_policy",
87 "compute/google_compute_organization_security_policy_association",
88 "compute/google_compute_organization_security_policy_rule",
89 "compute/google_compute_per_instance_config",
90 "compute/google_compute_region_autoscaler",
91 "compute/google_compute_region_disk_resource_policy_attachment",
92 "compute/google_compute_region_per_instance_config",
93 "container_analysis/google_container_analysis_occurrence",
94 "data_catalog/google_data_catalog_entry",
95 "data_catalog/google_data_catalog_entry_group",
96 "data_catalog/google_data_catalog_tag",
97 "data_catalog/google_data_catalog_tag_template",
98 "dataform/google_dataform_repository",
99 "datastore/google_datastore_index",
100 "datastream/google_datastream_connection_profile",
101 "datastream/google_datastream_private_connection",
102 "datastream/google_datastream_stream",
103 "deployment_manager/google_deployment_manager_deployment",
104 "dialogflow/google_dialogflow_agent",
105 "dialogflow/google_dialogflow_entity_type",
106 "dialogflow/google_dialogflow_fulfillment",
107 "dialogflow/google_dialogflow_intent",
108 "dialogflow_cx/google_dialogflow_cx_agent",
109 "dialogflow_cx/google_dialogflow_cx_entity_type",
110 "dialogflow_cx/google_dialogflow_cx_flow",
111 "dialogflow_cx/google_dialogflow_cx_intent",
112 "dialogflow_cx/google_dialogflow_cx_page",
113 "dialogflow_cx/google_dialogflow_cx_webhook",
114 "dns/google_dns_response_policy",
115 "dns/google_dns_response_policy_rule",
116 "document_ai/google_document_ai_processor",
117 "document_ai/google_document_ai_processor_default_version",
118 "essential_contacts/google_essential_contacts_contact",
119 "filestore/google_filestore_snapshot",
120 "firebase/google_firebase_android_app",
121 "firebase/google_firebase_project",
122 "firebase/google_firebase_web_app",
123 "firebase_database/google_firebase_database_instance",
124 "firebase_hosting/google_firebase_hosting_channel",
125 "firebase_hosting/google_firebase_hosting_site",
126 "firebase_storage/google_firebase_storage_bucket",
127 "gke_backup/google_gke_backup_backup_plan",
128 "healthcare/google_healthcare_consent_store",
129 "healthcare/google_healthcare_dataset",
130 "healthcare/google_healthcare_dicom_store",
131 "healthcare/google_healthcare_fhir_store",
132 "healthcare/google_healthcare_hl7_v2_store",
133 "identity_platform/google_identity_platform_default_supported_idp_config",
134 "identity_platform/google_identity_platform_inbound_saml_config",
135 "identity_platform/google_identity_platform_project_default_config",
136 "identity_platform/google_identity_platform_tenant_default_supported_idp_config",
137 "identity_platform/google_identity_platform_tenant_inbound_saml_config",
138 "kms/google_kms_crypto_key_version",
139 "kms/google_kms_key_ring_import_job",
140 "kms/google_kms_secret_ciphertext",
141 "ml_engine/google_ml_engine_model",
142 "network_management/google_network_management_connectivity_test",
143 "network_services/google_network_services_edge_cache_keyset",
144 "network_services/google_network_services_edge_cache_origin",
145 "network_services/google_network_services_edge_cache_service",
146 "notebooks/google_notebooks_environment",
147 "org_policy/google_org_policy_custom_constraint",
148 "os_config/google_os_config_patch_deployment",
149 "os_login/google_os_login_ssh_public_key",
150 "pubsub_lite/google_pubsub_lite_subscription",
151 "pubsub_lite/google_pubsub_lite_topic",
152 "security_center/google_scc_notification_config",
153 "security_center/google_scc_source",
154 "service_usage/google_service_usage_consumer_quota_override",
155 "storage/google_storage_hmac_key",
156 "storage_transfer/google_storage_transfer_agent_pool",
157 "tpu/google_tpu_node",
158 "vertex_ai/google_vertex_ai_dataset",
159 "vertex_ai/google_vertex_ai_endpoint",
160 "vertex_ai/google_vertex_ai_featurestore",
161 "vertex_ai/google_vertex_ai_featurestore_entitytype",
162 "vertex_ai/google_vertex_ai_featurestore_entitytype_feature",
163 "vertex_ai/google_vertex_ai_index",
164 "vertex_ai/google_vertex_ai_metadata_store",
165 "vertex_ai/google_vertex_ai_tensorboard",
166 "workflows/google_workflows_workflow",
167 "workstations/google_workstations_workstation_cluster",
168 }
169
170
171
172
173 betaAllowlist = []string{
174 "bigquery/google_bigquery_routine",
175 "data_catalog/google_data_catalog_policy_tag",
176 "data_catalog/google_data_catalog_taxonomy",
177 "tags/google_tags_tag_binding",
178 "tags/google_tags_tag_key",
179 "tags/google_tags_tag_value",
180 }
181 )
182
183 type AutoGenType struct {
184 ServiceNameInLC string
185 KRMKindName string
186 TFTypeName string
187 Version string
188 }
189
190 func (a *AutoGenType) loadKRMKindFromSM(smAndRCMap map[string]map[string]string) error {
191 service := a.ServiceNameInLC
192 tfType := a.TFTypeName
193 rcMap, ok := smAndRCMap[a.ServiceNameInLC]
194 if !ok {
195 return fmt.Errorf("can't find allowlisted service %v "+
196 "in generated service mappings", service)
197 }
198 krmKind, ok := rcMap[tfType]
199 if !ok {
200 return fmt.Errorf("can't find allowlisted type %v "+
201 "under service %v in auto-generated service mappings",
202 tfType, service)
203 }
204 a.KRMKindName = krmKind
205 return nil
206 }
207
208 func newAutoGenType(autoGenTypeInString string, version string) (*AutoGenType, error) {
209 parts := strings.Split(autoGenTypeInString, "/")
210 if len(parts) != 2 {
211 return nil, fmt.Errorf("type for resource auto-generation should be"+
212 " in the format '[terraform_product_name]/[terraform_type_name]', split by one '/',"+
213 " but the provided type is %q", autoGenTypeInString)
214 }
215
216 if !text.IsSnakeCase(parts[0]) && !text.IsSnakeCase(parts[1]) {
217 return nil, fmt.Errorf("type for resource auto-generation should be"+
218 " in the format '[terraform_product_name]/[terraform_type_name]', both terraform_product_name"+
219 " and terraform_type_name should be in snake case, but the provided"+
220 " type is %q", autoGenTypeInString)
221 }
222
223 return &AutoGenType{
224 ServiceNameInLC: strings.Replace(parts[0], "_", "", -1),
225 TFTypeName: parts[1],
226 Version: version,
227 }, nil
228 }
229
230 type AutoGenAllowlist struct {
231 ServiceAndTFTypes map[string]map[string]*AutoGenType
232 ServiceAndKRMKinds map[string]map[string]*AutoGenType
233 KRMKinds map[string]*AutoGenType
234 }
235
236 func (l *AutoGenAllowlist) HasService(serviceNameInLC string) bool {
237 _, ok := l.ServiceAndTFTypes[serviceNameInLC]
238 return ok
239 }
240
241 func (l *AutoGenAllowlist) GetTFTypeInService(serviceNameInLC, tfType string) (*AutoGenType, bool) {
242 resourceMap, ok := l.ServiceAndTFTypes[serviceNameInLC]
243 if !ok {
244 return nil, false
245 }
246 autoGenType, ok := resourceMap[tfType]
247 return autoGenType, ok
248 }
249
250 func (l *AutoGenAllowlist) GetKRMKind(krmKind string) (*AutoGenType, bool) {
251 autoGenType, ok := l.KRMKinds[krmKind]
252 return autoGenType, ok
253 }
254
255 func (l *AutoGenAllowlist) HasKRMKindInService(serviceNameInLC, krmKind string) bool {
256 resourceMap, ok := l.ServiceAndKRMKinds[serviceNameInLC]
257 if !ok {
258 return false
259 }
260 _, ok = resourceMap[krmKind]
261 return ok
262 }
263
264 func (l *AutoGenAllowlist) addAutoGenType(autoGenType *AutoGenType) error {
265 _, ok := l.ServiceAndTFTypes[autoGenType.ServiceNameInLC]
266 if !ok {
267 l.ServiceAndTFTypes[autoGenType.ServiceNameInLC] = make(map[string]*AutoGenType)
268 l.ServiceAndKRMKinds[autoGenType.ServiceNameInLC] = make(map[string]*AutoGenType)
269 }
270 TFTypeMap, _ := l.ServiceAndTFTypes[autoGenType.ServiceNameInLC]
271 KRMKindMap, _ := l.ServiceAndKRMKinds[autoGenType.ServiceNameInLC]
272 _, ok = TFTypeMap[autoGenType.TFTypeName]
273 if ok {
274 return fmt.Errorf("TF type %v has already been allowlisted under "+
275 "service %v", autoGenType.TFTypeName, autoGenType.ServiceNameInLC)
276 }
277
278 TFTypeMap[autoGenType.TFTypeName] = autoGenType
279 KRMKindMap[autoGenType.KRMKindName] = autoGenType
280 l.KRMKinds[autoGenType.KRMKindName] = autoGenType
281 return nil
282 }
283
284 func NewAutoGenAllowlist() *AutoGenAllowlist {
285 return &AutoGenAllowlist{
286 ServiceAndTFTypes: make(map[string]map[string]*AutoGenType),
287 ServiceAndKRMKinds: make(map[string]map[string]*AutoGenType),
288 KRMKinds: make(map[string]*AutoGenType),
289 }
290 }
291
292 func LoadAutoGenAllowList(generatedSMMap map[string]v1alpha1.ServiceMapping) (*AutoGenAllowlist, error) {
293 smAndRCMap := getGeneratedSMAndRCMap(generatedSMMap)
294 autoGenAllowlist := NewAutoGenAllowlist()
295 for _, typeInString := range alphaAllowlist {
296 autoGenType, err := newAutoGenType(typeInString, k8s.KCCAPIVersionV1Alpha1)
297 if err != nil {
298 return nil, fmt.Errorf("error converting allowlisted type %v from string to AutoGenType: %w", typeInString, err)
299 }
300 if err := autoGenType.loadKRMKindFromSM(smAndRCMap); err != nil {
301 return nil, fmt.Errorf("error loading KRMKind for allowlisted type %v: %w", typeInString, err)
302 }
303 if err := autoGenAllowlist.addAutoGenType(autoGenType); err != nil {
304 return nil, fmt.Errorf("error adding AutoGenType for %v into the AutoGenAllowlist: %w", typeInString, err)
305 }
306 }
307 for _, typeInString := range betaAllowlist {
308 autoGenType, err := newAutoGenType(typeInString, k8s.KCCAPIVersion)
309 if err != nil {
310 return nil, fmt.Errorf("error converting allowlisted type %v from string to AutoGenType: %w", typeInString, err)
311 }
312 if err := autoGenType.loadKRMKindFromSM(smAndRCMap); err != nil {
313 return nil, fmt.Errorf("error loading KRMKind for allowlisted type %v: %w", typeInString, err)
314 }
315 if err := autoGenAllowlist.addAutoGenType(autoGenType); err != nil {
316 return nil, fmt.Errorf("error adding AutoGenType for %v into the AutoGenAllowlist: %w", typeInString, err)
317 }
318 }
319 return autoGenAllowlist, nil
320 }
321
322 func getGeneratedSMAndRCMap(generatedSMMap map[string]v1alpha1.ServiceMapping) map[string]map[string]string {
323 smAndRCMap := make(map[string]map[string]string)
324 for smName, sm := range generatedSMMap {
325 service := strings.TrimSuffix(smName, ".cnrm.cloud.google.com")
326 generatedRCMap := make(map[string]string)
327 for _, rc := range sm.Spec.Resources {
328 generatedRCMap[rc.Name] = rc.Kind
329 }
330 smAndRCMap[service] = generatedRCMap
331 }
332 return smAndRCMap
333 }
334
View as plain text