From 310d3114a8d23e90da7961e0d14c499b3a1774ed Mon Sep 17 00:00:00 2001 From: rch Date: Thu, 20 Nov 2025 14:23:59 -0800 Subject: [PATCH] Remove TF generation feature (data sources provide and improve upon the extant functionality, and it is unused) --- cmd/cone/main.go | 1 - cmd/cone/terraform.go | 22 ---- cmd/cone/terraform_flags.go | 11 -- cmd/cone/terraform_gen.go | 198 ----------------------------------- pkg/terraform/app.go | 33 ------ pkg/terraform/entitlement.go | 40 ------- pkg/terraform/policy.go | 35 ------- pkg/terraform/templater.go | 68 ------------ 8 files changed, 408 deletions(-) delete mode 100644 cmd/cone/terraform.go delete mode 100644 cmd/cone/terraform_flags.go delete mode 100644 cmd/cone/terraform_gen.go delete mode 100644 pkg/terraform/app.go delete mode 100644 pkg/terraform/entitlement.go delete mode 100644 pkg/terraform/policy.go delete mode 100644 pkg/terraform/templater.go diff --git a/cmd/cone/main.go b/cmd/cone/main.go index 9d09d497..1bfa7425 100644 --- a/cmd/cone/main.go +++ b/cmd/cone/main.go @@ -71,7 +71,6 @@ func runCli(ctx context.Context) int { cliCmd.AddCommand(loginCmd()) cliCmd.AddCommand(hasCmd()) cliCmd.AddCommand(tokenCmd()) - cliCmd.AddCommand(terraformCmd()) cliCmd.AddCommand(decryptCredentialCmd()) err = cliCmd.ExecuteContext(ctx) diff --git a/cmd/cone/terraform.go b/cmd/cone/terraform.go deleted file mode 100644 index cb710250..00000000 --- a/cmd/cone/terraform.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "github.com/spf13/cobra" -) - -func terraformCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "terraform", - Aliases: []string{"tf"}, - Short: "A group of commands related to interacting with a terraform provider.", - RunE: terraformRun, - } - - cmd.AddCommand(terraformGenCmd()) - - return cmd -} - -func terraformRun(cmd *cobra.Command, _ []string) error { - return cmd.Help() -} diff --git a/cmd/cone/terraform_flags.go b/cmd/cone/terraform_flags.go deleted file mode 100644 index 5b656a5d..00000000 --- a/cmd/cone/terraform_flags.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -import "github.com/spf13/cobra" - -const ( - tfAppIdFlag = "app-id" -) - -func addTfAppIdFlag(cmd *cobra.Command) { - cmd.Flags().String(tfAppIdFlag, "", "App ID to get entitlements for.") -} diff --git a/cmd/cone/terraform_gen.go b/cmd/cone/terraform_gen.go deleted file mode 100644 index 23fc68c7..00000000 --- a/cmd/cone/terraform_gen.go +++ /dev/null @@ -1,198 +0,0 @@ -package main - -import ( - "bytes" - "context" - "errors" - "fmt" - "os" - "os/exec" - "path" - "path/filepath" - "strings" - - "github.com/conductorone/cone/pkg/client" - "github.com/conductorone/cone/pkg/terraform" - "github.com/pterm/pterm" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "golang.org/x/exp/maps" - "golang.org/x/exp/slices" -) - -const ( - terraformProviderExample = "https://github.com/ConductorOne/terraform-provider-conductorone/blob/main/examples/provider/provider.tf" - tempTfFile = "cone_temp.tf" -) - -var objects = []string{"policy", "app_entitlement"} - -func terraformGenCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "gen ", - Short: fmt.Sprintf("Import all terraform resources for the specified object type (%s, or * for all). Terraform v1.5 or later is required", strings.Join(objects, ", ")), - RunE: terraformGen, - } - addTfAppIdFlag(cmd) - - return cmd -} - -func writeToFile(filename, data string) error { - file, err := os.Create(filename) - if err != nil { - return err - } - defer file.Close() - - _, err = file.WriteString(data) - if err != nil { - return err - } - - return nil -} - -func getResourceMap(ctx context.Context, c client.C1Client, v *viper.Viper, object string) (map[string]terraform.TemplateData, error) { - resources := make(map[string]terraform.TemplateData) - if err := populateResourcesWithApps(ctx, c, object, resources); err != nil { - return nil, err - } - if err := populateResourcesWithPolicies(ctx, c, object, resources); err != nil { - return nil, err - } - if err := populateResourcesWithEntitlements(ctx, c, v, object, resources); err != nil { - return nil, err - } - return resources, nil -} - -func populateResourcesWithApps(ctx context.Context, c client.C1Client, object string, resources map[string]terraform.TemplateData) error { - if object == "app" || object == "*" { - apps, err := c.ListApps(ctx) - if err != nil { - return err - } - for _, app := range apps { - tmplData := terraform.AppTemplate{App: app} - resources[tmplData.GetOutputId()] = tmplData - } - } - return nil -} - -func populateResourcesWithPolicies(ctx context.Context, c client.C1Client, object string, resources map[string]terraform.TemplateData) error { - if object == "policy" || object == "*" { - policies, err := c.ListPolicies(ctx) - if err != nil { - return err - } - for _, policy := range policies { - tmplData := terraform.PolicyTemplate{Policy: policy} - resources[tmplData.GetOutputId()] = tmplData - } - } - return nil -} - -func populateResourcesWithEntitlements(ctx context.Context, c client.C1Client, v *viper.Viper, object string, resources map[string]terraform.TemplateData) error { - if object == "app_entitlement" || object == "*" { - appId := v.GetString(tfAppIdFlag) - if appId == "" { - return errors.New("app-id flag is required for app_entitlement object") - } - - entitlements, err := c.ListEntitlements(ctx, appId) - if err != nil { - return err - } - for _, entitlement := range entitlements { - tmplData := terraform.AppEntitlementTemplate{AppEntitlement: entitlement} - resources[tmplData.GetOutputId()] = tmplData - } - } - return nil -} - -func getFileName(object string) string { - switch object { - case "app_entitlement": - return "generated_app_entitlements.tf" - case "policy": - return "generated_policies.tf" - case "*": - return "generated_resources.tf" - default: - return "generated_objects.tf" - } -} - -func terraformGen(cmd *cobra.Command, args []string) error { - ctx, c, v, err := cmdContext(cmd) - if err != nil { - return err - } - - if err := validateArgLenth(2, args, cmd); err != nil { - return err - } - - object := args[0] - if !slices.Contains(objects, object) && object != "*" { - return fmt.Errorf("invalid object name, the following are supported: %s, or * for all)", strings.Join(objects, ", ")) - } - - inputDir := args[1] - terraformDir, err := filepath.Abs(inputDir) - if err != nil { - return fmt.Errorf("terraform directory %s does not exist", terraformDir) - } - - generatedFileName := getFileName(object) - - // File cannot already exist - generatedFilePath := path.Join(terraformDir, generatedFileName) - if _, err := os.Stat(generatedFilePath); err == nil { - pterm.Error.Printfln("The file %s already exists in the directory. Please remove it and try again.", generatedFileName) - return fmt.Errorf("file %s already exists", generatedFileName) - } - - tempFilePath := path.Join(terraformDir, tempTfFile) - - // Turns objects into dataTemplates - resources, err := getResourceMap(ctx, c, v, object) - if err != nil { - return err - } - - outputTemplate, err := terraform.ApplyTemplates(maps.Values(resources), terraform.ImportTemplateString) - if err != nil { - return err - } - - err = writeToFile(tempFilePath, outputTemplate) - if err != nil { - return err - } - - var buffer bytes.Buffer - - //nolint:gosec // this user input is being validated above, it should be safe to use here - cmdTf := exec.Command("terraform", "plan", "-generate-config-out="+generatedFileName) - cmdTf.Dir = terraformDir - cmdTf.Stdout = &buffer - err = cmdTf.Run() - if err != nil { - pterm.Info.Println("Please make sure you have Terraform v1.5 or later installed and the conductorone provider is v0.4.2 or later") - pterm.Info.Println("You can find out more here: https://developer.hashicorp.com/terraform/language/import/generating-configuration") - pterm.Error.Printfln("Try running `terraform plan -generate-config-out=%s` in `%s` to see a more detailed error message.", generatedFileName, terraformDir) - return fmt.Errorf("terraform plan failed: %w", err) - } - - pterm.Success.Println("Successfully generated terraform resources! Please review these resources and move them into your main configuration files.") - err = os.Remove(tempFilePath) - if err != nil { - return err - } - return nil -} diff --git a/pkg/terraform/app.go b/pkg/terraform/app.go deleted file mode 100644 index 6f243cce..00000000 --- a/pkg/terraform/app.go +++ /dev/null @@ -1,33 +0,0 @@ -package terraform - -import "github.com/conductorone/conductorone-sdk-go/pkg/models/shared" - -const TerraformAppType = "conductorone_app" - -type AppTemplate struct { - App shared.App -} - -func (a AppTemplate) GetRequired() map[string]string { - ids := make(map[string]string) - if a.App.DisplayName != nil { - ids["display_name"] = *a.App.DisplayName - } - return ids -} - -func (a AppTemplate) GetType() string { - return TerraformAppType // Assuming the type is "App" -} - -func (a AppTemplate) GetId() string { - return *a.App.ID -} - -func (a AppTemplate) GetResourceId() string { - return resourcePrefix + *a.App.ID -} - -func (a AppTemplate) GetOutputId() string { - return a.GetType() + "_" + a.GetResourceId() -} diff --git a/pkg/terraform/entitlement.go b/pkg/terraform/entitlement.go deleted file mode 100644 index c4f29453..00000000 --- a/pkg/terraform/entitlement.go +++ /dev/null @@ -1,40 +0,0 @@ -package terraform - -import ( - "github.com/conductorone/conductorone-sdk-go/pkg/models/shared" -) - -const TerraformAppEntilementType = "conductorone_app_entitlement" - -type AppEntitlementTemplate struct { - AppEntitlement shared.AppEntitlement -} - -func (ae AppEntitlementTemplate) GetRequired() map[string]string { - ids := make(map[string]string) - // Should probably be an error if any are nil - if ae.AppEntitlement.AppID != nil { - ids["app_id"] = *ae.AppEntitlement.AppID - } - if ae.AppEntitlement.AppResourceID != nil { - ids["id"] = *ae.AppEntitlement.ID - } - return ids -} - -func (ae AppEntitlementTemplate) GetType() string { - return TerraformAppEntilementType -} - -func (ae AppEntitlementTemplate) GetId() string { - ids := ae.GetRequired() - return ids["id"] + "_" + ids["app_id"] -} - -func (ae AppEntitlementTemplate) GetResourceId() string { - return resourcePrefix + ae.GetId() -} - -func (ae AppEntitlementTemplate) GetOutputId() string { - return ae.GetType() + "_" + ae.GetResourceId() -} diff --git a/pkg/terraform/policy.go b/pkg/terraform/policy.go deleted file mode 100644 index 035e29ff..00000000 --- a/pkg/terraform/policy.go +++ /dev/null @@ -1,35 +0,0 @@ -package terraform - -import ( - "github.com/conductorone/conductorone-sdk-go/pkg/models/shared" -) - -const TerraformPolicyType = "conductorone_policy" - -type PolicyTemplate struct { - Policy shared.Policy -} - -func (p PolicyTemplate) GetRequired() map[string]string { - ids := make(map[string]string) - if p.Policy.DisplayName != nil { - ids["display_name"] = *p.Policy.DisplayName - } - return ids -} - -func (p PolicyTemplate) GetType() string { - return TerraformPolicyType // Assuming the type is "App" -} - -func (p PolicyTemplate) GetId() string { - return *p.Policy.ID -} - -func (p PolicyTemplate) GetResourceId() string { - return resourcePrefix + *p.Policy.ID -} - -func (p PolicyTemplate) GetOutputId() string { - return p.GetType() + "_" + p.GetResourceId() -} diff --git a/pkg/terraform/templater.go b/pkg/terraform/templater.go deleted file mode 100644 index 64c28058..00000000 --- a/pkg/terraform/templater.go +++ /dev/null @@ -1,68 +0,0 @@ -package terraform - -import ( - "bytes" - "text/template" -) - -const resourcePrefix = "id_" -const ImportTemplateString = `import {{"{"}} - to = {{.GetType}}.{{.GetResourceId}} - id = "{{.GetId}}" -{{"}\n"}}` - -type TemplateData interface { - GetRequired() map[string]string - GetType() string - GetId() string - GetResourceId() string - GetOutputId() string -} - -func ObjectNameToTerraformType(objectName string) string { - switch objectName { - case "app": - return TerraformAppType - case "policy": - return TerraformPolicyType - case "app_entitlement": - return TerraformAppEntilementType - default: - return "" - } -} - -func ApplyTemplate(data TemplateData, tmpl string) (string, error) { - // Prepare a buffer to hold the combined output - var combinedOutput bytes.Buffer - - // Process the datasource template - templateString := template.New("tmpl") - - // Parse the template file - templateString, err := templateString.Parse(tmpl) - if err != nil { - return "", err - } - err = templateString.Execute(&combinedOutput, data) - if err != nil { - return "", err - } - - // Return the combined output as a string - return combinedOutput.String(), nil -} - -func ApplyTemplates(data []TemplateData, templates ...string) (string, error) { - res := "" - for _, v := range data { - for _, template := range templates { - str, err := ApplyTemplate(v, template) - if err != nil { - return "", err - } - res += str - } - } - return res, nil -}