diff --git a/pkg/tfimportprovider/cloudFoundryDomainImportProvider.go b/pkg/tfimportprovider/cloudFoundryDomainImportProvider.go index 3558e99..7133a18 100644 --- a/pkg/tfimportprovider/cloudFoundryDomainImportProvider.go +++ b/pkg/tfimportprovider/cloudFoundryDomainImportProvider.go @@ -50,7 +50,7 @@ func createDomainImportBlock(data map[string]interface{}, orgId string, filterVa } missingSpace, subset := isSubset(cfAllDomains, filterValues) if !subset { - return "", 0, fmt.Errorf("cloud foudndry domain %s not found in the organization with ID %s. Please adjust it in the provided file", missingSpace, orgId) + return "", 0, fmt.Errorf("cloud foundry domain %s not found in the organization with ID %s. Please adjust it in the provided file", missingSpace, orgId) } } else { for x, value := range domains { diff --git a/pkg/tfimportprovider/cloudFoundryRouteImportProvider.go b/pkg/tfimportprovider/cloudFoundryRouteImportProvider.go index a95f2de..0ded424 100644 --- a/pkg/tfimportprovider/cloudFoundryRouteImportProvider.go +++ b/pkg/tfimportprovider/cloudFoundryRouteImportProvider.go @@ -50,7 +50,7 @@ func createRouteImportBlock(data map[string]interface{}, orgId string, filterVal } missingRoute, subset := isSubset(cfAllRoutes, filterValues) if !subset { - return "", 0, fmt.Errorf("cloud foudndry route %s not found in the organization with ID %s. Please adjust it in the provided file", missingRoute, orgId) + return "", 0, fmt.Errorf("cloud foundry route %s not found in the organization with ID %s. Please adjust it in the provided file", missingRoute, orgId) } } else { for x, value := range routes { diff --git a/pkg/tfimportprovider/cloudFoundrySpaceQuotaImportProvider.go b/pkg/tfimportprovider/cloudFoundrySpaceQuotaImportProvider.go new file mode 100644 index 0000000..e04d680 --- /dev/null +++ b/pkg/tfimportprovider/cloudFoundrySpaceQuotaImportProvider.go @@ -0,0 +1,79 @@ +package tfimportprovider + +import ( + "fmt" + "log" + "slices" + "strings" + + tfutils "github.com/SAP/terraform-exporter-btp/pkg/tfutils" +) + +type cloudfoundrySpaceQuotaImportProvider struct { + TfImportProvider +} + +func newcloudfoundrySpaceQuotaImportProvider() ITfImportProvider { + return &cloudfoundrySpaceQuotaImportProvider{ + TfImportProvider: TfImportProvider{ + resourceType: tfutils.CfSpaceQuotaType, + }, + } +} + +func (tf *cloudfoundrySpaceQuotaImportProvider) GetImportBlock(data map[string]interface{}, levelId string, filterValues []string) (string, int, error) { + count := 0 + orgId := levelId + + resourceDoc, err := tfutils.GetDocByResourceName(tfutils.ResourcesKind, tfutils.CfSpaceQuotaType, tfutils.OrganizationLevel) + if err != nil { + fmt.Print("\r\n") + log.Fatalf("read doc failed!") + return "", count, err + } + + importBlock, count, err := createSpaceQuotaImportBlock(data, orgId, filterValues, resourceDoc) + if err != nil { + return "", count, err + } + + return importBlock, count, nil +} + +func createSpaceQuotaImportBlock(data map[string]interface{}, orgId string, filterValues []string, resourceDoc tfutils.EntityDocs) (importBlock string, count int, err error) { + count = 0 + quotas := data["space_quotas"].([]interface{}) + + if len(filterValues) != 0 { + var cfAllSpaceQuotas []string + + for x, value := range quotas { + quota := value.(map[string]interface{}) + cfAllSpaceQuotas = append(cfAllSpaceQuotas, fmt.Sprintf("%v", quota["name"])) + if slices.Contains(filterValues, fmt.Sprintf("%v", quota["name"])) { + importBlock += templateSpaceQuotaImport(x, quota, resourceDoc) + count++ + } + } + + missingQuota, subset := isSubset(cfAllSpaceQuotas, filterValues) + + if !subset { + return "", 0, fmt.Errorf("cloud foundry space quota %s not found in the organization with ID %s. Please adjust it in the provided file", missingQuota, orgId) + } + } else { + for x, value := range quotas { + quota := value.(map[string]interface{}) + importBlock += templateSpaceQuotaImport(x, quota, resourceDoc) + count++ + } + } + + return importBlock, count, nil +} + +func templateSpaceQuotaImport(x int, quota map[string]interface{}, resourceDoc tfutils.EntityDocs) string { + template := strings.Replace(resourceDoc.Import, "", "space_quota_"+fmt.Sprintf("%v", x), -1) + template = strings.Replace(template, "", fmt.Sprintf("%v", quota["id"]), -1) + return template + "\n" +} diff --git a/pkg/tfimportprovider/cloudFoundrySpaceQuotaImportProvider_test.go b/pkg/tfimportprovider/cloudFoundrySpaceQuotaImportProvider_test.go new file mode 100644 index 0000000..1c8574c --- /dev/null +++ b/pkg/tfimportprovider/cloudFoundrySpaceQuotaImportProvider_test.go @@ -0,0 +1,72 @@ +package tfimportprovider + +import ( + "testing" + + tfutils "github.com/SAP/terraform-exporter-btp/pkg/tfutils" + "github.com/stretchr/testify/assert" +) + +func TestCreateSpaceQuotaImportBlock(t *testing.T) { + resourceDoc := tfutils.EntityDocs{ + Import: "import {\n\t\t\t\tto = cloudfoundry_space_quota.\n\t\t\t\tid = \"\"\"\n\t\t\t }\n", + } + + jsonString := "{\"name\": null,\"org\":\"12345\",\"space_quotas\": [{\"allow_paid_service_plans\": false,\"created_at\":\"2024-12-03T07:03:20Z\",\"id\":\"12345678\",\"instance_memory\": 15000,\"name\":\"test-quota1\",\"org\":\"12345\",\"spaces\": null,\"total_app_instances\": 10,\"total_app_log_rate_limit\": null,\"total_app_tasks\": null,\"total_memory\": 2048,\"total_route_ports\": null,\"total_routes\": 10,\"total_service_keys\": null,\"total_services\": 100,\"updated_at\":\"2024-12-03T07:03:20Z\"}]}" + dataSpaceQuotaConfig, _ := GetDataFromJsonString(jsonString) + + jsonStringMultipleSpacesQuotas := "{\"name\": null,\"org\":\"12345\",\"space_quotas\": [{\"allow_paid_service_plans\": false,\"created_at\":\"2024-12-03T07:03:20Z\",\"id\":\"12345678\",\"instance_memory\": 15000,\"name\":\"test-quota1\",\"org\":\"12345\",\"spaces\": null,\"total_app_instances\": 10,\"total_app_log_rate_limit\": null,\"total_app_tasks\": null,\"total_memory\": 2048,\"total_route_ports\": null,\"total_routes\": 10,\"total_service_keys\": null,\"total_services\": 100,\"updated_at\":\"2024-12-03T07:03:20Z\"}, {\"allow_paid_service_plans\": false,\"created_at\":\"2024-12-03T07:03:20Z\",\"id\":\"23456789\",\"instance_memory\": 15000,\"name\":\"test-quota2\",\"org\":\"12345\",\"spaces\": null,\"total_app_instances\": 10,\"total_app_log_rate_limit\": null,\"total_app_tasks\": null,\"total_memory\": 2048,\"total_route_ports\": null,\"total_routes\": 10,\"total_service_keys\": null,\"total_services\": 100,\"updated_at\":\"2024-12-03T07:03:20Z\"}]}" + dataMultipleSpacesQuotas, _ := GetDataFromJsonString(jsonStringMultipleSpacesQuotas) + + tests := []struct { + name string + data map[string]interface{} + orgId string + filterValues []string + expectedBlock string + expectedCount int + expectError bool + }{ + + { + name: "Valid data without filter", + data: dataSpaceQuotaConfig, + orgId: "12345", + filterValues: []string{}, + expectedBlock: "import {\n\t\t\t\tto = cloudfoundry_space_quota.space_quota_0\n\t\t\t\tid = \"12345678\"\"\n\t\t\t }\n\n", + expectedCount: 1, + expectError: false, + }, + { + name: "Valid data with matching filter", + data: dataMultipleSpacesQuotas, + orgId: "12345", + filterValues: []string{"test-quota2"}, + expectedBlock: "import {\n\t\t\t\tto = cloudfoundry_space_quota.space_quota_1\n\t\t\t\tid = \"23456789\"\"\n\t\t\t }\n\n", + expectedCount: 1, + expectError: false, + }, + { + name: "Invalid filter value", + data: dataSpaceQuotaConfig, + orgId: "12345", + filterValues: []string{"wrong-space-quota-name"}, + expectedBlock: "", + expectedCount: 0, + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + importBlock, count, err := createSpaceQuotaImportBlock(tt.data, tt.orgId, tt.filterValues, resourceDoc) + if tt.expectError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedBlock, importBlock) + assert.Equal(t, tt.expectedCount, count) + } + }) + } +} diff --git a/pkg/tfimportprovider/cloudfoundrySpaceImportProvider.go b/pkg/tfimportprovider/cloudfoundrySpaceImportProvider.go index 30f031e..fb89c59 100644 --- a/pkg/tfimportprovider/cloudfoundrySpaceImportProvider.go +++ b/pkg/tfimportprovider/cloudfoundrySpaceImportProvider.go @@ -59,7 +59,7 @@ func createSpaceImportBlock(data map[string]interface{}, orgId string, filterVal missingSpace, subset := isSubset(cfAllSpaces, filterValues) if !subset { - return "", 0, fmt.Errorf("cloud foudndry space %s not found in the organization with ID %s. Please adjust it in the provided file", missingSpace, orgId) + return "", 0, fmt.Errorf("cloud foundry space %s not found in the organization with ID %s. Please adjust it in the provided file", missingSpace, orgId) } } else { for x, value := range spaces { diff --git a/pkg/tfimportprovider/cloudfoundryUserImportProvider.go b/pkg/tfimportprovider/cloudfoundryUserImportProvider.go index 954e8a7..5d16f01 100644 --- a/pkg/tfimportprovider/cloudfoundryUserImportProvider.go +++ b/pkg/tfimportprovider/cloudfoundryUserImportProvider.go @@ -59,7 +59,7 @@ func createUserImportBlock(data map[string]interface{}, orgId string, filterValu missingSpace, subset := isSubset(cfAllUsers, filterValues) if !subset { - return "", 0, fmt.Errorf("cloud foudndry user %s not found in the organization with ID %s. Please adjust it in the provided file", missingSpace, orgId) + return "", 0, fmt.Errorf("cloud foundry user %s not found in the organization with ID %s. Please adjust it in the provided file", missingSpace, orgId) } } else { for x, value := range users { diff --git a/pkg/tfimportprovider/tfImportProviderFactory.go b/pkg/tfimportprovider/tfImportProviderFactory.go index b1d2a23..8482866 100644 --- a/pkg/tfimportprovider/tfImportProviderFactory.go +++ b/pkg/tfimportprovider/tfImportProviderFactory.go @@ -39,6 +39,8 @@ func GetImportBlockProvider(cmdResourceName string, level string) (ITfImportProv return newCloudfoundryDomainImportProvider(), nil case tfutils.CmdCfRouteParameter: return newCloudfoundryRouteImportProvider(), nil + case tfutils.CmdCfSpaceQuotaParameter: + return newcloudfoundrySpaceQuotaImportProvider(), nil default: return nil, fmt.Errorf("unsupported resource provided") } diff --git a/pkg/tfutils/tfConfig.go b/pkg/tfutils/tfConfig.go index d1620d0..a4ff3ca 100644 --- a/pkg/tfutils/tfConfig.go +++ b/pkg/tfutils/tfConfig.go @@ -42,6 +42,7 @@ var AllowedResourcesOrganization = []string{ CmdCfUserParameter, CmdCfDomainParamater, CmdCfRouteParameter, + CmdCfSpaceQuotaParameter, } func GenerateConfig(resourceFileName string, configFolder string, isMainCmd bool, resourceNameLong string) error { diff --git a/pkg/tfutils/tfImport.go b/pkg/tfutils/tfImport.go index 62bdd18..cc2f63c 100644 --- a/pkg/tfutils/tfImport.go +++ b/pkg/tfutils/tfImport.go @@ -43,6 +43,7 @@ const ( CmdCfUserParameter string = "users" CmdCfDomainParamater string = "domains" CmdCfRouteParameter string = "routes" + CmdCfSpaceQuotaParameter string = "space-quotas" ) const ( @@ -66,10 +67,11 @@ const ( ) const ( - CfSpaceType string = "cloudfoundry_space" - CfUserType string = "cloudfoundry_user" - CfDomainType string = "cloudfoundry_domain" - CfRouteType string = "cloudfoundry_route" + CfSpaceType string = "cloudfoundry_space" + CfUserType string = "cloudfoundry_user" + CfDomainType string = "cloudfoundry_domain" + CfRouteType string = "cloudfoundry_route" + CfSpaceQuotaType string = "cloudfoundry_space_quota" ) const DirectoryFeatureDefault string = "DEFAULT" @@ -187,6 +189,8 @@ func TranslateResourceParamToTechnicalName(resource string, level string) string return CfDomainType case CmdCfRouteParameter: return CfRouteType + case CmdCfSpaceQuotaParameter: + return CfSpaceQuotaType } return "" } @@ -379,6 +383,8 @@ func transformDataToStringArray(btpResource string, data map[string]interface{}) transformDataToStringArrayGeneric(data, &stringArr, "domains", "name") case CfRouteType: transformDataToStringArrayGeneric(data, &stringArr, "routes", "url") + case CfSpaceQuotaType: + transformDataToStringArrayGeneric(data, &stringArr, "space_quotas", "name") } return stringArr }