Sfoglia il codice sorgente

update deployment cli to accept updates

Alexander Belanger 4 anni fa
parent
commit
5b34db937f
5 ha cambiato i file con 117 aggiunte e 31 eliminazioni
  1. 44 0
      cli/cmd/api/deploy.go
  2. 38 15
      cli/cmd/deploy.go
  3. 29 13
      cli/cmd/deploy/deploy.go
  4. 2 2
      cli/values-test.yaml
  5. 4 1
      server/api/release_handler.go

+ 44 - 0
cli/cmd/api/deploy.go

@@ -178,3 +178,47 @@ func (c *Client) DeployTemplate(
 
 	return nil
 }
+
+type UpgradeReleaseRequest struct {
+	Values    string `json:"values"`
+	Namespace string `json:"namespace"`
+}
+
+func (c *Client) UpgradeRelease(
+	ctx context.Context,
+	projID, clusterID uint,
+	name string,
+	upgradeReq *UpgradeReleaseRequest,
+) error {
+	data, err := json.Marshal(upgradeReq)
+
+	if err != nil {
+		return err
+	}
+
+	req, err := http.NewRequest(
+		"POST",
+		fmt.Sprintf("%s/projects/%d/releases/%s/upgrade?"+url.Values{
+			"namespace":  []string{upgradeReq.Namespace},
+			"cluster_id": []string{fmt.Sprintf("%d", clusterID)},
+			"storage":    []string{"secret"},
+		}.Encode(), c.BaseURL, projID, name),
+		strings.NewReader(string(data)),
+	)
+
+	if err != nil {
+		return err
+	}
+
+	req = req.WithContext(ctx)
+
+	if httpErr, err := c.sendRequest(req, nil, true); httpErr != nil || err != nil {
+		if httpErr != nil {
+			return fmt.Errorf("code %d, errors %v", httpErr.Code, httpErr.Errors)
+		}
+
+		return err
+	}
+
+	return nil
+}

+ 38 - 15
cli/cmd/deploy.go

@@ -32,6 +32,11 @@ local directory ~/path-to-dir with the tag "testing":
 
   %s
 
+To add new configuration or update existing configuration, you can pass a values.yaml file in via the 
+--values flag. For example;
+
+  %s
+
 If your application is set up to use a Dockerfile by default, you can use a buildpack via the flag 
 "--method pack". Conversely, if your application is set up to use a buildpack by default, you can 
 use a Dockerfile by passing the flag "--method docker". You can specify the relative path to a Dockerfile 
@@ -54,6 +59,7 @@ as documented above. For example:
 		color.New(color.FgBlue, color.Bold).Sprintf("Help for \"porter deploy\":"),
 		color.New(color.FgGreen, color.Bold).Sprintf("porter deploy --app example-app"),
 		color.New(color.FgGreen, color.Bold).Sprintf("porter deploy --app remote-git-app --local --path ~/path-to-dir --tag testing"),
+		color.New(color.FgGreen, color.Bold).Sprintf("porter deploy --app remote-git-app --values my-values.yaml"),
 		color.New(color.FgGreen, color.Bold).Sprintf("porter deploy --app remote-git-app --method docker --dockerfile ./docker/prod.Dockerfile"),
 		color.New(color.FgGreen, color.Bold).Sprintf("porter deploy --app local-app"),
 		color.New(color.FgGreen, color.Bold).Sprintf("porter deploy --app local-app --method docker --dockerfile ~/porter-test/prod.Dockerfile"),
