From 4304fce20b79af0a55f9cc1464e894a0d58ac785 Mon Sep 17 00:00:00 2001 From: Daniel Gonzalez Date: Fri, 25 Oct 2024 10:25:28 -0600 Subject: [PATCH] initial --- main.go | 22 +++++++++++++++++++--- pipelines.go | 33 ++++++++++++++++++++++++++------- projects.go | 4 ++-- reconcilepipeline.go | 4 ++-- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/main.go b/main.go index 2207fd0..08fddd8 100644 --- a/main.go +++ b/main.go @@ -65,6 +65,7 @@ var migrationReq = struct { SpinnakerAPIKey string `survey:"spinnaker-api-key"` SpinnakerAppName string `survey:"app-name"` PipelineName string `survey:"pipeline-name"` + PipelineJson string `survey:"pipeline-json"` Cert string `survey:"cert"` Key string `survey:"key"` Auth64 string `survey:"auth64"` @@ -136,18 +137,28 @@ func logMigrationDetails() { } func logSpinnakerMigrationDetails(authMethod string) { + + determinePipelineOutput := func() string { + if len(migrationReq.PipelineJson) > 0 { + return migrationReq.PipelineJson + } + if len(migrationReq.PipelineName) > 0 { + return migrationReq.PipelineName + } + return "All" + } // Manually format the log message with line breaks logMessage := fmt.Sprintf("\nMigration details:\n"+ " Platform: %s\n"+ " Spinnaker Host: %s\n"+ " App name: %s\n"+ - " Pipeline Name: %s\n"+ + " Pipeline(s): %s\n"+ " Authentication method: %s \n"+ " Insecure: %t", migrationReq.Platform, migrationReq.SpinnakerHost, migrationReq.SpinnakerAppName, - migrationReq.PipelineName, + determinePipelineOutput(), authMethod, migrationReq.AllowInsecureReq, ) @@ -346,6 +357,11 @@ func main() { Usage: "Specifies URL to the Spinnaker Gate service. Required when --platform is spinnaker.", Destination: &migrationReq.SpinnakerHost, }), + altsrc.NewStringFlag(&cli.StringFlag{ + Name: "pipeline-json", + Usage: "Specifies Spinnaker Pipeline JSON file to be migrated.", + Destination: &migrationReq.PipelineJson, + }), altsrc.NewStringFlag(&cli.StringFlag{ Name: "spinnaker-api-key", Usage: "Specifies URL to the Spinnaker Gate service. Required when --platform is spinnaker.", @@ -593,7 +609,7 @@ func main() { }, &cli.StringFlag{ Name: "pipeline-name", - Usage: "Specifies Spinnaker Pipeline which to be migrated.", + Usage: "Specifies Spinnaker Pipeline to be migrated.", Destination: &migrationReq.PipelineName, }, &cli.StringFlag{ diff --git a/pipelines.go b/pipelines.go index 7e7726e..790c28f 100644 --- a/pipelines.go +++ b/pipelines.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "os" "sort" "strconv" @@ -72,14 +73,16 @@ func migrateSpinnakerPipelines() error { authMethod = authx509 } log.Info("Importing the application....") - if len(migrationReq.SpinnakerHost) == 0 { + if len(migrationReq.PipelineJson) == 0 && len(migrationReq.SpinnakerHost) == 0 { migrationReq.SpinnakerHost = TextInput("Please provide spinnaker host : ") } - if len(migrationReq.SpinnakerAppName) == 0 { + if len(migrationReq.PipelineJson) == 0 && len(migrationReq.SpinnakerAppName) == 0 { migrationReq.SpinnakerAppName = TextInput("Please provide the Spinnaker application name : ") } if !migrationReq.All { - migrationReq.PipelineName = TextInput("Please provide the Spinnaker pipeline name : ") + if len(migrationReq.PipelineJson) == 0 { + migrationReq.PipelineName = TextInput("Please provide the Spinnaker pipeline name : ") + } } logSpinnakerMigrationDetails(authMethod) @@ -87,25 +90,41 @@ func migrateSpinnakerPipelines() error { if !confirm { log.Fatal("Aborting...") } + var jsonBody []byte var pipelines []map[string]interface{} var err error + if len(migrationReq.PipelineName) > 0 { jsonBody, err = getSinglePipeline(authMethod, migrationReq.PipelineName) } else { - jsonBody, err = getAllPipelines(authMethod, migrationReq.SpinnakerAppName) + if len(migrationReq.PipelineJson) > 0 { + // Read from file + jsonBody, err = os.ReadFile(migrationReq.PipelineJson) + if err != nil { + return fmt.Errorf("failed to read pipeline JSON file: %v", err) + } + } else { + jsonBody, err = getAllPipelines(authMethod, migrationReq.SpinnakerAppName) + } } + if err != nil { return err } + pipelines, err = normalizeJsonArray(jsonBody) if err != nil { return err } - pipelines, err = fetchDependentPipelines(pipelines, err, authMethod) + + if len(migrationReq.PipelineJson) == 0 { + pipelines, err = fetchDependentPipelines(pipelines, err, authMethod) + } if err != nil { return err } + payload := map[string][]map[string]interface{}{"pipelines": pipelines} _, err = createSpinnakerPipelines(payload) return err @@ -163,8 +182,8 @@ func addDependentPipelineRecursive(pipelines []map[string]interface{}, pipelineS } stages, ok := p["stages"].([]interface{}) if !ok { - fmt.Println("error: nable to assert 'stages' to the correct type.") - return nil, errors.New("unable to assert 'stages' to the correct type") + fmt.Println("error: unable to assert 'stages' to the correct type. :(((") + return nil, errors.New("unable to assert 'stages' to the correct type :(((((") } for _, stage := range stages { s := stage.(map[string]interface{}) diff --git a/projects.go b/projects.go index ed4f6e3..e17e29c 100644 --- a/projects.go +++ b/projects.go @@ -53,7 +53,7 @@ func createProject(*cli.Context) error { } func createAProject(orgIdentifier string, name string, identifier string) error { - url := fmt.Sprintf("%s/api/projects?accountIdentifier=%s&orgIdentifier=%s", GetBaseUrl(migrationReq.Environment, NextGenService), migrationReq.Account, orgIdentifier) + url := fmt.Sprintf("%s/api/projects?accountIdentifier=%s&orgIdentifier=%s", GetBaseUrl("Prod", NextGenService), migrationReq.Account, orgIdentifier) _, err := Post(url, migrationReq.Auth, ProjectBody{ Project: ProjectDetails{ OrgIdentifier: orgIdentifier, @@ -359,7 +359,7 @@ func CheckProjectExistsAndCreate() error { log.Infof("Project with identifier %s exists", migrationReq.ProjectIdentifier) } else { log.Infof("Project with identifier %s does not exist", migrationReq.ProjectIdentifier) - if err := createAProject(migrationReq.OrgIdentifier, migrationReq.ProjectIdentifier, formatString(migrationReq.ProjectIdentifier)); err != nil { + if err := createAProject(migrationReq.OrgIdentifier, migrationReq.ProjectIdentifier, migrationReq.ProjectIdentifier); err != nil { log.Error(err) } log.Infof("Project with identifier %s created", migrationReq.ProjectIdentifier) diff --git a/reconcilepipeline.go b/reconcilepipeline.go index 589198f..33c4c14 100644 --- a/reconcilepipeline.go +++ b/reconcilepipeline.go @@ -70,7 +70,7 @@ func performReconciliation(pipelineID string, queryParams map[string]string) { // It makes a request to fetch the UUID of the pipeline. func getPipelineUUID(identifier string, queryParams map[string]string) (string, error) { queryParams["getDefaultFromOtherRepo"] = "true" - url := GetUrlWithQueryParams(migrationReq.Environment, PipelineService, "api/pipelines/"+identifier+"/validate", queryParams) + url := GetUrlWithQueryParams("Prod", PipelineService, "api/pipelines/"+identifier+"/validate", queryParams) respBody, err := Post(url, migrationReq.Auth, nil) if err != nil { return "", err @@ -85,7 +85,7 @@ func getPipelineUUID(identifier string, queryParams map[string]string) (string, // checkReconcileNeeded is a function that takes a pipeline UUID and a map of query parameters. // It makes a request to check if reconciliation is needed for the pipeline. func checkReconcileNeeded(uuid string, queryParams map[string]string) (bool, error) { - url := GetUrlWithQueryParams(migrationReq.Environment, PipelineService, "api/pipelines/validate/"+uuid, queryParams) + url := GetUrlWithQueryParams("Prod", PipelineService, "api/pipelines/validate/"+uuid, queryParams) respBodyObj, err := Get(url, migrationReq.Auth) if err != nil { return false, err