github.com/spinnaker/spin@v1.30.0/cmd/application/save.go (about)

     1  // Copyright (c) 2018, Google, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //   http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  //   Unless required by applicable law or agreed to in writing, software
    10  //   distributed under the License is distributed on an "AS IS" BASIS,
    11  //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  //   See the License for the specific language governing permissions and
    13  //   limitations under the License.
    14  
    15  package application
    16  
    17  import (
    18  	"errors"
    19  	"fmt"
    20  	"strings"
    21  
    22  	"github.com/spf13/cobra"
    23  
    24  	orca_tasks "github.com/spinnaker/spin/cmd/orca-tasks"
    25  	"github.com/spinnaker/spin/util"
    26  )
    27  
    28  type saveOptions struct {
    29  	*applicationOptions
    30  	applicationFile string
    31  	applicationName string
    32  	ownerEmail      string
    33  	cloudProviders  *[]string
    34  }
    35  
    36  var (
    37  	saveApplicationShort = "Save the provided application"
    38  	saveApplicationLong  = "Save the specified application"
    39  )
    40  
    41  func NewSaveCmd(appOptions *applicationOptions) *cobra.Command {
    42  	options := &saveOptions{
    43  		applicationOptions: appOptions,
    44  	}
    45  	cmd := &cobra.Command{
    46  		Use:   "save",
    47  		Short: saveApplicationShort,
    48  		Long:  saveApplicationLong,
    49  		RunE: func(cmd *cobra.Command, args []string) error {
    50  			return saveApplication(cmd, options)
    51  		},
    52  	}
    53  	cmd.PersistentFlags().StringVarP(&options.applicationFile, "file", "f", "", "path to the application file")
    54  	cmd.PersistentFlags().StringVarP(&options.applicationName, "application-name", "a", "", "name of the application")
    55  	cmd.PersistentFlags().StringVarP(&options.ownerEmail, "owner-email", "", "", "email of the application owner")
    56  	options.cloudProviders = cmd.PersistentFlags().StringArrayP("cloud-providers", "", []string{}, "cloud providers configured for this application")
    57  
    58  	return cmd
    59  }
    60  
    61  func saveApplication(cmd *cobra.Command, options *saveOptions) error {
    62  	// TODO(jacobkiefer): Should we check for an existing application of the same name?
    63  
    64  	initialApp, err := util.ParseJsonFromFileOrStdin(options.applicationFile, true)
    65  	if err != nil {
    66  		return fmt.Errorf("Could not parse supplied application: %v.\n", err)
    67  	}
    68  
    69  	var app map[string]interface{}
    70  	if initialApp != nil && len(initialApp) > 0 {
    71  		app = initialApp
    72  		if len(*options.cloudProviders) != 0 {
    73  			options.Ui.Warn("Overriding application cloud providers with explicit flag values.\n")
    74  			app["cloudProviders"] = strings.Join(*options.cloudProviders, ",")
    75  		}
    76  		if options.applicationName != "" {
    77  			options.Ui.Warn("Overriding application name with explicit flag values.\n")
    78  			app["name"] = options.applicationName
    79  		}
    80  		if options.ownerEmail != "" {
    81  			options.Ui.Warn("Overriding application owner email with explicit flag values.\n")
    82  			app["email"] = options.ownerEmail
    83  		}
    84  		// TODO(jacobkiefer): Add validation for valid cloudProviders and well-formed emails.
    85  		if !(app["cloudProviders"] != nil && app["name"] != "" && app["email"] != "") {
    86  			return errors.New("Required application parameter missing, exiting...")
    87  		}
    88  	} else {
    89  		if options.applicationName == "" || options.ownerEmail == "" || len(*options.cloudProviders) == 0 {
    90  			return errors.New("Required application parameter missing, exiting...")
    91  		}
    92  		app = map[string]interface{}{
    93  			"cloudProviders": strings.Join(*options.cloudProviders, ","),
    94  			"instancePort":   80,
    95  			"name":           options.applicationName,
    96  			"email":          options.ownerEmail,
    97  		}
    98  	}
    99  
   100  	createAppTask := map[string]interface{}{
   101  		"job":         []interface{}{map[string]interface{}{"type": "createApplication", "application": app}},
   102  		"application": app["name"],
   103  		"description": fmt.Sprintf("Create Application: %s", app["name"]),
   104  	}
   105  
   106  	ref, _, err := options.GateClient.TaskControllerApi.TaskUsingPOST1(options.GateClient.Context, createAppTask)
   107  	if err != nil {
   108  		return err
   109  	}
   110  
   111  	err = orca_tasks.WaitForSuccessfulTask(options.GateClient, ref)
   112  	if err != nil {
   113  		return err
   114  	}
   115  
   116  	options.Ui.Success("Application save succeeded")
   117  	return nil
   118  }