@@ -169,27 +175,29 @@ linked it via "porter connect".
 }
 
 var deployCallWebhookCmd = &cobra.Command{
-	Use:   "call-webhook",
-	Short: "Calls the webhook for an application specified by the --app flag.",
+	Use:   "update-config",
+	Short: "Updates the configuration for an application specified by the --app flag.",
 	Long: fmt.Sprintf(`
 %s 
 
-Calls the webhook for an application specified by the --app flag. This webhook will 
-trigger a new deployment for the application, with the new image set. For example:
+Updates the configuration for an application specified by the --app flag, using the configuration
+given by the --values flag. This will trigger a new deployment for the application with 
+new configuration set. Note that this will merge your existing configuration with configuration
+specified in the --values file. For example:
 
   %s
 
-This command will by default call the webhook with image tag "latest," but you can 
-specify a different tag with the --tag flag:
+You can update the configuration with only a new tag with the --tag flag, which will only update
+the image that the application uses if no --values file is specified:
 
   %s
 `,
-		color.New(color.FgBlue, color.Bold).Sprintf("Help for \"porter deploy call-webhook\":"),
-		color.New(color.FgGreen, color.Bold).Sprintf("porter deploy call-webhook --app example-app"),
+		color.New(color.FgBlue, color.Bold).Sprintf("Help for \"porter deploy update-config\":"),
+		color.New(color.FgGreen, color.Bold).Sprintf("porter deploy call-webhook --app example-app --values my-values.yaml"),
 		color.New(color.FgGreen, color.Bold).Sprintf("porter deploy call-webhook --app example-app --tag custom-tag"),
 	),
 	Run: func(cmd *cobra.Command, args []string) {
-		err := checkLoginAndRun(args, deployCallWebhook)
+		err := checkLoginAndRun(args, deployUpgrade)
 
 		if err != nil {
 			os.Exit(1)
@@ -227,7 +235,7 @@ func init() {
 	deployCmd.PersistentFlags().BoolVar(
 		&local,
 		"local",
-		false,
+		true,
 		"Whether local context should be used for build",
 	)
 
@@ -247,6 +255,14 @@ func init() {
 		"the specified tag to use, if not \"latest\"",
 	)
 
+	deployCmd.PersistentFlags().StringVarP(
+		&values,
+		"values",
+		"v",
+		"",
+		"Filepath to a values.yaml file",
+	)
+
 	deployCmd.PersistentFlags().StringVar(
 		&dockerfile,
 		"dockerfile",
@@ -296,7 +312,7 @@ func deployFull(resp *api.AuthCheckResponse, client *api.Client, args []string)
 		return err
 	}
 
-	err = deployCallWebhookWithAgent(deployAgent)
+	err = deployUpgradeWithAgent(deployAgent)
 
 	if err != nil {
 		return err
@@ -349,14 +365,14 @@ func deployPush(resp *api.AuthCheckResponse, client *api.Client, args []string)
 	return deployPushWithAgent(deployAgent)
 }
 
-func deployCallWebhook(resp *api.AuthCheckResponse, client *api.Client, args []string) error {
+func deployUpgrade(resp *api.AuthCheckResponse, client *api.Client, args []string) error {
 	deployAgent, err := deployGetAgent(client)
 
 	if err != nil {
 		return err
 	}
 
-	return deployCallWebhookWithAgent(deployAgent)
+	return deployUpgradeWithAgent(deployAgent)
 }
 
 // HELPER METHODS
@@ -409,11 +425,18 @@ func deployPushWithAgent(deployAgent *deploy.DeployAgent) error {
 	return deployAgent.Push()
 }
 
-func deployCallWebhookWithAgent(deployAgent *deploy.DeployAgent) error {
+func deployUpgradeWithAgent(deployAgent *deploy.DeployAgent) error {
 	// push the deployment
 	color.New(color.FgGreen).Println("Calling webhook for", app)
 
-	err := deployAgent.CallWebhook()
+	// read the values if necessary
+	valuesObj, err := readValuesFile()
+
+	if err != nil {
+		return err
+	}
+
+	err = deployAgent.UpdateImageAndValues(valuesObj)
 
 	if err != nil {
 		return err

+ 29 - 13
cli/cmd/deploy/deploy.go

@@ -2,6 +2,7 @@ package deploy
 
 import (
 	"context"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"io/ioutil"
@@ -12,6 +13,7 @@ import (
 	"github.com/porter-dev/porter/cli/cmd/api"
 	"github.com/porter-dev/porter/cli/cmd/docker"
 	"github.com/porter-dev/porter/cli/cmd/github"
+	"github.com/porter-dev/porter/internal/templater/utils"
 	"k8s.io/client-go/util/homedir"
 )
 
@@ -215,7 +217,9 @@ func (d *DeployAgent) Build() error {
 	}
 
 	if d.tag == "" {
-		d.tag = "latest"
+		currImageSection := d.release.Config["image"].(map[string]interface{})
+
+		d.tag = currImageSection["tag"].(string)
 	}
 
 	err = d.pullCurrentReleaseImage()
@@ -247,23 +251,31 @@ func (d *DeployAgent) Push() error {
 	return d.agent.PushImage(fmt.Sprintf("%s:%s", d.imageRepo, d.tag))
 }
 
-func (d *DeployAgent) CallWebhook() error {
-	releaseExt, err := d.client.GetReleaseWebhook(
-		context.Background(),
-		d.opts.ProjectID,
-		d.opts.ClusterID,
-		d.release.Name,
-		d.release.Namespace,
-	)
+func (d *DeployAgent) UpdateImageAndValues(overrideValues map[string]interface{}) error {
+	mergedValues := utils.CoalesceValues(d.release.Config, overrideValues)
+
+	// overwrite the tag based on a new image
+	currImageSection := mergedValues["image"].(map[string]interface{})
+
+	if d.tag != "" && currImageSection["tag"] != d.tag {
+		currImageSection["tag"] = d.tag
+	}
+
+	bytes, err := json.Marshal(mergedValues)
 
 	if err != nil {
 		return err
 	}
 
-	return d.client.DeployWithWebhook(
+	return d.client.UpgradeRelease(
 		context.Background(),
-		releaseExt.WebhookToken,
-		d.tag,
+		d.opts.ProjectID,
+		d.opts.ClusterID,
+		d.release.Name,
+		&api.UpgradeReleaseRequest{
+			Values:    string(bytes),
+			Namespace: d.release.Namespace,
+		},
 	)
 }
 
@@ -298,7 +310,11 @@ func GetEnvFromConfig(config map[string]interface{}) (map[string]string, error)
 }
 
 func (d *DeployAgent) getReleaseImage() (string, error) {
-	// pull the currently deployed image to use cache, if possible
+	if d.release.ImageRepoURI != "" {
+		return d.release.ImageRepoURI, nil
+	}
+
+	// get the image from the conig
 	imageConfig, err := getNestedMap(d.release.Config, "image")
 
 	if err != nil {

+ 2 - 2
cli/values-test.yaml

@@ -1,2 +1,2 @@
-ingress:
-  enabled: false
+container:
+  port: 8080

+ 4 - 1
server/api/release_handler.go

@@ -82,6 +82,7 @@ type PorterRelease struct {
 	HasMetrics      bool                            `json:"has_metrics"`
 	LatestVersion   string                          `json:"latest_version"`
 	GitActionConfig *models.GitActionConfigExternal `json:"git_action_config"`
+	ImageRepoURI    string                          `json:"image_repo_uri"`
 }
 
 var porterApplications = map[string]string{"web": "", "job": "", "worker": ""}
@@ -163,7 +164,7 @@ func (app *App) HandleGetRelease(w http.ResponseWriter, r *http.Request) {
 		HelmRelease:   release,
 	}
 
-	res := &PorterRelease{release, nil, false, "", nil}
+	res := &PorterRelease{release, nil, false, "", nil, ""}
 
 	for _, file := range release.Chart.Files {
 		if strings.Contains(file.Name, "form.yaml") {
@@ -218,6 +219,8 @@ func (app *App) HandleGetRelease(w http.ResponseWriter, r *http.Request) {
 	modelRelease, err := app.Repo.Release.ReadRelease(form.Cluster.ID, release.Name, release.Namespace)
 
 	if modelRelease != nil {
+		res.ImageRepoURI = modelRelease.ImageRepoURI
+
 		gitAction := modelRelease.GitActionConfig
 
 		if gitAction.ID != 0 {