From 70e027bd22cb1b4423b97d5bde10dde4916f1964 Mon Sep 17 00:00:00 2001 From: Christian Lechner <22294087+lechnerc77@users.noreply.github.com.> Date: Fri, 13 Sep 2024 15:55:52 +0200 Subject: [PATCH 1/2] refactor: import via files --- cmd/export.go | 11 - cmd/exportAll.go | 10 +- cmd/exportEnvironmentInstances.go | 2 +- cmd/exportEnvironmentInstancesHelper.go | 44 +- cmd/exportEnvironmentInstancesHelper_test.go | 2 +- cmd/exportFromFileHelper.go | 381 +----------------- cmd/exportSubaccount.go | 2 +- cmd/exportSubaccountEntitlements.go | 2 +- cmd/exportSubaccountEntitlementsHelper.go | 42 +- ...exportSubaccountEntitlementsHelper_test.go | 2 +- cmd/exportSubaccountHelper.go | 13 +- cmd/exportSubaccountHelper_test.go | 2 +- cmd/exportSubaccountSubscriptions.go | 2 +- cmd/exportSubaccountSubscriptionsHelper.go | 47 ++- ...xportSubaccountSubscriptionsHelper_Test.go | 2 +- cmd/exportTrustConfigurations.go | 2 +- cmd/exportTrustConfigurationsHelper.go | 41 +- cmd/exportTrustConfigurationsHelper_test.go | 2 +- tfutils/docs.go | 34 +- tfutils/docs_test.go | 4 +- 20 files changed, 179 insertions(+), 468 deletions(-) diff --git a/cmd/export.go b/cmd/export.go index 8253671..f8112a0 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -20,20 +20,9 @@ The resources.tf file can be renamed by using the flag --resourceFileName. The command will fail if a resource file already exists`, Run: func(cmd *cobra.Command, args []string) { fmt.Printf("Invalid command\n\nUse 'btptfexporter export --help' for syntax instructions.\n\nERROR") - //fmt.Println("please provide the resource to be imported with this commnad. Supported resources are subaccount, entilements, environment-instances, subscriptions, trust-configurations") }, } func init() { rootCmd.AddCommand(exportCmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // exportCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // exportCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } diff --git a/cmd/exportAll.go b/cmd/exportAll.go index 016d7ca..af28e88 100644 --- a/cmd/exportAll.go +++ b/cmd/exportAll.go @@ -21,23 +21,23 @@ btp_subaccount_trust_configurations `, setupConfigDir(configDir) execPreExportSteps("saconf") - exportSubaccount(subaccount, "saconf") + exportSubaccount(subaccount, "saconf", nil) execPostExportSteps("saconf", configDir, resourceFileName, "SUBACCOUNT") execPreExportSteps("saentitlementconf") - exportSubaccountEntitlements(subaccount, "saentitlementconf") + exportSubaccountEntitlements(subaccount, "saentitlementconf", nil) execPostExportSteps("saentitlementconf", configDir, resourceFileName, "SUBACCOUNT ENTITLEMENTS") execPreExportSteps("saenvinstanceconf") - exportEnvironmentInstances(subaccount, "saenvinstanceconf") + exportEnvironmentInstances(subaccount, "saenvinstanceconf", nil) execPostExportSteps("saenvinstanceconf", configDir, resourceFileName, "SUBACCOUNT ENVIRONMENT INSTANCES") execPreExportSteps("sasubscriptionconf") - exportSubaccountSubscriptions(subaccount, "sasubscriptionconf") + exportSubaccountSubscriptions(subaccount, "sasubscriptionconf", nil) execPostExportSteps("sasubscriptionconf", configDir, resourceFileName, "SUBACCOUNT SUBSCRIPTIONS") execPreExportSteps("satrustconf") - exportTrustConfigurations(subaccount, "satrustconf") + exportTrustConfigurations(subaccount, "satrustconf", nil) execPostExportSteps("satrustconf", configDir, resourceFileName, "SUBACCOUNT TRUST CONFIGURATIONS") finalizeTfConfig(configDir) diff --git a/cmd/exportEnvironmentInstances.go b/cmd/exportEnvironmentInstances.go index 0c2e742..f00a104 100644 --- a/cmd/exportEnvironmentInstances.go +++ b/cmd/exportEnvironmentInstances.go @@ -15,7 +15,7 @@ var exportEnvironmentInstancesCmd = &cobra.Command{ resourceFileName, _ := cmd.Flags().GetString("resourceFileName") configDir, _ := cmd.Flags().GetString("config-output-dir") setupConfigDir(configDir) - exportEnvironmentInstances(subaccount, configDir) + exportEnvironmentInstances(subaccount, configDir, nil) generateConfig(resourceFileName, configDir) }, } diff --git a/cmd/exportEnvironmentInstancesHelper.go b/cmd/exportEnvironmentInstancesHelper.go index c83a359..af91af0 100644 --- a/cmd/exportEnvironmentInstancesHelper.go +++ b/cmd/exportEnvironmentInstancesHelper.go @@ -7,10 +7,11 @@ import ( "log" "os" "path/filepath" + "slices" "strings" ) -func exportEnvironmentInstances(subaccountID string, configFolder string) { +func exportEnvironmentInstances(subaccountID string, configFolder string, filterValues []string) { dataBlock, err := readDataSource(subaccountID) if err != nil { @@ -44,7 +45,7 @@ func exportEnvironmentInstances(subaccountID string, configFolder string) { return } - importBlock, err := getImportBlock(data, subaccountID) + importBlock, err := getImportBlock(data, subaccountID, filterValues) if err != nil { log.Fatalf("error: %v", err) return @@ -81,7 +82,7 @@ func readDataSource(subaccountId string) (string, error) { } -func getImportBlock(data map[string]interface{}, subaccountId string) (string, error) { +func getImportBlock(data map[string]interface{}, subaccountId string, filterValues []string) (string, error) { choice := "btp_subaccount_environment_instance" resource_doc, err := tfutils.GetDocsForResource("SAP", "btp", "btp", "resources", choice, BtpProviderVersion, "github.com") if err != nil { @@ -92,13 +93,38 @@ func getImportBlock(data map[string]interface{}, subaccountId string) (string, e var importBlock string environmentInstances := data["values"].([]interface{}) - for _, value := range environmentInstances { - environmentInstance := value.(map[string]interface{}) - template := strings.Replace(resource_doc.Import, "", fmt.Sprintf("%v", environmentInstance["environment_type"]), -1) - template = strings.Replace(template, "", subaccountId, -1) - template = strings.Replace(template, "", fmt.Sprintf("%v", environmentInstance["id"]), -1) - importBlock += template + "\n" + if len(filterValues) != 0 { + var subaccountAllEnvInstances []string + + for _, value := range environmentInstances { + + environmentInstance := value.(map[string]interface{}) + subaccountAllEnvInstances = append(subaccountAllEnvInstances, fmt.Sprintf("%v", environmentInstance["environment_type"])) + if slices.Contains(filterValues, fmt.Sprintf("%v", environmentInstance["environment_type"])) { + importBlock += templateEnvironmentInstanceImport(environmentInstance, subaccountId, resource_doc) + } + } + + missingEnvInstance, subset := isSubset(subaccountAllEnvInstances, filterValues) + + if !subset { + return "", fmt.Errorf("environment instance %s not found in the subaccount. Please adjust it in the provided file", missingEnvInstance) + + } + } else { + + for _, value := range environmentInstances { + environmentInstance := value.(map[string]interface{}) + importBlock += templateEnvironmentInstanceImport(environmentInstance, subaccountId, resource_doc) + } } return importBlock, nil } + +func templateEnvironmentInstanceImport(environmentInstance map[string]interface{}, subaccountId string, resource_doc tfutils.EntityDocs) string { + template := strings.Replace(resource_doc.Import, "", fmt.Sprintf("%v", environmentInstance["environment_type"]), -1) + template = strings.Replace(template, "", subaccountId, -1) + template = strings.Replace(template, "", fmt.Sprintf("%v", environmentInstance["id"]), -1) + return template + "\n" +} diff --git a/cmd/exportEnvironmentInstancesHelper_test.go b/cmd/exportEnvironmentInstancesHelper_test.go index e38a56e..ad0144e 100644 --- a/cmd/exportEnvironmentInstancesHelper_test.go +++ b/cmd/exportEnvironmentInstancesHelper_test.go @@ -30,7 +30,7 @@ func TestGetImportBlock(t *testing.T) { t.Errorf("error in unmarshalling") } - importBlock, err := getImportBlock(data, "5163621f-6a1e-4fbf-af3a-0f530a0dc4d5") + importBlock, err := getImportBlock(data, "5163621f-6a1e-4fbf-af3a-0f530a0dc4d5", nil) if err != nil { t.Errorf("error creating importBlock") } diff --git a/cmd/exportFromFileHelper.go b/cmd/exportFromFileHelper.go index daae6c7..f7cedbf 100644 --- a/cmd/exportFromFileHelper.go +++ b/cmd/exportFromFileHelper.go @@ -1,15 +1,12 @@ package cmd import ( - "btptfexport/tfutils" "encoding/json" "fmt" "io" "log" "os" - "path/filepath" "slices" - "strings" ) type Resource struct { @@ -69,393 +66,23 @@ func exportFromFile(subaccount string, jsonfile string, resourceFile string, con } func generateConfigForResource(resource string, values []string, subaccount string, configDir string) { - //fmt.Println(resource) - //fmt.Println(values) if resource == "environment-instances" { - getEnvInstanceConfig(values, subaccount, configDir) + exportEnvironmentInstances(subaccount, configDir, values) } if resource == "subaccount" { exportSubaccount(subaccount, configDir, values) } if resource == "entitlements" { - getEntitlementConfig(values, subaccount, configDir) + exportEnvironmentInstances(subaccount, configDir, values) } if resource == "subscriptions" { - getSubscriptionConfig(values, subaccount, configDir) + exportSubaccountSubscriptions(subaccount, configDir, values) } if resource == "trust-configurations" { - getTrustConfig(values, subaccount, configDir) + exportTrustConfigurations(subaccount, configDir, values) } } -func getTrustConfig(values []string, subaccountID string, configDir string) { - dataBlock, err := readSubaccountTrustConfigurationsDataSource(subaccountID) - if err != nil { - fmt.Println("error getting data source:", err) - return - } - - dataBlockFile := filepath.Join(TmpFolder, "main.tf") - err = tfutils.CreateFileWithContent(dataBlockFile, dataBlock) - if err != nil { - log.Fatalf("create file %s failed!", dataBlockFile) - return - } - - jsonBytes, err := GetTfStateData(TmpFolder, SubaccountTrustConfigurationType) - if err != nil { - log.Fatalf("error json.Marshal: %s", err) - return - } - - jsonString := string(jsonBytes) - var data map[string]interface{} - err = json.Unmarshal([]byte(jsonString), &data) - if err != nil { - fmt.Println("error:", err) - return - } - importBlock, err := getImportBlock4(data, subaccountID, values) - if err != nil { - fmt.Println("error:", err) - os.Exit(0) - } - - currentDir, err := os.Getwd() - if err != nil { - fmt.Println("error getting current directory:", err) - return - } - - if len(importBlock) == 0 { - log.Println("No trust configuration found for the given subaccount") - return - } - - importFileName := "subaccount_trust_configurations_import.tf" - importFileName = filepath.Join(currentDir, configDir, importFileName) - - err = tfutils.CreateFileWithContent(importFileName, importBlock) - if err != nil { - log.Fatalf("create file %s failed!", dataBlockFile) - return - } - - log.Println("subaccount trust configuration has been exported. Please check " + configDir + " folder") -} - -func getImportBlock4(data map[string]interface{}, subaccountId string, values []string) (string, error) { - choice := "btp_subaccount_trust_configuration" - resource_doc, err := tfutils.GetDocsForResource("SAP", "btp", "btp", "resources", choice, BtpProviderVersion, "github.com") - if err != nil { - log.Fatalf("read doc failed!") - return "", err - } - - var importBlock string - var subaccountAllTrusts []string - trusts := data["values"].([]interface{}) - - for x, value := range trusts { - - trust := value.(map[string]interface{}) - subaccountAllTrusts = append(subaccountAllTrusts, fmt.Sprintf("%v", trust["origin"])) - if slices.Contains(values, fmt.Sprintf("%v", trust["origin"])) { - template := strings.Replace(resource_doc.Import, "", "trust"+fmt.Sprint(x), -1) - template = strings.Replace(template, "", subaccountId, -1) - template = strings.Replace(template, "", fmt.Sprintf("%v", trust["origin"]), -1) - importBlock += template + "\n" - } - } - - missingTrust, subset := isSubset(subaccountAllTrusts, values) - - if !subset { - return "", fmt.Errorf("trust configuration %s not found in the subaccount. Please adjust it in the provided file", missingTrust) - - } - - return importBlock, nil -} - -func getSubscriptionConfig(values []string, subaccountID string, configDir string) { - dataBlock, err := readSubaccountSubscriptionDataSource(subaccountID) - if err != nil { - fmt.Println("error getting data source:", err) - return - } - - dataBlockFile := filepath.Join(TmpFolder, "main.tf") - err = tfutils.CreateFileWithContent(dataBlockFile, dataBlock) - if err != nil { - log.Fatalf("create file %s failed!", dataBlockFile) - return - } - - jsonBytes, err := GetTfStateData(TmpFolder, SubaccountSubscriptionType) - if err != nil { - log.Fatalf("error json.Marshal: %s", err) - return - } - - jsonString := string(jsonBytes) - var data map[string]interface{} - err = json.Unmarshal([]byte(jsonString), &data) - if err != nil { - fmt.Println("error:", err) - return - } - importBlock, err := getImportBlock3(data, subaccountID, values) - if err != nil { - fmt.Println("error:", err) - os.Exit(0) - } - - currentDir, err := os.Getwd() - if err != nil { - fmt.Println("error getting current directory:", err) - return - } - - if len(importBlock) == 0 { - log.Println("No subscription found for the given subaccount") - return - } - - importFileName := "subaccount_subscriptions_import.tf" - importFileName = filepath.Join(currentDir, configDir, importFileName) - - err = tfutils.CreateFileWithContent(importFileName, importBlock) - if err != nil { - log.Fatalf("create file %s failed!", dataBlockFile) - return - } - - log.Println("subaccount subscriptions has been exported. Please check " + configDir + " folder") - -} - -func getImportBlock3(data map[string]interface{}, subaccountId string, values []string) (string, error) { - choice := "btp_subaccount_subscription" - resource_doc, err := tfutils.GetDocsForResource("SAP", "btp", "btp", "resources", choice, BtpProviderVersion, "github.com") - if err != nil { - log.Fatalf("read doc failed!") - return "", err - } - - var importBlock string - var subaccountAllSubscriptions []string - subscriptions := data["values"].([]interface{}) - - for _, value := range subscriptions { - subscription := value.(map[string]interface{}) - subaccountAllSubscriptions = append(subaccountAllSubscriptions, fmt.Sprintf("%v", subscription["app_name"])+"_"+fmt.Sprintf("%v", subscription["plan_name"])) - if slices.Contains(values, fmt.Sprintf("%v", subscription["app_name"])+"_"+fmt.Sprintf("%v", subscription["plan_name"])) { - template := strings.Replace(resource_doc.Import, "", strings.Replace(fmt.Sprintf("%v", subscription["app_name"]), "-", "_", -1), -1) - template = strings.Replace(template, "", subaccountId, -1) - template = strings.Replace(template, "", fmt.Sprintf("%v", subscription["app_name"]), -1) - template = strings.Replace(template, "", fmt.Sprintf("%v", subscription["plan_name"]), -1) - importBlock += template + "\n" - } - } - - missingSubscription, subset := isSubset(subaccountAllSubscriptions, values) - - if !subset { - return "", fmt.Errorf("subscription %s not found in the subaccount. Please adjust it in the provided file", missingSubscription) - - } - - return importBlock, nil -} - -func getEntitlementConfig(values []string, subaccountID string, configDir string) { - dataBlock, err := readSubaccountEntilementsDataSource(subaccountID) - if err != nil { - fmt.Println("error getting data source:", err) - return - } - - dataBlockFile := filepath.Join(TmpFolder, "main.tf") - err = tfutils.CreateFileWithContent(dataBlockFile, dataBlock) - if err != nil { - log.Fatalf("create file %s failed!", dataBlockFile) - return - } - - jsonBytes, err := GetTfStateData(TmpFolder, SubaccountEntitlementType) - if err != nil { - log.Fatalf("error json.Marshal: %s", err) - return - } - - jsonString := string(jsonBytes) - var data map[string]interface{} - err = json.Unmarshal([]byte(jsonString), &data) - if err != nil { - fmt.Println("error:", err) - return - } - importBlock, err := getImportBlock2(data, subaccountID, values) - if err != nil { - fmt.Println("error:", err) - os.Exit(0) - } - - if len(importBlock) == 0 { - log.Println("No Entitlement found for the given subaccount") - return - } - - currentDir, err := os.Getwd() - if err != nil { - fmt.Println("error getting current directory:", err) - return - } - - importFileName := "subaccount_entitlements_import.tf" - importFileName = filepath.Join(currentDir, configDir, importFileName) - - err = tfutils.CreateFileWithContent(importFileName, importBlock) - if err != nil { - log.Fatalf("create file %s failed!", dataBlockFile) - return - } - - log.Println("btp subaccount entitlements has been exported. Please check " + configDir + " folder") - -} - -func getImportBlock2(data map[string]interface{}, subaccountId string, values []string) (string, error) { - - choice := "btp_subaccount_entitlement" - resource_doc, err := tfutils.GetDocsForResource("SAP", "btp", "btp", "resources", choice, BtpProviderVersion, "github.com") - if err != nil { - log.Fatalf("read doc failed!") - return "", err - } - - var importBlock string - var subaccountAllEntitlements []string - for key, value := range data { - - subaccountAllEntitlements = append(subaccountAllEntitlements, strings.Replace(key, ":", "_", -1)) - if slices.Contains(values, strings.Replace(key, ":", "_", -1)) { - template := strings.Replace(resource_doc.Import, "", strings.Replace(key, ":", "_", -1), -1) - template = strings.Replace(template, "", subaccountId, -1) - if subMap, ok := value.(map[string]interface{}); ok { - for subKey, subValue := range subMap { - template = strings.Replace(template, "<"+subKey+">", fmt.Sprintf("%v", subValue), -1) - } - } - importBlock += template + "\n" - } - } - - missingEntitlement, subset := isSubset(subaccountAllEntitlements, values) - - if !subset { - return "", fmt.Errorf("entitlement %s not found in the subaccount. Please adjust it in the provided file", missingEntitlement) - - } - - return importBlock, nil - -} - -func getEnvInstanceConfig(values []string, subaccountID string, configDir string) { - - dataBlock, err := readDataSource(subaccountID) - if err != nil { - fmt.Println("error getting data source:", err) - return - } - - dataBlockFile := filepath.Join(TmpFolder, "main.tf") - err = tfutils.CreateFileWithContent(dataBlockFile, dataBlock) - if err != nil { - log.Fatalf("create file %s failed!", dataBlockFile) - return - } - - jsonBytes, err := GetTfStateData(TmpFolder, EnvironmentInstanceType) - if err != nil { - log.Fatalf("error json.Marshal: %s", err) - return - } - - jsonString := string(jsonBytes) - var data map[string]interface{} - err = json.Unmarshal([]byte(jsonString), &data) - if err != nil { - fmt.Println("error:", err) - return - } - - importBlock, err := getImportBlock1(data, subaccountID, values) - - if err != nil { - fmt.Println("error:", err) - os.Exit(0) - } - - if len(importBlock) == 0 { - log.Println("No environment instance found for the given subaccount") - return - } - - currentDir, err := os.Getwd() - if err != nil { - fmt.Println("error getting current directory:", err) - return - } - importFileName := "btp_environment_instances_import.tf" - importFileName = filepath.Join(currentDir, configDir, importFileName) - - err = tfutils.CreateFileWithContent(importFileName, importBlock) - if err != nil { - log.Fatalf("create file %s failed!", dataBlockFile) - return - } - - log.Println(" environment instances have been exported. Please check " + configDir + " folder") - -} - -func getImportBlock1(data map[string]interface{}, subaccountId string, values []string) (string, error) { - choice := "btp_subaccount_environment_instance" - resource_doc, err := tfutils.GetDocsForResource("SAP", "btp", "btp", "resources", choice, BtpProviderVersion, "github.com") - if err != nil { - log.Fatalf("read doc failed!") - return "", err - } - - var importBlock string - var subaccountAllEnvInstances []string - environmentInstances := data["values"].([]interface{}) - - for _, value := range environmentInstances { - - environmentInstance := value.(map[string]interface{}) - subaccountAllEnvInstances = append(subaccountAllEnvInstances, fmt.Sprintf("%v", environmentInstance["environment_type"])) - if slices.Contains(values, fmt.Sprintf("%v", environmentInstance["environment_type"])) { - template := strings.Replace(resource_doc.Import, "", fmt.Sprintf("%v", environmentInstance["environment_type"]), -1) - template = strings.Replace(template, "", subaccountId, -1) - template = strings.Replace(template, "", fmt.Sprintf("%v", environmentInstance["id"]), -1) - importBlock += template + "\n" - } - } - - missingEnvInstance, subset := isSubset(subaccountAllEnvInstances, values) - - if !subset { - return "", fmt.Errorf("environment instance %s not found in the subaccount. Please adjust it in the provided file", missingEnvInstance) - - } - - return importBlock, nil -} - func isSubset(superSet []string, subset []string) (string, bool) { for _, value := range subset { if !slices.Contains(superSet, value) { diff --git a/cmd/exportSubaccount.go b/cmd/exportSubaccount.go index d63df88..af4f30d 100644 --- a/cmd/exportSubaccount.go +++ b/cmd/exportSubaccount.go @@ -15,7 +15,7 @@ var subaccountCmd = &cobra.Command{ resourceFileName, _ := cmd.Flags().GetString("resourceFileName") configDir, _ := cmd.Flags().GetString("config-output-dir") setupConfigDir(configDir) - exportSubaccount(subaccount, configDir) + exportSubaccount(subaccount, configDir, nil) generateConfig(resourceFileName, configDir) }, } diff --git a/cmd/exportSubaccountEntitlements.go b/cmd/exportSubaccountEntitlements.go index 1b10db4..addd972 100644 --- a/cmd/exportSubaccountEntitlements.go +++ b/cmd/exportSubaccountEntitlements.go @@ -15,7 +15,7 @@ var exportSubaccountEntitlementsCmd = &cobra.Command{ resourceFileName, _ := cmd.Flags().GetString("resourceFileName") configDir, _ := cmd.Flags().GetString("config-output-dir") setupConfigDir(configDir) - exportSubaccountEntitlements(subaccount, configDir) + exportSubaccountEntitlements(subaccount, configDir, nil) generateConfig(resourceFileName, configDir) }, } diff --git a/cmd/exportSubaccountEntitlementsHelper.go b/cmd/exportSubaccountEntitlementsHelper.go index dae3f38..b0f915a 100644 --- a/cmd/exportSubaccountEntitlementsHelper.go +++ b/cmd/exportSubaccountEntitlementsHelper.go @@ -7,10 +7,11 @@ import ( "log" "os" "path/filepath" + "slices" "strings" ) -func exportSubaccountEntitlements(subaccountID string, configDir string) { +func exportSubaccountEntitlements(subaccountID string, configDir string, filterValues []string) { dataBlock, err := readSubaccountEntilementsDataSource(subaccountID) if err != nil { @@ -44,7 +45,7 @@ func exportSubaccountEntitlements(subaccountID string, configDir string) { return } - importBlock, err := getEntitlementsImportBlock(data, subaccountID) + importBlock, err := getEntitlementsImportBlock(data, subaccountID, filterValues) if err != nil { log.Fatalf("error: %v", err) return @@ -82,7 +83,7 @@ func readSubaccountEntilementsDataSource(subaccountId string) (string, error) { } -func getEntitlementsImportBlock(data map[string]interface{}, subaccountId string) (string, error) { +func getEntitlementsImportBlock(data map[string]interface{}, subaccountId string, filterValues []string) (string, error) { choice := "btp_subaccount_entitlement" resource_doc, err := tfutils.GetDocsForResource("SAP", "btp", "btp", "resources", choice, BtpProviderVersion, "github.com") if err != nil { @@ -91,17 +92,38 @@ func getEntitlementsImportBlock(data map[string]interface{}, subaccountId string } var importBlock string - for key, value := range data { - template := strings.Replace(resource_doc.Import, "", strings.Replace(key, ":", "_", -1), -1) - template = strings.Replace(template, "", subaccountId, -1) - if subMap, ok := value.(map[string]interface{}); ok { - for subKey, subValue := range subMap { - template = strings.Replace(template, "<"+subKey+">", fmt.Sprintf("%v", subValue), -1) + if len(filterValues) != 0 { + var subaccountAllEntitlements []string + for key, value := range data { + subaccountAllEntitlements = append(subaccountAllEntitlements, strings.Replace(key, ":", "_", -1)) + if slices.Contains(filterValues, strings.Replace(key, ":", "_", -1)) { + importBlock += templateEntitlementImport(key, value, subaccountId, resource_doc) } } - importBlock += template + "\n" + + missingEntitlement, subset := isSubset(subaccountAllEntitlements, filterValues) + + if !subset { + return "", fmt.Errorf("entitlement %s not found in the subaccount. Please adjust it in the provided file", missingEntitlement) + } + + } else { + for key, value := range data { + importBlock += templateEntitlementImport(key, value, subaccountId, resource_doc) + } } return importBlock, nil } + +func templateEntitlementImport(key string, value interface{}, subaccountId string, resource_doc tfutils.EntityDocs) string { + template := strings.Replace(resource_doc.Import, "", strings.Replace(key, ":", "_", -1), -1) + template = strings.Replace(template, "", subaccountId, -1) + if subMap, ok := value.(map[string]interface{}); ok { + for subKey, subValue := range subMap { + template = strings.Replace(template, "<"+subKey+">", fmt.Sprintf("%v", subValue), -1) + } + } + return template + "\n" +} diff --git a/cmd/exportSubaccountEntitlementsHelper_test.go b/cmd/exportSubaccountEntitlementsHelper_test.go index 51ca8cf..11245c9 100644 --- a/cmd/exportSubaccountEntitlementsHelper_test.go +++ b/cmd/exportSubaccountEntitlementsHelper_test.go @@ -31,7 +31,7 @@ func TestGetEntitlementsImportBlock(t *testing.T) { t.Errorf("error in unmarshalling") } - importBlock, err := getEntitlementsImportBlock(data, "5163621f-6a1e-4fbf-af3a-0f530a0dc4d5") + importBlock, err := getEntitlementsImportBlock(data, "5163621f-6a1e-4fbf-af3a-0f530a0dc4d5", nil) if err != nil { t.Errorf("error creating importBlock") } diff --git a/cmd/exportSubaccountHelper.go b/cmd/exportSubaccountHelper.go index fc650db..5bb4355 100644 --- a/cmd/exportSubaccountHelper.go +++ b/cmd/exportSubaccountHelper.go @@ -10,7 +10,7 @@ import ( "strings" ) -func exportSubaccount(subaccountID string, configDir string, optionalValues ...[]string) { +func exportSubaccount(subaccountID string, configDir string, filterValues []string) { dataBlock, err := readSubaccountDataSource(subaccountID) if err != nil { @@ -44,15 +44,14 @@ func exportSubaccount(subaccountID string, configDir string, optionalValues ...[ return } - if len(optionalValues) != 0 { - valueFromJson := optionalValues[0] - if valueFromJson[0] != fmt.Sprintf("%v", data["name"]) { - log.Println("Error:", fmt.Errorf("subaccount %s not found. Please adjust it in the provided file", valueFromJson[0])) + if len(filterValues) != 0 { + if filterValues[0] != fmt.Sprintf("%v", data["name"]) { + log.Println("Error:", fmt.Errorf("subaccount %s not found. Please adjust it in the provided file", filterValues[0])) os.Exit(0) } } - importBlock, err := getSubaccountImportBlock(data, subaccountID) + importBlock, err := getSubaccountImportBlock(data, subaccountID, nil) if err != nil { log.Fatalf("error: %v", err) return @@ -83,7 +82,7 @@ func readSubaccountDataSource(subaccountId string) (string, error) { } -func getSubaccountImportBlock(data map[string]interface{}, subaccountId string) (string, error) { +func getSubaccountImportBlock(data map[string]interface{}, subaccountId string, filterValues []string) (string, error) { choice := "btp_subaccount" resource_doc, err := tfutils.GetDocsForResource("SAP", "btp", "btp", "resources", choice, BtpProviderVersion, "github.com") if err != nil { diff --git a/cmd/exportSubaccountHelper_test.go b/cmd/exportSubaccountHelper_test.go index 26d337b..799d41f 100644 --- a/cmd/exportSubaccountHelper_test.go +++ b/cmd/exportSubaccountHelper_test.go @@ -30,7 +30,7 @@ func TestGetSubaccountImportBlock(t *testing.T) { t.Errorf("error in unmarshalling") } - importBlock, err := getSubaccountImportBlock(data, "5163621f-6a1e-4fbf-af3a-0f530a0dc4d5") + importBlock, err := getSubaccountImportBlock(data, "5163621f-6a1e-4fbf-af3a-0f530a0dc4d5", nil) if err != nil { t.Errorf("error creating importBlock") } diff --git a/cmd/exportSubaccountSubscriptions.go b/cmd/exportSubaccountSubscriptions.go index dc3409d..5ca086f 100644 --- a/cmd/exportSubaccountSubscriptions.go +++ b/cmd/exportSubaccountSubscriptions.go @@ -15,7 +15,7 @@ var exportSubaccountSubscriptionsCmd = &cobra.Command{ resourceFileName, _ := cmd.Flags().GetString("resourceFileName") configDir, _ := cmd.Flags().GetString("config-output-dir") setupConfigDir(configDir) - exportSubaccountSubscriptions(subaccount, configDir) + exportSubaccountSubscriptions(subaccount, configDir, nil) generateConfig(resourceFileName, configDir) }, } diff --git a/cmd/exportSubaccountSubscriptionsHelper.go b/cmd/exportSubaccountSubscriptionsHelper.go index 65c068d..bb489b0 100644 --- a/cmd/exportSubaccountSubscriptionsHelper.go +++ b/cmd/exportSubaccountSubscriptionsHelper.go @@ -7,10 +7,11 @@ import ( "log" "os" "path/filepath" + "slices" "strings" ) -func exportSubaccountSubscriptions(subaccountID string, configDir string) { +func exportSubaccountSubscriptions(subaccountID string, configDir string, filterValues []string) { dataBlock, err := readSubaccountSubscriptionDataSource(subaccountID) if err != nil { @@ -45,7 +46,7 @@ func exportSubaccountSubscriptions(subaccountID string, configDir string) { return } - importBlock, err := getSubscriptionsImportBlock(data, subaccountID) + importBlock, err := getSubscriptionsImportBlock(data, subaccountID, filterValues) if err != nil { fmt.Println("error:", err) return @@ -82,7 +83,7 @@ func readSubaccountSubscriptionDataSource(subaccountId string) (string, error) { } -func getSubscriptionsImportBlock(data map[string]interface{}, subaccountId string) (string, error) { +func getSubscriptionsImportBlock(data map[string]interface{}, subaccountId string, filterValues []string) (string, error) { choice := "btp_subaccount_subscription" resource_doc, err := tfutils.GetDocsForResource("SAP", "btp", "btp", "resources", choice, BtpProviderVersion, "github.com") if err != nil { @@ -93,16 +94,40 @@ func getSubscriptionsImportBlock(data map[string]interface{}, subaccountId strin var importBlock string subscriptions := data["values"].([]interface{}) - for _, value := range subscriptions { - subscription := value.(map[string]interface{}) - if fmt.Sprintf("%v", subscription["state"]) != "NOT_SUBSCRIBED" { - template := strings.Replace(resource_doc.Import, "", strings.Replace(fmt.Sprintf("%v", subscription["app_name"]), "-", "_", -1), -1) - template = strings.Replace(template, "", subaccountId, -1) - template = strings.Replace(template, "", fmt.Sprintf("%v", subscription["app_name"]), -1) - template = strings.Replace(template, "", fmt.Sprintf("%v", subscription["plan_name"]), -1) - importBlock += template + "\n" + if len(filterValues) != 0 { + var subaccountAllSubscriptions []string + + for _, value := range subscriptions { + subscription := value.(map[string]interface{}) + subaccountAllSubscriptions = append(subaccountAllSubscriptions, fmt.Sprintf("%v", subscription["app_name"])+"_"+fmt.Sprintf("%v", subscription["plan_name"])) + if slices.Contains(filterValues, fmt.Sprintf("%v", subscription["app_name"])+"_"+fmt.Sprintf("%v", subscription["plan_name"])) { + importBlock += templateSubscriptionImport(subscription, subaccountId, resource_doc) + } + } + + missingSubscription, subset := isSubset(subaccountAllSubscriptions, filterValues) + + if !subset { + return "", fmt.Errorf("subscription %s not found in the subaccount. Please adjust it in the provided file", missingSubscription) + + } + + } else { + for _, value := range subscriptions { + subscription := value.(map[string]interface{}) + if fmt.Sprintf("%v", subscription["state"]) != "NOT_SUBSCRIBED" { + importBlock += templateSubscriptionImport(subscription, subaccountId, resource_doc) + } } } return importBlock, nil } + +func templateSubscriptionImport(subscription map[string]interface{}, subaccountId string, resource_doc tfutils.EntityDocs) string { + template := strings.Replace(resource_doc.Import, "", strings.Replace(fmt.Sprintf("%v", subscription["app_name"]), "-", "_", -1), -1) + template = strings.Replace(template, "", subaccountId, -1) + template = strings.Replace(template, "", fmt.Sprintf("%v", subscription["app_name"]), -1) + template = strings.Replace(template, "", fmt.Sprintf("%v", subscription["plan_name"]), -1) + return template + "\n" +} diff --git a/cmd/exportSubaccountSubscriptionsHelper_Test.go b/cmd/exportSubaccountSubscriptionsHelper_Test.go index 3c4b0c6..154cd5a 100644 --- a/cmd/exportSubaccountSubscriptionsHelper_Test.go +++ b/cmd/exportSubaccountSubscriptionsHelper_Test.go @@ -30,7 +30,7 @@ func TestGetSubscriptionsImportBlock(t *testing.T) { t.Errorf("error in unmarshalling") } - importBlock, err := getSubscriptionsImportBlock(data, "5163621f-6a1e-4fbf-af3a-0f530a0dc4d5") + importBlock, err := getSubscriptionsImportBlock(data, "5163621f-6a1e-4fbf-af3a-0f530a0dc4d5", nil) if err != nil { t.Errorf("error creating importBlock") } diff --git a/cmd/exportTrustConfigurations.go b/cmd/exportTrustConfigurations.go index 3eb10ec..c0c8af6 100644 --- a/cmd/exportTrustConfigurations.go +++ b/cmd/exportTrustConfigurations.go @@ -15,7 +15,7 @@ var exportTrustConfigurationsCmd = &cobra.Command{ resourceFileName, _ := cmd.Flags().GetString("resourceFileName") configDir, _ := cmd.Flags().GetString("config-output-dir") setupConfigDir(configDir) - exportTrustConfigurations(subaccount, configDir) + exportTrustConfigurations(subaccount, configDir, nil) generateConfig(resourceFileName, configDir) }, } diff --git a/cmd/exportTrustConfigurationsHelper.go b/cmd/exportTrustConfigurationsHelper.go index 8c2aef0..ed1b338 100644 --- a/cmd/exportTrustConfigurationsHelper.go +++ b/cmd/exportTrustConfigurationsHelper.go @@ -7,10 +7,11 @@ import ( "log" "os" "path/filepath" + "slices" "strings" ) -func exportTrustConfigurations(subaccountID string, configDir string) { +func exportTrustConfigurations(subaccountID string, configDir string, filterValues []string) { dataBlock, err := readSubaccountTrustConfigurationsDataSource(subaccountID) if err != nil { log.Fatalf("error getting data source: %v", err) @@ -43,7 +44,7 @@ func exportTrustConfigurations(subaccountID string, configDir string) { return } - importBlock, err := getTrustConfigurationsImportBlock(data, subaccountID) + importBlock, err := getTrustConfigurationsImportBlock(data, subaccountID, filterValues) if err != nil { log.Fatalf("error: %v", err) return @@ -80,7 +81,7 @@ func readSubaccountTrustConfigurationsDataSource(subaccountId string) (string, e } -func getTrustConfigurationsImportBlock(data map[string]interface{}, subaccountId string) (string, error) { +func getTrustConfigurationsImportBlock(data map[string]interface{}, subaccountId string, filterValues []string) (string, error) { choice := "btp_subaccount_trust_configuration" resource_doc, err := tfutils.GetDocsForResource("SAP", "btp", "btp", "resources", choice, BtpProviderVersion, "github.com") if err != nil { @@ -91,13 +92,35 @@ func getTrustConfigurationsImportBlock(data map[string]interface{}, subaccountId var importBlock string trusts := data["values"].([]interface{}) - for x, value := range trusts { - trust := value.(map[string]interface{}) - template := strings.Replace(resource_doc.Import, "", "trust"+fmt.Sprint(x), -1) - template = strings.Replace(template, "", subaccountId, -1) - template = strings.Replace(template, "", fmt.Sprintf("%v", trust["origin"]), -1) - importBlock += template + "\n" + if len(filterValues) != 0 { + var subaccountAllTrusts []string + + for x, value := range trusts { + trust := value.(map[string]interface{}) + subaccountAllTrusts = append(subaccountAllTrusts, fmt.Sprintf("%v", trust["origin"])) + if slices.Contains(filterValues, fmt.Sprintf("%v", trust["origin"])) { + importBlock += templateTrustImport(x, trust, subaccountId, resource_doc) + } + } + + missingTrust, subset := isSubset(subaccountAllTrusts, filterValues) + + if !subset { + return "", fmt.Errorf("trust configuration %s not found in the subaccount. Please adjust it in the provided file", missingTrust) + } + } else { + for x, value := range trusts { + trust := value.(map[string]interface{}) + importBlock += templateTrustImport(x, trust, subaccountId, resource_doc) + } } return importBlock, nil } + +func templateTrustImport(x int, trust map[string]interface{}, subaccountId string, resource_doc tfutils.EntityDocs) string { + template := strings.Replace(resource_doc.Import, "", "trust"+fmt.Sprint(x), -1) + template = strings.Replace(template, "", subaccountId, -1) + template = strings.Replace(template, "", fmt.Sprintf("%v", trust["origin"]), -1) + return template + "\n" +} diff --git a/cmd/exportTrustConfigurationsHelper_test.go b/cmd/exportTrustConfigurationsHelper_test.go index 33c12be..82df7cd 100644 --- a/cmd/exportTrustConfigurationsHelper_test.go +++ b/cmd/exportTrustConfigurationsHelper_test.go @@ -30,7 +30,7 @@ func TestGetTrustConfigurationsImportBlock(t *testing.T) { t.Errorf("error in unmarshalling") } - importBlock, err := getTrustConfigurationsImportBlock(data, "5163621f-6a1e-4fbf-af3a-0f530a0dc4d5") + importBlock, err := getTrustConfigurationsImportBlock(data, "5163621f-6a1e-4fbf-af3a-0f530a0dc4d5", nil) if err != nil { t.Errorf("error creating importBlock") } diff --git a/tfutils/docs.go b/tfutils/docs.go index 7b44c5e..66f3177 100644 --- a/tfutils/docs.go +++ b/tfutils/docs.go @@ -38,8 +38,8 @@ type argumentDocs struct { isNested bool } -// entityDocs represents the documentation for a resource or datasource as extracted from TF markdown. -type entityDocs struct { +// EntityDocs represents the documentation for a resource or datasource as extracted from TF markdown. +type EntityDocs struct { // Description is the description of the resource Description string Arguments map[string]*argumentDocs @@ -140,7 +140,7 @@ type tfMarkdownParser struct { kind DocKind markdownFileName string rawname string - ret entityDocs + ret EntityDocs } // splitGroupLines splits and groups a string, s, by a given separator, sep. @@ -566,7 +566,7 @@ func (ns *nestedSchema) allParameters() []parameter { } func parseTopLevelSchemaIntoDocs( - accumulatedDocs *entityDocs, + accumulatedDocs *EntityDocs, topLevelSchema *topLevelSchema, ) { //for _, param := range topLevelSchema.allParameters() { @@ -588,7 +588,7 @@ func parseTopLevelSchemaIntoDocs( } func parseNestedSchemaIntoDocuments( - accumulatedDocs *entityDocs, + accumulatedDocs *EntityDocs, nestedSchema *nestedSchema, ) { @@ -618,7 +618,7 @@ func parseNestedSchemaIntoDocuments( } } -func (ed *entityDocs) getOrCreateArgumentDocs(argumentName string) (*argumentDocs, bool) { +func (ed *EntityDocs) getOrCreateArgumentDocs(argumentName string) (*argumentDocs, bool) { if ed.Arguments == nil { ed.Arguments = make(map[string]*argumentDocs) } @@ -851,7 +851,7 @@ func getNestedBlockNames(line string) string { var genericNestedRegexp = regexp.MustCompile("supports? the following:") -func parseArgumentReferenceSection(subsec []string, entity *entityDocs) { +func parseArgumentReferenceSection(subsec []string, entity *EntityDocs) { var lastArgument, nestedBlock string addHeading := func(headingName string, headingDescription string, line string) { @@ -976,7 +976,7 @@ func (p *tfMarkdownParser) parseImport(importLines []string) { p.ret.Import = p.ret.Import + strings.Join(importString, " ") } -func parseAttrReferenceSection(attributeLines []string, entity *entityDocs) { +func parseAttrReferenceSection(attributeLines []string, entity *EntityDocs) { var lastMatchedAttribute string for _, line := range attributeLines { matches := attributeBulletRegexp.FindStringSubmatch(line) @@ -1054,7 +1054,7 @@ func reorgenizeText(text string) (string, bool) { return strings.TrimSpace(strings.Join(parts, "")), false } -func cleanupDocument(name string, doc entityDocs) (entityDocs, bool) { +func cleanupDocument(name string, doc EntityDocs) (EntityDocs, bool) { hasElidedDoc := false cleanedArguments := make(map[string]*argumentDocs, len(doc.Arguments)) @@ -1106,7 +1106,7 @@ func cleanupDocument(name string, doc entityDocs) (entityDocs, bool) { doc.Import += "}\n" } - return entityDocs{ + return EntityDocs{ Description: cleanupText, Arguments: cleanedArguments, Attributes: cleanedAttributes, @@ -1114,8 +1114,8 @@ func cleanupDocument(name string, doc entityDocs) (entityDocs, bool) { }, hasElidedDoc } -func (p *tfMarkdownParser) parse(tfMarkdown []byte) (entityDocs, error) { - p.ret = entityDocs{ +func (p *tfMarkdownParser) parse(tfMarkdown []byte) (EntityDocs, error) { + p.ret = EntityDocs{ Arguments: make(map[string]*argumentDocs), Attributes: make(map[string]string), } @@ -1132,7 +1132,7 @@ func (p *tfMarkdownParser) parse(tfMarkdown []byte) (entityDocs, error) { for _, section := range sections { if err := p.parseMarkdownSections(section); err != nil { - return entityDocs{}, err + return EntityDocs{}, err } } @@ -1144,7 +1144,7 @@ func (p *tfMarkdownParser) parse(tfMarkdown []byte) (entityDocs, error) { // parseTFMarkdown takes a TF website markdown doc and extracts a structured representation for use in // generating doc comments func parseTFMarkdown(kind DocKind, - markdown []byte, markdownFileName, rawname string) (entityDocs, error) { + markdown []byte, markdownFileName, rawname string) (EntityDocs, error) { p := &tfMarkdownParser{ kind: kind, @@ -1158,17 +1158,17 @@ func parseTFMarkdown(kind DocKind, // TF website documentation markdown content func GetDocsForResource(org string, provider string, resourcePrefix string, kind DocKind, rawname string /* info tfbridge.ResourceOrDataSourceInfo, */, providerModuleVersion string, - githost string) (entityDocs, error) { + githost string) (EntityDocs, error) { markdownBytes, markdownFileName, found := getMarkdownDetails(org, provider, resourcePrefix, kind, rawname, providerModuleVersion, githost) if !found { - return entityDocs{}, fmt.Errorf("could not find docs for %v %v", kind, rawname) + return EntityDocs{}, fmt.Errorf("could not find docs for %v %v", kind, rawname) } doc, err := parseTFMarkdown(kind, markdownBytes, markdownFileName, rawname) if err != nil { - return entityDocs{}, err + return EntityDocs{}, err } return doc, nil diff --git a/tfutils/docs_test.go b/tfutils/docs_test.go index f1e4510..769d29b 100644 --- a/tfutils/docs_test.go +++ b/tfutils/docs_test.go @@ -54,7 +54,7 @@ func TestParseArgumentFromMarkdownLine(t *testing.T) { } func TestParseAttrReferenceSection(t *testing.T) { - ret := entityDocs{ + ret := EntityDocs{ Arguments: make(map[string]*argumentDocs), Attributes: make(map[string]string), } @@ -300,7 +300,7 @@ func TestArgumentRegularExp(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - ret := entityDocs{ + ret := EntityDocs{ Arguments: make(map[string]*argumentDocs), } parseArgumentReferenceSection(tt.input, &ret) From f568ffd139ceb0c9243e53e80e42117222142925 Mon Sep 17 00:00:00 2001 From: Christian Lechner <22294087+lechnerc77@users.noreply.github.com.> Date: Fri, 13 Sep 2024 16:13:09 +0200 Subject: [PATCH 2/2] refactor: delegation to correct export --- cmd/exportFromFileHelper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/exportFromFileHelper.go b/cmd/exportFromFileHelper.go index f7cedbf..254f9af 100644 --- a/cmd/exportFromFileHelper.go +++ b/cmd/exportFromFileHelper.go @@ -73,7 +73,7 @@ func generateConfigForResource(resource string, values []string, subaccount stri exportSubaccount(subaccount, configDir, values) } if resource == "entitlements" { - exportEnvironmentInstances(subaccount, configDir, values) + exportSubaccountEntitlements(subaccount, configDir, values) } if resource == "subscriptions" { exportSubaccountSubscriptions(subaccount, configDir, values)