diff --git a/docs/content/en/docs/user-guide/configuration-reference.md b/docs/content/en/docs/user-guide/configuration-reference.md index 7eac0aabee..27aa808795 100644 --- a/docs/content/en/docs/user-guide/configuration-reference.md +++ b/docs/content/en/docs/user-guide/configuration-reference.md @@ -319,7 +319,7 @@ spec: | Field | Type | Description | Required | |-|-|-|-| -### CloudRunCanaryRolloutStageOptions +### CloudRunPromoteStageOptions | Field | Type | Description | Required | |-|-|-|-| diff --git a/examples/cloudrun/analysis/.pipe.yaml b/examples/cloudrun/analysis/.pipe.yaml index 923efc0893..51543d0356 100644 --- a/examples/cloudrun/analysis/.pipe.yaml +++ b/examples/cloudrun/analysis/.pipe.yaml @@ -1,26 +1,17 @@ apiVersion: pipecd.dev/v1beta1 kind: CloudRunApp spec: - input: - platform: managed - region: asia-northeast1 pipeline: stages: - # Deploy workloads of the new version. - # But this is still receiving no traffic. - - name: CLOUDRUN_CANARY_ROLLOUT - # Change the traffic routing state where - # the new version will receive the specified percentage of traffic. - # This is known as multi-phase canary strategy. - - name: CLOUDRUN_TRAFFIC_ROUTING + # Promote new version to receive amount of traffic. + - name: CLOUDRUN_PROMOTE with: - canary: 10 + percent: 10 # Optional: We can also add an ANALYSIS stage to verify the new version. # If this stage finds any not good metrics of the new version, # a rollback process to the previous version will be executed. - name: ANALYSIS - # Change the traffic routing state where - # the new version will receive 100% of the traffic. - - name: CLOUDRUN_TRAFFIC_ROUTING + # Promote new version to receive all traffic. + - name: CLOUDRUN_PROMOTE with: - canary: 100 + percent: 100 \ No newline at end of file diff --git a/examples/cloudrun/canary/.pipe.yaml b/examples/cloudrun/canary/.pipe.yaml index ec39528669..9ec124187d 100644 --- a/examples/cloudrun/canary/.pipe.yaml +++ b/examples/cloudrun/canary/.pipe.yaml @@ -2,22 +2,23 @@ apiVersion: pipecd.dev/v1beta1 kind: CloudRunApp spec: - input: - platform: managed - region: asia-northeast1 pipeline: stages: - # Deploy workloads of the new version. - # But this is still receiving no traffic. - - name: CLOUDRUN_CANARY_ROLLOUT - # Change the traffic routing state where - # the new version will receive the specified percentage of traffic. - # This is known as multi-phase canary strategy. - - name: CLOUDRUN_TRAFFIC_ROUTING + # Promote new version to receive amount of traffic. + - name: CLOUDRUN_PROMOTE with: - canary: 10 - # Change the traffic routing state where - # the new version will receive 100% of the traffic. - - name: CLOUDRUN_TRAFFIC_ROUTING + percent: 10 + - name: WAIT with: - canary: 100 + duration: 30s + # Promote new version to receive amount of traffic. + - name: CLOUDRUN_PROMOTE + with: + percent: 50 + - name: WAIT + with: + duration: 30s + # Promote new version to receive all traffic. + - name: CLOUDRUN_PROMOTE + with: + percent: 100 diff --git a/examples/cloudrun/simple/.pipe.yaml b/examples/cloudrun/simple/.pipe.yaml index e50edbda1d..9992e10509 100644 --- a/examples/cloudrun/simple/.pipe.yaml +++ b/examples/cloudrun/simple/.pipe.yaml @@ -2,6 +2,3 @@ apiVersion: pipecd.dev/v1beta1 kind: CloudRunApp spec: - input: - platform: managed - region: asia-northeast1 diff --git a/pkg/app/piped/cloudprovider/cloudrun/BUILD.bazel b/pkg/app/piped/cloudprovider/cloudrun/BUILD.bazel index 11d4e1b60a..1714919dd3 100644 --- a/pkg/app/piped/cloudprovider/cloudrun/BUILD.bazel +++ b/pkg/app/piped/cloudprovider/cloudrun/BUILD.bazel @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", @@ -23,3 +23,10 @@ go_library( "@org_uber_go_zap//:go_default_library", ], ) + +go_test( + name = "go_default_test", + size = "small", + srcs = ["servicemanifest_test.go"], + embed = [":go_default_library"], +) diff --git a/pkg/app/piped/cloudprovider/cloudrun/client.go b/pkg/app/piped/cloudprovider/cloudrun/client.go index 7639fb7ac5..138837881d 100644 --- a/pkg/app/piped/cloudprovider/cloudrun/client.go +++ b/pkg/app/piped/cloudprovider/cloudrun/client.go @@ -77,7 +77,7 @@ func (c *client) Apply(ctx context.Context, sm ServiceManifest) (*Service, error updatedService, err := call.Do() if err != nil { if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { - return nil, fmt.Errorf("service %s was not found (%w)", name, ErrServiceNotFound) + return nil, fmt.Errorf("service %s was not found (%w), the service must be registered from Google CloudRun page", name, ErrServiceNotFound) } return nil, err } diff --git a/pkg/app/piped/cloudprovider/cloudrun/servicemanifest.go b/pkg/app/piped/cloudprovider/cloudrun/servicemanifest.go index e98d2b24f9..61c946d145 100644 --- a/pkg/app/piped/cloudprovider/cloudrun/servicemanifest.go +++ b/pkg/app/piped/cloudprovider/cloudrun/servicemanifest.go @@ -84,8 +84,21 @@ func ParseServiceManifest(data []byte) (ServiceManifest, error) { }, nil } -func DecideRevisionName(m ServiceManifest, commit string) (string, error) { - containers, ok, err := unstructured.NestedSlice(m.u.Object, "spec", "template", "spec", "containers") +func DecideRevisionName(sm ServiceManifest, commit string) (string, error) { + tag, err := FindImageTag(sm) + if err != nil { + return "", err + } + tag = strings.ReplaceAll(tag, ".", "") + + if len(commit) > 7 { + commit = commit[:7] + } + return fmt.Sprintf("%s-%s-%s", sm.Name, tag, commit), nil +} + +func FindImageTag(sm ServiceManifest) (string, error) { + containers, ok, err := unstructured.NestedSlice(sm.u.Object, "spec", "template", "spec", "containers") if err != nil { return "", err } @@ -106,13 +119,8 @@ func DecideRevisionName(m ServiceManifest, commit string) (string, error) { return "", fmt.Errorf("image was missing") } _, tag := parseContainerImage(image) - tag = strings.ReplaceAll(tag, ".", "") - - if len(commit) > 7 { - commit = commit[:7] - } - return fmt.Sprintf("%s-%s-%s", m.Name, tag, commit), nil + return tag, nil } func parseContainerImage(image string) (name, tag string) { diff --git a/pkg/app/piped/cloudprovider/cloudrun/servicemanifest_test.go b/pkg/app/piped/cloudprovider/cloudrun/servicemanifest_test.go new file mode 100644 index 0000000000..9933acc992 --- /dev/null +++ b/pkg/app/piped/cloudprovider/cloudrun/servicemanifest_test.go @@ -0,0 +1,15 @@ +// Copyright 2020 The PipeCD Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cloudrun diff --git a/pkg/app/piped/executor/cloudrun/BUILD.bazel b/pkg/app/piped/executor/cloudrun/BUILD.bazel index a2742ea0f1..2051ef6d34 100644 --- a/pkg/app/piped/executor/cloudrun/BUILD.bazel +++ b/pkg/app/piped/executor/cloudrun/BUILD.bazel @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", @@ -12,3 +12,10 @@ go_library( "//pkg/model:go_default_library", ], ) + +go_test( + name = "go_default_test", + size = "small", + srcs = ["cloudrun_test.go"], + embed = [":go_default_library"], +) diff --git a/pkg/app/piped/executor/cloudrun/cloudrun.go b/pkg/app/piped/executor/cloudrun/cloudrun.go index fc5e00dd35..85617c37c1 100644 --- a/pkg/app/piped/executor/cloudrun/cloudrun.go +++ b/pkg/app/piped/executor/cloudrun/cloudrun.go @@ -45,8 +45,7 @@ func Register(r registerer) { } r.Register(model.StageCloudRunSync, f) - r.Register(model.StageCloudRunCanaryRollout, f) - r.Register(model.StageCloudRunTrafficRouting, f) + r.Register(model.StageCloudRunPromote, f) r.RegisterRollback(model.ApplicationKind_CLOUDRUN, f) } @@ -81,11 +80,8 @@ func (e *Executor) Execute(sig executor.StopSignal) model.StageStatus { case model.StageCloudRunSync: status = e.ensureSync(ctx) - case model.StageCloudRunCanaryRollout: - status = e.ensureCanaryRollout(ctx) - - case model.StageCloudRunTrafficRouting: - status = e.ensureTrafficRouting(ctx) + case model.StageCloudRunPromote: + status = e.ensurePromote(ctx) case model.StageRollback: status = e.ensureRollback(ctx) @@ -99,18 +95,11 @@ func (e *Executor) Execute(sig executor.StopSignal) model.StageStatus { } func (e *Executor) ensureSync(ctx context.Context) model.StageStatus { - var ( - commit = e.Deployment.Trigger.Commit.Hash - appDir = filepath.Join(e.RepoDir, e.Deployment.GitPath.Path) - ) - - e.LogPersister.Infof("Loading service manifest at the triggered commit %s", commit) - sm, err := provider.LoadServiceManifest(appDir, e.config.Input.ServiceManifestFile) - if err != nil { - e.LogPersister.Errorf("Failed to load service manifest file (%v)", err) + commit := e.Deployment.Trigger.Commit.Hash + sm, ok := e.loadServiceManifest() + if !ok { return model.StageStatus_STAGE_FAILURE } - e.LogPersister.Info("Successfully loaded the service manifest") e.LogPersister.Info("Generate a service manifest that configures all traffic to the revision specified at the triggered commit") revision, err := provider.DecideRevisionName(sm, commit) @@ -145,14 +134,156 @@ func (e *Executor) ensureSync(ctx context.Context) model.StageStatus { return model.StageStatus_STAGE_SUCCESS } -func (e *Executor) ensureCanaryRollout(ctx context.Context) model.StageStatus { - return model.StageStatus_STAGE_SUCCESS -} +func (e *Executor) ensurePromote(ctx context.Context) model.StageStatus { + options := e.StageConfig.CloudRunPromoteStageOptions + if options == nil { + e.LogPersister.Errorf("Malformed configuration for stage %s", e.Stage.Name) + return model.StageStatus_STAGE_FAILURE + } + + // Determine the last deployed revision name. + lastDeployedCommit := e.Deployment.RunningCommitHash + if lastDeployedCommit == "" { + e.LogPersister.Errorf("Unable to determine the last deployed commit") + } + + lastDeployedServiceManifest, ok := e.loadLastDeployedServiceManifest() + if !ok { + return model.StageStatus_STAGE_FAILURE + } + + lastDeployedRevisionName, err := provider.DecideRevisionName(lastDeployedServiceManifest, lastDeployedCommit) + if err != nil { + e.LogPersister.Errorf("Unable to decide the last deployed revision name for the commit %s (%v)", lastDeployedCommit, err) + return model.StageStatus_STAGE_FAILURE + } + + // Load triggered service manifest to apply. + commit := e.Deployment.Trigger.Commit.Hash + sm, ok := e.loadServiceManifest() + if !ok { + return model.StageStatus_STAGE_FAILURE + } -func (e *Executor) ensureTrafficRouting(ctx context.Context) model.StageStatus { + e.LogPersister.Infof("Generating a service manifest that configures traffic as: %d%% to new version, %d%% to old version", options.Percent, 100-options.Percent) + revisionName, err := provider.DecideRevisionName(sm, commit) + if err != nil { + e.LogPersister.Errorf("Unable to decide revision name for the commit %s (%v)", commit, err) + return model.StageStatus_STAGE_FAILURE + } + + if err := sm.SetRevision(revisionName); err != nil { + e.LogPersister.Errorf("Unable to set revision name to service manifest (%v)", err) + return model.StageStatus_STAGE_FAILURE + } + + revisions := []provider.RevisionTraffic{ + { + RevisionName: revisionName, + Percent: options.Percent, + }, + { + RevisionName: lastDeployedRevisionName, + Percent: 100 - options.Percent, + }, + } + if err := sm.UpdateTraffic(revisions); err != nil { + e.LogPersister.Errorf("Unable to configure traffic (%v)", err) + return model.StageStatus_STAGE_FAILURE + } + e.LogPersister.Info("Successfully generated the appropriate service manifest") + + e.LogPersister.Info("Start applying the service manifest") + client, err := provider.DefaultRegistry().Client(ctx, e.cloudProviderName, e.cloudProviderConfig, e.Logger) + if err != nil { + e.LogPersister.Errorf("Unable to create ClourRun client for the provider (%v)", err) + return model.StageStatus_STAGE_FAILURE + } + if _, err := client.Apply(ctx, sm); err != nil { + e.LogPersister.Errorf("Failed to apply the service manifest (%v)", err) + return model.StageStatus_STAGE_FAILURE + } + e.LogPersister.Info("Successfully applied the service manifest") + + // TODO: Wait to ensure the traffic was fully configured. return model.StageStatus_STAGE_SUCCESS } func (e *Executor) ensureRollback(ctx context.Context) model.StageStatus { + commit := e.Deployment.RunningCommitHash + if commit == "" { + e.LogPersister.Errorf("Unable to determine the last deployed commit to rollback. It seems this is the first deployment.") + return model.StageStatus_STAGE_FAILURE + } + + sm, ok := e.loadLastDeployedServiceManifest() + if !ok { + return model.StageStatus_STAGE_FAILURE + } + + e.LogPersister.Info("Generate a service manifest that configures all traffic to the last deployed revision") + revision, err := provider.DecideRevisionName(sm, commit) + if err != nil { + e.LogPersister.Errorf("Unable to decide revision name for the commit %s (%v)", commit, err) + return model.StageStatus_STAGE_FAILURE + } + + if err := sm.SetRevision(revision); err != nil { + e.LogPersister.Errorf("Unable to set revision name to service manifest (%v)", err) + return model.StageStatus_STAGE_FAILURE + } + + if err := sm.UpdateAllTraffic(revision); err != nil { + e.LogPersister.Errorf("Unable to configure all traffic to revision %s (%v)", revision, err) + return model.StageStatus_STAGE_FAILURE + } + e.LogPersister.Info("Successfully generated the appropriate service manifest") + + e.LogPersister.Info("Start applying the service manifest") + client, err := provider.DefaultRegistry().Client(ctx, e.cloudProviderName, e.cloudProviderConfig, e.Logger) + if err != nil { + e.LogPersister.Errorf("Unable to create ClourRun client for the provider (%v)", err) + return model.StageStatus_STAGE_FAILURE + } + if _, err := client.Apply(ctx, sm); err != nil { + e.LogPersister.Errorf("Failed to apply the service manifest (%v)", err) + return model.StageStatus_STAGE_FAILURE + } + e.LogPersister.Info("Successfully applied the service manifest") + return model.StageStatus_STAGE_SUCCESS } + +func (e *Executor) loadServiceManifest() (provider.ServiceManifest, bool) { + var ( + commit = e.Deployment.Trigger.Commit.Hash + appDir = filepath.Join(e.RepoDir, e.Deployment.GitPath.Path) + ) + + e.LogPersister.Infof("Loading service manifest at the triggered commit %s", commit) + sm, err := provider.LoadServiceManifest(appDir, e.config.Input.ServiceManifestFile) + if err != nil { + e.LogPersister.Errorf("Failed to load service manifest file (%v)", err) + return provider.ServiceManifest{}, false + } + e.LogPersister.Info("Successfully loaded the service manifest") + + return sm, true +} + +func (e *Executor) loadLastDeployedServiceManifest() (provider.ServiceManifest, bool) { + var ( + commit = e.Deployment.RunningCommitHash + appDir = filepath.Join(e.RunningRepoDir, e.Deployment.GitPath.Path) + ) + + e.LogPersister.Infof("Loading service manifest at the last deployed commit %s", commit) + sm, err := provider.LoadServiceManifest(appDir, e.config.Input.ServiceManifestFile) + if err != nil { + e.LogPersister.Errorf("Failed to load service manifest file (%v)", err) + return provider.ServiceManifest{}, false + } + e.LogPersister.Info("Successfully loaded the service manifest") + + return sm, true +} diff --git a/pkg/app/piped/executor/cloudrun/cloudrun_test.go b/pkg/app/piped/executor/cloudrun/cloudrun_test.go new file mode 100644 index 0000000000..9933acc992 --- /dev/null +++ b/pkg/app/piped/executor/cloudrun/cloudrun_test.go @@ -0,0 +1,15 @@ +// Copyright 2020 The PipeCD Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cloudrun diff --git a/pkg/app/piped/planner/cloudrun/BUILD.bazel b/pkg/app/piped/planner/cloudrun/BUILD.bazel index a130d729bc..495e341725 100644 --- a/pkg/app/piped/planner/cloudrun/BUILD.bazel +++ b/pkg/app/piped/planner/cloudrun/BUILD.bazel @@ -9,8 +9,10 @@ go_library( importpath = "github.com/pipe-cd/pipe/pkg/app/piped/planner/cloudrun", visibility = ["//visibility:public"], deps = [ + "//pkg/app/piped/cloudprovider/cloudrun:go_default_library", "//pkg/app/piped/planner:go_default_library", "//pkg/config:go_default_library", "//pkg/model:go_default_library", + "@org_uber_go_zap//:go_default_library", ], ) diff --git a/pkg/app/piped/planner/cloudrun/cloudrun.go b/pkg/app/piped/planner/cloudrun/cloudrun.go index c2ec532181..8c8c0c478b 100644 --- a/pkg/app/piped/planner/cloudrun/cloudrun.go +++ b/pkg/app/piped/planner/cloudrun/cloudrun.go @@ -19,6 +19,9 @@ import ( "fmt" "time" + "go.uber.org/zap" + + provider "github.com/pipe-cd/pipe/pkg/app/piped/cloudprovider/cloudrun" "github.com/pipe-cd/pipe/pkg/app/piped/planner" "github.com/pipe-cd/pipe/pkg/model" ) @@ -37,7 +40,6 @@ func Register(r registerer) { } // Plan decides which pipeline should be used for the given input. -// TODO: Implement the logic for CloudRun planner. func (p *Planner) Plan(ctx context.Context, in planner.Input) (out planner.Output, err error) { cfg := in.DeploymentConfig.CloudRunDeploymentSpec if cfg == nil { @@ -45,14 +47,48 @@ func (p *Planner) Plan(ctx context.Context, in planner.Input) (out planner.Outpu return } + // Determine application version from the manifest. + if version, e := p.determineVersion(in.AppDir, cfg.Input.ServiceManifestFile); e == nil { + out.Version = version + } else { + out.Version = "unknown" + in.Logger.Warn("unable to determine target version", zap.Error(e)) + } + + // This is the first time to deploy this application or it was unable to retrieve that value. + // We just do the quick sync. + if in.MostRecentSuccessfulCommitHash == "" { + out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, time.Now()) + out.Summary = "Quick sync by deploying the new version and configuring all traffic to it because it seems this is the first deployment" + return + } + + // When no pipeline was configured, do the quick sync. if cfg.Pipeline == nil || len(cfg.Pipeline.Stages) == 0 { out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, time.Now()) - out.Summary = "Quick sync by just deploying the new version and configuring all traffic to it because no pipeline was configured" + out.Summary = "Quick sync by deploying the new version and configuring all traffic to it because no pipeline was configured" return } - out.Stages = buildProgressivePipeline(cfg.Pipeline, cfg.Input.AutoRollback, time.Now()) - out.Summary = "Sync progressively because ... (unimplemented)" + // Load service manifest at the last deployed commit to decide running version. + if err = in.Repo.Checkout(ctx, in.MostRecentSuccessfulCommitHash); err == nil { + if lastVersion, e := p.determineVersion(in.AppDir, cfg.Input.ServiceManifestFile); e == nil { + out.Stages = buildProgressivePipeline(cfg.Pipeline, cfg.Input.AutoRollback, time.Now()) + out.Summary = fmt.Sprintf("Sync progressively because of updating image from %s to %s", lastVersion, out.Version) + return + } + } + out.Stages = buildProgressivePipeline(cfg.Pipeline, cfg.Input.AutoRollback, time.Now()) + out.Summary = "Sync progressively with the specified pipeline" return } + +func (p *Planner) determineVersion(appDir, serviceManifestFile string) (string, error) { + sm, err := provider.LoadServiceManifest(appDir, serviceManifestFile) + if err != nil { + return "", err + } + + return provider.FindImageTag(sm) +} diff --git a/pkg/config/deployment.go b/pkg/config/deployment.go index 7f453defae..ae5ae48ebf 100644 --- a/pkg/config/deployment.go +++ b/pkg/config/deployment.go @@ -64,9 +64,8 @@ type PipelineStage struct { TerraformPlanStageOptions *TerraformPlanStageOptions TerraformApplyStageOptions *TerraformApplyStageOptions - CloudRunSyncStageOptions *CloudRunSyncStageOptions - CloudRunCanaryRolloutStageOptions *CloudRunCanaryRolloutStageOptions - CloudRunTrafficRoutingStageOptions *CloudRunTrafficRoutingStageOptions + CloudRunSyncStageOptions *CloudRunSyncStageOptions + CloudRunPromoteStageOptions *CloudRunPromoteStageOptions LambdaSyncStageOptions *LambdaSyncStageOptions LambdaCanaryRolloutStageOptions *LambdaCanaryRolloutStageOptions @@ -160,15 +159,10 @@ func (s *PipelineStage) UnmarshalJSON(data []byte) error { if len(gs.With) > 0 { err = json.Unmarshal(gs.With, s.CloudRunSyncStageOptions) } - case model.StageCloudRunCanaryRollout: - s.CloudRunCanaryRolloutStageOptions = &CloudRunCanaryRolloutStageOptions{} + case model.StageCloudRunPromote: + s.CloudRunPromoteStageOptions = &CloudRunPromoteStageOptions{} if len(gs.With) > 0 { - err = json.Unmarshal(gs.With, s.CloudRunCanaryRolloutStageOptions) - } - case model.StageCloudRunTrafficRouting: - s.CloudRunTrafficRoutingStageOptions = &CloudRunTrafficRoutingStageOptions{} - if len(gs.With) > 0 { - err = json.Unmarshal(gs.With, s.CloudRunTrafficRoutingStageOptions) + err = json.Unmarshal(gs.With, s.CloudRunPromoteStageOptions) } case model.StageLambdaSync: diff --git a/pkg/config/deployment_cloudrun.go b/pkg/config/deployment_cloudrun.go index fea16d21c8..ccbcedf1ca 100644 --- a/pkg/config/deployment_cloudrun.go +++ b/pkg/config/deployment_cloudrun.go @@ -43,10 +43,6 @@ type CloudRunDeploymentInput struct { // The name of service manifest file placing in application configuration directory. // Default is service.yaml ServiceManifestFile string `json:"serviceManifestFile"` - // The target platform for deploying service. This must be one of: "managed", "gke", "kubernetes". - Platform string `json:"platform"` - // The region in which the service will be deployed. - Region string `json:"region"` // Automatically reverts all changes from all stages when one of them failed. // Default is true. AutoRollback bool `json:"autoRollback"` @@ -56,29 +52,7 @@ type CloudRunDeploymentInput struct { type CloudRunSyncStageOptions struct { } -// CloudRunCanaryRolloutStageOptions contains all configurable values for a CLOUDRUN_CANARY_ROLLOUT stage. -type CloudRunCanaryRolloutStageOptions struct { -} - -// CloudRunTrafficRoutingStageOptions contains all configurable values for a CLOUDRUN_TRAFFIC_ROUTING stage. -type CloudRunTrafficRoutingStageOptions struct { - // Which variant should receive all traffic. - // This can be either "primary" or "canary". - All string `json:"all"` - // The percentage of traffic should be routed to PRIMARY variant. - Primary int `json:"primary"` - // The percentage of traffic should be routed to CANARY variant. - Canary int `json:"canary"` -} - -func (opts CloudRunTrafficRoutingStageOptions) Percentages() (primary, canary int) { - switch opts.All { - case "primary": - primary = 100 - return - case "canary": - canary = 100 - return - } - return opts.Primary, opts.Canary +// CloudRunPromoteStageOptions contains all configurable values for a CLOUDRUN_PROMOTE stage. +type CloudRunPromoteStageOptions struct { + Percent int `json:"percent"` } diff --git a/pkg/config/deployment_lambda.go b/pkg/config/deployment_lambda.go index d431515af9..d0b58c0b26 100644 --- a/pkg/config/deployment_lambda.go +++ b/pkg/config/deployment_lambda.go @@ -52,7 +52,7 @@ type LambdaDeploymentInput struct { type LambdaSyncStageOptions struct { } -// LambdaCanaryRolloutStageOptions contains all configurable values for a CLOUDRUN_CANARY_ROLLOUT stage. +// LambdaCanaryRolloutStageOptions contains all configurable values for a CLOUDRUN_PROMOTE stage. type LambdaCanaryRolloutStageOptions struct { } diff --git a/pkg/config/testdata/application/cloudrun-app-bluegreen.yaml b/pkg/config/testdata/application/cloudrun-app-bluegreen.yaml index 00e1725f3b..462390ffaf 100644 --- a/pkg/config/testdata/application/cloudrun-app-bluegreen.yaml +++ b/pkg/config/testdata/application/cloudrun-app-bluegreen.yaml @@ -8,7 +8,7 @@ spec: stages: # Deploy workloads of the new version. # But this is still receiving no traffic. - - name: CLOUDRUN_CANARY_ROLLOUT + - name: CLOUDRUN_PROMOTE # Change the traffic routing state where # the new version will receive 100% of the traffic as soon as possible. # This is known as blue-green strategy. diff --git a/pkg/config/testdata/application/cloudrun-app-canary.yaml b/pkg/config/testdata/application/cloudrun-app-canary.yaml index 5f6a37b9a7..399d019cd8 100644 --- a/pkg/config/testdata/application/cloudrun-app-canary.yaml +++ b/pkg/config/testdata/application/cloudrun-app-canary.yaml @@ -8,7 +8,7 @@ spec: stages: # Deploy workloads of the new version. # But this is still receiving no traffic. - - name: CLOUDRUN_CANARY_ROLLOUT + - name: CLOUDRUN_PROMOTE # Change the traffic routing state where # the new version will receive the specified percentage of traffic. # This is known as multi-phase canary strategy. diff --git a/pkg/model/stage.go b/pkg/model/stage.go index a5bfe895ed..d6f23e3ce9 100644 --- a/pkg/model/stage.go +++ b/pkg/model/stage.go @@ -62,12 +62,8 @@ const ( // StageCloudRunSync does quick sync by rolling out the new version // and switching all traffic to it. StageCloudRunSync Stage = "CLOUDRUN_SYNC" - // StageCloudRunCanaryRollout represents the state where - // the workloads of the new version has been rolled out. - StageCloudRunCanaryRollout Stage = "CLOUDRUN_CANARY_ROLLOUT" - // StageCloudRunTrafficRouting represents the state where the traffic to application - // should be splitted as the specified percentage to previous version and new version. - StageCloudRunTrafficRouting Stage = "CLOUDRUN_TRAFFIC_ROUTING" + // StageCloudRunPromote promotes the new version to receive amount of traffic. + StageCloudRunPromote Stage = "CLOUDRUN_PROMOTE" // StageLambdaSync does quick sync by rolling out the new version // and switching all traffic to it.