diff --git a/go.mod b/go.mod index 370f7a03c..f21f0d56d 100644 --- a/go.mod +++ b/go.mod @@ -9,15 +9,15 @@ require ( github.com/fatih/color v1.18.0 github.com/google/uuid v1.6.0 github.com/mattn/go-isatty v0.0.20 - github.com/nexus-rpc/sdk-go v0.2.0 + github.com/nexus-rpc/sdk-go v0.3.0 github.com/olekukonko/tablewriter v0.0.5 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.6 github.com/stretchr/testify v1.10.0 - github.com/temporalio/ui-server/v2 v2.35.0 - go.temporal.io/api v1.44.1 - go.temporal.io/sdk v1.32.1 - go.temporal.io/server v1.27.0-rc.0 + github.com/temporalio/ui-server/v2 v2.36.0 + go.temporal.io/api v1.45.0 + go.temporal.io/sdk v1.33.0 + go.temporal.io/server v1.27.0-127.0.0.20250226023855-64a2e8cb4a17 google.golang.org/grpc v1.70.0 google.golang.org/protobuf v1.36.5 gopkg.in/yaml.v3 v3.0.1 @@ -53,7 +53,7 @@ require ( github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-jose/go-jose/v4 v4.0.4 // indirect + github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-sql-driver/mysql v1.9.0 // indirect diff --git a/go.sum b/go.sum index 53168840f..4fb819a10 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,8 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu github.com/go-faker/faker/v4 v4.6.0 h1:6aOPzNptRiDwD14HuAnEtlTa+D1IfFuEHO8+vEFwjTs= github.com/go-faker/faker/v4 v4.6.0/go.mod h1:ZmrHuVtTTm2Em9e0Du6CJ9CADaLEzGXW62z1YqFH0m0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= -github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -242,8 +242,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/nexus-rpc/sdk-go v0.2.0 h1:NKMkfTTQDEkbnP46/oB7cV7Ml25Wk+9w7lOyeYJQLAc= -github.com/nexus-rpc/sdk-go v0.2.0/go.mod h1:TpfkM2Cw0Rlk9drGkoiSMpFqflKTiQLWUNyKJjF8mKQ= +github.com/nexus-rpc/sdk-go v0.3.0 h1:Y3B0kLYbMhd4C2u00kcYajvmOrfozEtTV/nHSnV57jA= +github.com/nexus-rpc/sdk-go v0.3.0/go.mod h1:TpfkM2Cw0Rlk9drGkoiSMpFqflKTiQLWUNyKJjF8mKQ= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= @@ -319,8 +319,8 @@ github.com/temporalio/sqlparser v0.0.0-20231115171017-f4060bcfa6cb/go.mod h1:143 github.com/temporalio/tchannel-go v1.22.1-0.20220818200552-1be8d8cffa5b/go.mod h1:c+V9Z/ZgkzAdyGvHrvC5AsXgN+M9Qwey04cBdKYzV7U= github.com/temporalio/tchannel-go v1.22.1-0.20240528171429-1db37fdea938 h1:sEJGhmDo+0FaPWM6f0v8Tjia0H5pR6/Baj6+kS78B+M= github.com/temporalio/tchannel-go v1.22.1-0.20240528171429-1db37fdea938/go.mod h1:ezRQRwu9KQXy8Wuuv1aaFFxoCNz5CeNbVOOkh3xctbY= -github.com/temporalio/ui-server/v2 v2.35.0 h1:9msJGma2dEiwI+nI3iU7TfpnmgRCQv+R8Yd8JWqurC4= -github.com/temporalio/ui-server/v2 v2.35.0/go.mod h1:suM9z9+8208achw/6ZWd3/mF4k9x567mIBAg10S5lf4= +github.com/temporalio/ui-server/v2 v2.36.0 h1:U9ZKCEfnW7a7I0axhOPaOIDeeF+i09K3v1OHeiXCSkQ= +github.com/temporalio/ui-server/v2 v2.36.0/go.mod h1:1v+2UefCW9DSTskDbmrXcyhR+r+m2XdvDU1IwBAwDmE= github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg= github.com/twmb/murmur3 v1.1.8/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/uber-common/bark v1.0.0/go.mod h1:g0ZuPcD7XiExKHynr93Q742G/sbrdVQkghrqLGOoFuY= @@ -371,12 +371,12 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= -go.temporal.io/api v1.44.1 h1:sb5Hq08AB0WtYvfLJMiWmHzxjqs2b+6Jmzg4c8IOeng= -go.temporal.io/api v1.44.1/go.mod h1:1WwYUMo6lao8yl0371xWUm13paHExN5ATYT/B7QtFis= -go.temporal.io/sdk v1.32.1 h1:slA8prhdFr4lxpsTcRusWVitD/cGjELfKUh0mBj73SU= -go.temporal.io/sdk v1.32.1/go.mod h1:8U8H7rF9u4Hyb4Ry9yiEls5716DHPNvVITPNkgWUwE8= -go.temporal.io/server v1.27.0-rc.0 h1:dxa9m8Mzr7peHT8Ypv6su6gHP/IOw1G0pGMOT10giK8= -go.temporal.io/server v1.27.0-rc.0/go.mod h1:ddxnsbsXvdZ/oRvjLHaL45NJUGMOPW+3RLkhpq9TOAs= +go.temporal.io/api v1.45.0 h1:2FZ3eUoOYjavBaQi3/V93MBl99Nq1ifFRjrRwT3MeC8= +go.temporal.io/api v1.45.0/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM= +go.temporal.io/sdk v1.33.0 h1:T91UzeRdlHTiMGgpygsItOH9+VSkg+M/mG85PqNjdog= +go.temporal.io/sdk v1.33.0/go.mod h1:WwCmJZLy7zabz3ar5NRAQEygsdP8tgR9sDjISSHuWZw= +go.temporal.io/server v1.27.0-127.0.0.20250226023855-64a2e8cb4a17 h1:HGNLkRp18RIdYQIi9H3UwE1S+t8kVUuoNG7R6YMfhVM= +go.temporal.io/server v1.27.0-127.0.0.20250226023855-64a2e8cb4a17/go.mod h1:srmZuuEFsechItNt7XSU2yrlUIf7cJjaN7M7/qtyP+g= go.temporal.io/version v0.3.0 h1:dMrei9l9NyHt8nG6EB8vAwDLLTwx2SvRyucCSumAiig= go.temporal.io/version v0.3.0/go.mod h1:UA9S8/1LaKYae6TyD9NaPMJTZb911JcbqghI2CBSP78= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index 12a724051..66fe02dc1 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -131,6 +131,24 @@ func (v *WorkflowReferenceOptions) buildFlags(cctx *CommandContext, f *pflag.Fla f.StringVarP(&v.RunId, "run-id", "r", "", "Run ID.") } +type DeploymentNameOptions struct { + Name string +} + +func (v *DeploymentNameOptions) buildFlags(cctx *CommandContext, f *pflag.FlagSet) { + f.StringVarP(&v.Name, "name", "d", "", "Name for a Worker Deployment. Required.") + _ = cobra.MarkFlagRequired(f, "name") +} + +type DeploymentVersionOptions struct { + Version string +} + +func (v *DeploymentVersionOptions) buildFlags(cctx *CommandContext, f *pflag.FlagSet) { + f.StringVarP(&v.Version, "version", "v", "", "Fully-qualified name for a Worker Deployment Version. Use the format `YourDeploymentName.YourBuildID`. Required.") + _ = cobra.MarkFlagRequired(f, "version") +} + type DeploymentReferenceOptions struct { SeriesName string BuildId string @@ -2246,9 +2264,9 @@ func NewTemporalTaskQueueVersioningCommand(cctx *CommandContext, parent *Tempora s.Command.Use = "versioning" s.Command.Short = "Manage Task Queue Build ID handling (Experimental)" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nProvides commands to add, list, remove, or replace Worker Build ID assignment\nand redirect rules associated with Task Queues:\n\n\x1b[1mtemporal task-queue versioning [subcommands] [options] \\\n --task-queue YourTaskQueue\x1b[0m\n\nTask Queues support the following versioning rules and policies:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID." + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+\n\nProvides commands to add, list, remove, or replace Worker Build ID assignment\nand redirect rules associated with Task Queues:\n\n\x1b[1mtemporal task-queue versioning [subcommands] [options] \\\n --task-queue YourTaskQueue\x1b[0m\n\nTask Queues support the following versioning rules and policies:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID." } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nProvides commands to add, list, remove, or replace Worker Build ID assignment\nand redirect rules associated with Task Queues:\n\n```\ntemporal task-queue versioning [subcommands] [options] \\\n --task-queue YourTaskQueue\n```\n\nTask Queues support the following versioning rules and policies:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID." + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+\n\nProvides commands to add, list, remove, or replace Worker Build ID assignment\nand redirect rules associated with Task Queues:\n\n```\ntemporal task-queue versioning [subcommands] [options] \\\n --task-queue YourTaskQueue\n```\n\nTask Queues support the following versioning rules and policies:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID." } s.Command.Args = cobra.NoArgs s.Command.AddCommand(&NewTemporalTaskQueueVersioningAddRedirectRuleCommand(cctx, &s).Command) @@ -2279,9 +2297,9 @@ func NewTemporalTaskQueueVersioningAddRedirectRuleCommand(cctx *CommandContext, s.Command.Use = "add-redirect-rule [flags]" s.Command.Short = "Add Task Queue redirect rules (Experimental)" if hasHighlighting { - s.Command.Long = "Add a new redirect rule for a given Task Queue. You may add at most one\nredirect rule for each distinct source build ID:\n\n\x1b[1mtemporal task-queue versioning add-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourSourceBuildID\" \\\n --target-build-id \"YourTargetBuildID\"\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Add a new redirect rule for a given Task Queue. You may add at most one\nredirect rule for each distinct source build ID:\n\n\x1b[1mtemporal task-queue versioning add-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourSourceBuildID\" \\\n --target-build-id \"YourTargetBuildID\"\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Add a new redirect rule for a given Task Queue. You may add at most one\nredirect rule for each distinct source build ID:\n\n```\ntemporal task-queue versioning add-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourSourceBuildID\" \\\n --target-build-id \"YourTargetBuildID\"\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Add a new redirect rule for a given Task Queue. You may add at most one\nredirect rule for each distinct source build ID:\n\n```\ntemporal task-queue versioning add-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourSourceBuildID\" \\\n --target-build-id \"YourTargetBuildID\"\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.SourceBuildId, "source-build-id", "", "Source build ID. Required.") @@ -2312,9 +2330,9 @@ func NewTemporalTaskQueueVersioningCommitBuildIdCommand(cctx *CommandContext, pa s.Command.Use = "commit-build-id [flags]" s.Command.Short = "Complete Build ID rollout (Experimental)" if hasHighlighting { - s.Command.Long = "Complete a Build ID's rollout and clean up unnecessary rules that might have\nbeen created during a gradual rollout:\n\n\x1b[1mtemporal task-queue versioning commit-build-id \\\n --task-queue YourTaskQueue\n --build-id \"YourBuildId\"\x1b[0m\n\nThis command automatically applies the following atomic changes:\n\n- Adds an unconditional assignment rule for the target Build ID at the\n end of the list.\n- Removes all previously added assignment rules to the given target\n Build ID.\n- Removes any unconditional assignment rules for other Build IDs.\n\nRejects requests when there have been no recent pollers for this Build ID.\nThis prevents committing invalid Build IDs. Use the \x1b[1m--force\x1b[0m option to\noverride this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Complete a Build ID's rollout and clean up unnecessary rules that might have\nbeen created during a gradual rollout:\n\n\x1b[1mtemporal task-queue versioning commit-build-id \\\n --task-queue YourTaskQueue\n --build-id \"YourBuildId\"\x1b[0m\n\nThis command automatically applies the following atomic changes:\n\n- Adds an unconditional assignment rule for the target Build ID at the\n end of the list.\n- Removes all previously added assignment rules to the given target\n Build ID.\n- Removes any unconditional assignment rules for other Build IDs.\n\nRejects requests when there have been no recent pollers for this Build ID.\nThis prevents committing invalid Build IDs. Use the \x1b[1m--force\x1b[0m option to\noverride this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Complete a Build ID's rollout and clean up unnecessary rules that might have\nbeen created during a gradual rollout:\n\n```\ntemporal task-queue versioning commit-build-id \\\n --task-queue YourTaskQueue\n --build-id \"YourBuildId\"\n```\n\nThis command automatically applies the following atomic changes:\n\n- Adds an unconditional assignment rule for the target Build ID at the\n end of the list.\n- Removes all previously added assignment rules to the given target\n Build ID.\n- Removes any unconditional assignment rules for other Build IDs.\n\nRejects requests when there have been no recent pollers for this Build ID.\nThis prevents committing invalid Build IDs. Use the `--force` option to\noverride this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Complete a Build ID's rollout and clean up unnecessary rules that might have\nbeen created during a gradual rollout:\n\n```\ntemporal task-queue versioning commit-build-id \\\n --task-queue YourTaskQueue\n --build-id \"YourBuildId\"\n```\n\nThis command automatically applies the following atomic changes:\n\n- Adds an unconditional assignment rule for the target Build ID at the\n end of the list.\n- Removes all previously added assignment rules to the given target\n Build ID.\n- Removes any unconditional assignment rules for other Build IDs.\n\nRejects requests when there have been no recent pollers for this Build ID.\nThis prevents committing invalid Build IDs. Use the `--force` option to\noverride this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.BuildId, "build-id", "", "Target build ID. Required.") @@ -2344,9 +2362,9 @@ func NewTemporalTaskQueueVersioningDeleteAssignmentRuleCommand(cctx *CommandCont s.Command.Use = "delete-assignment-rule [flags]" s.Command.Short = "Removes a Task Queue assignment rule (Experimental)" if hasHighlighting { - s.Command.Long = "Deletes a rule identified by its index in the Task Queue's list of assignment\nrules.\n\n\x1b[1mtemporal task-queue versioning delete-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index YourIntegerRuleIndex\x1b[0m\n\nBy default, the Task Queue must retain one unconditional rule, such as \"no\nhint filter\" or \"percentage\". Otherwise, the delete operation is rejected.\nUse the \x1b[1m--force\x1b[0m option to override this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Deletes a rule identified by its index in the Task Queue's list of assignment\nrules.\n\n\x1b[1mtemporal task-queue versioning delete-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index YourIntegerRuleIndex\x1b[0m\n\nBy default, the Task Queue must retain one unconditional rule, such as \"no\nhint filter\" or \"percentage\". Otherwise, the delete operation is rejected.\nUse the \x1b[1m--force\x1b[0m option to override this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Deletes a rule identified by its index in the Task Queue's list of assignment\nrules.\n\n```\ntemporal task-queue versioning delete-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index YourIntegerRuleIndex\n```\n\nBy default, the Task Queue must retain one unconditional rule, such as \"no\nhint filter\" or \"percentage\". Otherwise, the delete operation is rejected.\nUse the `--force` option to override this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Deletes a rule identified by its index in the Task Queue's list of assignment\nrules.\n\n```\ntemporal task-queue versioning delete-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index YourIntegerRuleIndex\n```\n\nBy default, the Task Queue must retain one unconditional rule, such as \"no\nhint filter\" or \"percentage\". Otherwise, the delete operation is rejected.\nUse the `--force` option to override this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().IntVarP(&s.RuleIndex, "rule-index", "i", 0, "Position of the assignment rule to be replaced. Requests for invalid indices will fail. Required.") @@ -2375,9 +2393,9 @@ func NewTemporalTaskQueueVersioningDeleteRedirectRuleCommand(cctx *CommandContex s.Command.Use = "delete-redirect-rule [flags]" s.Command.Short = "Removes Build-ID routing rule (Experimental)" if hasHighlighting { - s.Command.Long = "Deletes the routing rule for the given source Build ID.\n\n\x1b[1mtemporal task-queue versioning delete-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourBuildId\"\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Deletes the routing rule for the given source Build ID.\n\n\x1b[1mtemporal task-queue versioning delete-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourBuildId\"\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Deletes the routing rule for the given source Build ID.\n\n```\ntemporal task-queue versioning delete-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourBuildId\"\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Deletes the routing rule for the given source Build ID.\n\n```\ntemporal task-queue versioning delete-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourBuildId\"\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.SourceBuildId, "source-build-id", "", "Source Build ID. Required.") @@ -2403,9 +2421,9 @@ func NewTemporalTaskQueueVersioningGetRulesCommand(cctx *CommandContext, parent s.Command.Use = "get-rules [flags]" s.Command.Short = "Fetch Worker Build ID assignments and redirect rules (Experimental)" if hasHighlighting { - s.Command.Long = "Retrieve all the Worker Build ID assignments and redirect rules associated\nwith a Task Queue:\n\n\x1b[1mtemporal task-queue versioning get-rules \\\n --task-queue YourTaskQueue\x1b[0m\n\nTask Queues support the following versioning rules:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Retrieve all the Worker Build ID assignments and redirect rules associated\nwith a Task Queue:\n\n\x1b[1mtemporal task-queue versioning get-rules \\\n --task-queue YourTaskQueue\x1b[0m\n\nTask Queues support the following versioning rules:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID.\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Retrieve all the Worker Build ID assignments and redirect rules associated\nwith a Task Queue:\n\n```\ntemporal task-queue versioning get-rules \\\n --task-queue YourTaskQueue\n```\n\nTask Queues support the following versioning rules:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Retrieve all the Worker Build ID assignments and redirect rules associated\nwith a Task Queue:\n\n```\ntemporal task-queue versioning get-rules \\\n --task-queue YourTaskQueue\n```\n\nTask Queues support the following versioning rules:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID.\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Run = func(c *cobra.Command, args []string) { @@ -2432,9 +2450,9 @@ func NewTemporalTaskQueueVersioningInsertAssignmentRuleCommand(cctx *CommandCont s.Command.Use = "insert-assignment-rule [flags]" s.Command.Short = "Add an assignment rule at a index (Experimental)" if hasHighlighting { - s.Command.Long = "Inserts a new assignment rule for this Task Queue. Rules are evaluated in\norder, starting from index 0. The first applicable rule is applied, and the\nrest ignored:\n\n\x1b[1mtemporal task-queue versioning insert-assignment-rule \\\n --task-queue YourTaskQueue \\\n --build-id \"YourBuildId\"\x1b[0m\n\nIf you do not specify a \x1b[1m--rule-index\x1b[0m, this command inserts at index 0.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Inserts a new assignment rule for this Task Queue. Rules are evaluated in\norder, starting from index 0. The first applicable rule is applied, and the\nrest ignored:\n\n\x1b[1mtemporal task-queue versioning insert-assignment-rule \\\n --task-queue YourTaskQueue \\\n --build-id \"YourBuildId\"\x1b[0m\n\nIf you do not specify a \x1b[1m--rule-index\x1b[0m, this command inserts at index 0.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Inserts a new assignment rule for this Task Queue. Rules are evaluated in\norder, starting from index 0. The first applicable rule is applied, and the\nrest ignored:\n\n```\ntemporal task-queue versioning insert-assignment-rule \\\n --task-queue YourTaskQueue \\\n --build-id \"YourBuildId\"\n```\n\nIf you do not specify a `--rule-index`, this command inserts at index 0.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Inserts a new assignment rule for this Task Queue. Rules are evaluated in\norder, starting from index 0. The first applicable rule is applied, and the\nrest ignored:\n\n```\ntemporal task-queue versioning insert-assignment-rule \\\n --task-queue YourTaskQueue \\\n --build-id \"YourBuildId\"\n```\n\nIf you do not specify a `--rule-index`, this command inserts at index 0.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.BuildId, "build-id", "", "Target Build ID. Required.") @@ -2467,9 +2485,9 @@ func NewTemporalTaskQueueVersioningReplaceAssignmentRuleCommand(cctx *CommandCon s.Command.Use = "replace-assignment-rule [flags]" s.Command.Short = "Update assignment rule at index (Experimental)" if hasHighlighting { - s.Command.Long = "Change an assignment rule for this Task Queue. By default, this enforces one\nunconditional rule (no hint filter or percentage). Otherwise, the operation\nwill be rejected. Set \x1b[1mforce\x1b[0m to true to bypass this validation.\n\n\x1b[1mtemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\"\x1b[0m\n\nTo assign multiple assignment rules to a single Build ID, use\n'insert-assignment-rule'.\n\nTo update the percent:\n\n\x1b[1mtemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\" \\\n --percentage AnIntegerPercent\x1b[0m\n\nPercent may vary between 0 and 100 (default).\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Change an assignment rule for this Task Queue. By default, this enforces one\nunconditional rule (no hint filter or percentage). Otherwise, the operation\nwill be rejected. Set \x1b[1mforce\x1b[0m to true to bypass this validation.\n\n\x1b[1mtemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\"\x1b[0m\n\nTo assign multiple assignment rules to a single Build ID, use\n'insert-assignment-rule'.\n\nTo update the percent:\n\n\x1b[1mtemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\" \\\n --percentage AnIntegerPercent\x1b[0m\n\nPercent may vary between 0 and 100 (default).\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Change an assignment rule for this Task Queue. By default, this enforces one\nunconditional rule (no hint filter or percentage). Otherwise, the operation\nwill be rejected. Set `force` to true to bypass this validation.\n\n```\ntemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\"\n```\n\nTo assign multiple assignment rules to a single Build ID, use\n'insert-assignment-rule'.\n\nTo update the percent:\n\n```\ntemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\" \\\n --percentage AnIntegerPercent\n```\n\nPercent may vary between 0 and 100 (default).\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Change an assignment rule for this Task Queue. By default, this enforces one\nunconditional rule (no hint filter or percentage). Otherwise, the operation\nwill be rejected. Set `force` to true to bypass this validation.\n\n```\ntemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\"\n```\n\nTo assign multiple assignment rules to a single Build ID, use\n'insert-assignment-rule'.\n\nTo update the percent:\n\n```\ntemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\" \\\n --percentage AnIntegerPercent\n```\n\nPercent may vary between 0 and 100 (default).\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.BuildId, "build-id", "", "Target Build ID. Required.") @@ -2502,9 +2520,9 @@ func NewTemporalTaskQueueVersioningReplaceRedirectRuleCommand(cctx *CommandConte s.Command.Use = "replace-redirect-rule [flags]" s.Command.Short = "Change the target for a Build ID's redirect (Experimental)" if hasHighlighting { - s.Command.Long = "Updates a Build ID's redirect rule on a Task Queue by replacing its target\nBuild ID:\n\n\x1b[1mtemporal task-queue versioning replace-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id YourSourceBuildId \\\n --target-build-id YourNewTargetBuildId\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Updates a Build ID's redirect rule on a Task Queue by replacing its target\nBuild ID:\n\n\x1b[1mtemporal task-queue versioning replace-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id YourSourceBuildId \\\n --target-build-id YourNewTargetBuildId\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Updates a Build ID's redirect rule on a Task Queue by replacing its target\nBuild ID:\n\n```\ntemporal task-queue versioning replace-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id YourSourceBuildId \\\n --target-build-id YourNewTargetBuildId\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Updates a Build ID's redirect rule on a Task Queue by replacing its target\nBuild ID:\n\n```\ntemporal task-queue versioning replace-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id YourSourceBuildId \\\n --target-build-id YourNewTargetBuildId\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.SourceBuildId, "source-build-id", "", "Source Build ID. Required.") @@ -2551,25 +2569,88 @@ func NewTemporalWorkerDeploymentCommand(cctx *CommandContext, parent *TemporalWo var s TemporalWorkerDeploymentCommand s.Parent = parent s.Command.Use = "deployment" - s.Command.Short = "Describe, list, and operate on Worker Deployments" + s.Command.Short = "Describe, list, and operate on Worker Deployments and Versions" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands perform operations on Worker Deployments:\n\n\x1b[1mtemporal worker deployment [command] [options]\x1b[0m\n\nFor example:\n\n\x1b[1mtemporal worker deployment list\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands perform operations on Worker Deployments:\n\n\x1b[1mtemporal worker deployment [command] [options]\x1b[0m\n\nFor example:\n\n\x1b[1mtemporal worker deployment list\x1b[0m\n\nLists the Deployments in the client's namespace.\n\nArguments can be Worker Deployment Versions associated with\na Deployment, using a fully qualified Version identifier that\nconcatenates the Deployment Name and the Build ID with the\nreserved separator \".\".\n\nFor example:\n\n\x1b[1mtemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\x1b[0m\n\nSets the current Deployment Version for a given Deployment." } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands perform operations on Worker Deployments:\n\n```\ntemporal worker deployment [command] [options]\n```\n\nFor example:\n\n```\ntemporal worker deployment list\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands perform operations on Worker Deployments:\n\n```\ntemporal worker deployment [command] [options]\n```\n\nFor example:\n\n```\ntemporal worker deployment list\n```\n\nLists the Deployments in the client's namespace.\n\nArguments can be Worker Deployment Versions associated with\na Deployment, using a fully qualified Version identifier that\nconcatenates the Deployment Name and the Build ID with the\nreserved separator \".\".\n\nFor example:\n\n```\ntemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\n```\n\nSets the current Deployment Version for a given Deployment." } s.Command.Args = cobra.NoArgs + s.Command.AddCommand(&NewTemporalWorkerDeploymentDeleteCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentDeleteVersionCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkerDeploymentDescribeCommand(cctx, &s).Command) - s.Command.AddCommand(&NewTemporalWorkerDeploymentGetCurrentCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentDescribeVersionCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkerDeploymentListCommand(cctx, &s).Command) - s.Command.AddCommand(&NewTemporalWorkerDeploymentSetCurrentCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentSetCurrentVersionCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentSetRampingVersionCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentUpdateMetadataVersionCommand(cctx, &s).Command) + return &s +} + +type TemporalWorkerDeploymentDeleteCommand struct { + Parent *TemporalWorkerDeploymentCommand + Command cobra.Command + DeploymentNameOptions + Identity string +} + +func NewTemporalWorkerDeploymentDeleteCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDeleteCommand { + var s TemporalWorkerDeploymentDeleteCommand + s.Parent = parent + s.Command.DisableFlagsInUseLine = true + s.Command.Use = "delete [flags]" + s.Command.Short = "Delete a Worker Deployment" + if hasHighlighting { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment given its Deployment Name.\nA Deployment can only be deleted if it has no Version in it.\n\n\x1b[1mtemporal worker deployment delete [options]\x1b[0m\n\nFor example, setting the user identity that removed the deployment:\n\n\x1b[1mtemporal worker deployment delete \\\n --name YourDeploymentName \\\n --identity YourIdentity\x1b[0m" + } else { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment given its Deployment Name.\nA Deployment can only be deleted if it has no Version in it.\n\n```\ntemporal worker deployment delete [options]\n```\n\nFor example, setting the user identity that removed the deployment:\n\n```\ntemporal worker deployment delete \\\n --name YourDeploymentName \\\n --identity YourIdentity\n\n```" + } + s.Command.Args = cobra.NoArgs + s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") + s.DeploymentNameOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Run = func(c *cobra.Command, args []string) { + if err := s.run(cctx, args); err != nil { + cctx.Options.Fail(err) + } + } + return &s +} + +type TemporalWorkerDeploymentDeleteVersionCommand struct { + Parent *TemporalWorkerDeploymentCommand + Command cobra.Command + DeploymentVersionOptions + Identity string + SkipDrainage bool +} + +func NewTemporalWorkerDeploymentDeleteVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDeleteVersionCommand { + var s TemporalWorkerDeploymentDeleteVersionCommand + s.Parent = parent + s.Command.DisableFlagsInUseLine = true + s.Command.Use = "delete-version [flags]" + s.Command.Short = "Delete a Worker Deployment Version" + if hasHighlighting { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n\x1b[1m--skip-drainage\x1b[0m.\n \n\x1b[1mtemporal worker deployment delete-version [options]\x1b[0m\n\nFor example, skipping the drainage restriction:\n\n\x1b[1mtemporal worker deployment delete-version \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \x1b[0m" + } else { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n`--skip-drainage`.\n \n```\ntemporal worker deployment delete-version [options]\n```\n\nFor example, skipping the drainage restriction:\n\n```\ntemporal worker deployment delete-version \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \n```" + } + s.Command.Args = cobra.NoArgs + s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") + s.Command.Flags().BoolVar(&s.SkipDrainage, "skip-drainage", false, "Ignore the deletion requirement of not draining.") + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Run = func(c *cobra.Command, args []string) { + if err := s.run(cctx, args); err != nil { + cctx.Options.Fail(err) + } + } return &s } type TemporalWorkerDeploymentDescribeCommand struct { Parent *TemporalWorkerDeploymentCommand Command cobra.Command - DeploymentReferenceOptions - ReportReachability bool + DeploymentNameOptions } func NewTemporalWorkerDeploymentDescribeCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDescribeCommand { @@ -2579,13 +2660,12 @@ func NewTemporalWorkerDeploymentDescribeCommand(cctx *CommandContext, parent *Te s.Command.Use = "describe [flags]" s.Command.Short = "Show properties of a Worker Deployment" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment, such as whether it is\ncurrent, the non-empty list of its task queues, custom metadata if\npresent, and reachability status when requested.\n\n\x1b[1mtemporal worker deployment describe [options]\x1b[0m\n\nFor example, to also include reachability information:\n\n\x1b[1mtemporal worker deployment describe \\\n --series-name YourDeploymentSeriesName \\\n --build-id YourDeploymentBuildId \\\n --report-reachability\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribe properties of a Worker Deployment, such as the versions\nassociated with it, routing information of new or existing tasks\nexecuted by this deployment, or its creation time.\n\n\x1b[1mtemporal worker deployment describe [options]\x1b[0m\n\nFor example, to describe a deployment \x1b[1mYourDeploymentName\x1b[0m in the default\nnamespace:\n\n\x1b[1mtemporal worker deployment describe \\\n --name YourDeploymentName\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment, such as whether it is\ncurrent, the non-empty list of its task queues, custom metadata if\npresent, and reachability status when requested.\n\n```\ntemporal worker deployment describe [options]\n```\n\nFor example, to also include reachability information:\n\n```\ntemporal worker deployment describe \\\n --series-name YourDeploymentSeriesName \\\n --build-id YourDeploymentBuildId \\\n --report-reachability\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribe properties of a Worker Deployment, such as the versions\nassociated with it, routing information of new or existing tasks\nexecuted by this deployment, or its creation time.\n\n```\ntemporal worker deployment describe [options]\n```\n\nFor example, to describe a deployment `YourDeploymentName` in the default\nnamespace:\n\n```\ntemporal worker deployment describe \\\n --name YourDeploymentName\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().BoolVar(&s.ReportReachability, "report-reachability", false, "Include reachability information of a Worker Deployment.") - s.DeploymentReferenceOptions.buildFlags(cctx, s.Command.Flags()) + s.DeploymentNameOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -2594,26 +2674,25 @@ func NewTemporalWorkerDeploymentDescribeCommand(cctx *CommandContext, parent *Te return &s } -type TemporalWorkerDeploymentGetCurrentCommand struct { - Parent *TemporalWorkerDeploymentCommand - Command cobra.Command - SeriesName string +type TemporalWorkerDeploymentDescribeVersionCommand struct { + Parent *TemporalWorkerDeploymentCommand + Command cobra.Command + DeploymentVersionOptions } -func NewTemporalWorkerDeploymentGetCurrentCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentGetCurrentCommand { - var s TemporalWorkerDeploymentGetCurrentCommand +func NewTemporalWorkerDeploymentDescribeVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDescribeVersionCommand { + var s TemporalWorkerDeploymentDescribeVersionCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true - s.Command.Use = "get-current [flags]" - s.Command.Short = "Show the current Worker Deployment" + s.Command.Use = "describe-version [flags]" + s.Command.Short = "Show properties of a Worker Deployment Version" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nGets the current Worker Deployment for a Deployment Series Name.\nWhen a Deployment is current, Workers of that Deployment will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment Series.\n\n\x1b[1mtemporal worker deployment get-current [options]\x1b[0m\n\nFor example:\n\n\x1b[1mtemporal worker deployment get-current \\\n --series-name YourDeploymentSeriesName\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribe properties of a Worker Deployment Version, such as the task \nqueues polled by workers in this Deployment Version, or drainage\ninformation required to safely decommission workers, or user-provided\nmetadata, or its creation/modification time.\n\n\x1b[1mtemporal worker deployment describe-version [options]\x1b[0m\n\nFor example, to describe a deployment version in a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with Build ID \x1b[1mYourBuildID\x1b[0m, and in the default\nnamespace:\n\n\x1b[1mtemporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nGets the current Worker Deployment for a Deployment Series Name.\nWhen a Deployment is current, Workers of that Deployment will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment Series.\n\n```\ntemporal worker deployment get-current [options]\n```\n\nFor example:\n\n```\ntemporal worker deployment get-current \\\n --series-name YourDeploymentSeriesName\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribe properties of a Worker Deployment Version, such as the task \nqueues polled by workers in this Deployment Version, or drainage\ninformation required to safely decommission workers, or user-provided\nmetadata, or its creation/modification time.\n\n```\ntemporal worker deployment describe-version [options]\n```\n\nFor example, to describe a deployment version in a deployment\n`YourDeploymentName`, with Build ID `YourBuildID`, and in the default\nnamespace:\n\n```\ntemporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVar(&s.SeriesName, "series-name", "", "Series Name for the current Worker Deployment. Required.") - _ = cobra.MarkFlagRequired(s.Command.Flags(), "series-name") + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -2623,9 +2702,8 @@ func NewTemporalWorkerDeploymentGetCurrentCommand(cctx *CommandContext, parent * } type TemporalWorkerDeploymentListCommand struct { - Parent *TemporalWorkerDeploymentCommand - Command cobra.Command - SeriesName string + Parent *TemporalWorkerDeploymentCommand + Command cobra.Command } func NewTemporalWorkerDeploymentListCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentListCommand { @@ -2635,12 +2713,11 @@ func NewTemporalWorkerDeploymentListCommand(cctx *CommandContext, parent *Tempor s.Command.Use = "list [flags]" s.Command.Short = "Enumerate Worker Deployments in the client's namespace" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace, optionally\nfiltering them by Deployment Series Name.\n\n\n\x1b[1mtemporal worker deployment list [options]\x1b[0m\n\nFor example, adding an optional filter:\n\n\x1b[1mtemporal worker deployment list \\\n --series-name YourDeploymentSeriesName\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace.\n\n\x1b[1mtemporal worker deployment list [options]\x1b[0m\n\nFor example, listing Deployments in YourDeploymentNamespace:\n\n\x1b[1mtemporal worker deployment list \\\n --namespace YourDeploymentNamespace\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace, optionally\nfiltering them by Deployment Series Name.\n\n\n```\ntemporal worker deployment list [options]\n```\n\nFor example, adding an optional filter:\n\n```\ntemporal worker deployment list \\\n --series-name YourDeploymentSeriesName\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace.\n\n```\ntemporal worker deployment list [options]\n```\n\nFor example, listing Deployments in YourDeploymentNamespace:\n\n```\ntemporal worker deployment list \\\n --namespace YourDeploymentNamespace\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVar(&s.SeriesName, "series-name", "", "Series Name to filter Worker Deployments.") s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -2649,27 +2726,103 @@ func NewTemporalWorkerDeploymentListCommand(cctx *CommandContext, parent *Tempor return &s } -type TemporalWorkerDeploymentSetCurrentCommand struct { +type TemporalWorkerDeploymentSetCurrentVersionCommand struct { + Parent *TemporalWorkerDeploymentCommand + Command cobra.Command + DeploymentVersionOptions + DeploymentName string + Identity string + IgnoreMissingTaskQueues bool + Yes bool +} + +func NewTemporalWorkerDeploymentSetCurrentVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentSetCurrentVersionCommand { + var s TemporalWorkerDeploymentSetCurrentVersionCommand + s.Parent = parent + s.Command.DisableFlagsInUseLine = true + s.Command.Use = "set-current-version [flags]" + s.Command.Short = "Make a Worker Deployment Version Current for a Deployment" + if hasHighlighting { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows, and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment set-current-version [options]\x1b[0m\n\nFor example, to set the Current Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, and\nin the default namespace:\n\n\x1b[1mtemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\x1b[0m\n\nThe target of set-current-version can also be \x1b[1m__unversioned__\x1b[0m, which\nmoves tasks to unversioned workers, but in this case we also need to\nspecify the Deployment Name.\n\n\x1b[1mtemporal worker deployment set-current-version \\\n --version __unversioned__ \\\n --deployment-name YourDeploymentName\x1b[0m " + } else { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows, and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment set-current-version [options]\n```\n\nFor example, to set the Current Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, and\nin the default namespace:\n\n```\ntemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\n```\n\nThe target of set-current-version can also be `__unversioned__`, which\nmoves tasks to unversioned workers, but in this case we also need to\nspecify the Deployment Name.\n\n```\ntemporal worker deployment set-current-version \\\n --version __unversioned__ \\\n --deployment-name YourDeploymentName\n``` " + } + s.Command.Args = cobra.NoArgs + s.Command.Flags().StringVar(&s.DeploymentName, "deployment-name", "", "Deployment name. Only needed when `--version` is `__unversioned__` or empty.") + s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") + s.Command.Flags().BoolVar(&s.IgnoreMissingTaskQueues, "ignore-missing-task-queues", false, "Override protection to accidentally remove task queues.") + s.Command.Flags().BoolVarP(&s.Yes, "yes", "y", false, "Don't prompt to confirm set Current Version.") + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Run = func(c *cobra.Command, args []string) { + if err := s.run(cctx, args); err != nil { + cctx.Options.Fail(err) + } + } + return &s +} + +type TemporalWorkerDeploymentSetRampingVersionCommand struct { + Parent *TemporalWorkerDeploymentCommand + Command cobra.Command + DeploymentVersionOptions + DeploymentName string + Percentage float32 + Delete bool + Identity string + IgnoreMissingTaskQueues bool + Yes bool +} + +func NewTemporalWorkerDeploymentSetRampingVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentSetRampingVersionCommand { + var s TemporalWorkerDeploymentSetRampingVersionCommand + s.Parent = parent + s.Command.DisableFlagsInUseLine = true + s.Command.Use = "set-ramping-version [flags]" + s.Command.Short = "Change Version Ramping settings for a Worker Deployment" + if hasHighlighting { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n\x1b[1mYourDeploymentName.YourBuildID\x1b[0m, or set to \"__unversioned__\", a special\nvalue that represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n\x1b[1mset-current-version\x1b[0m instead.\n\nTo remove a Ramping Version use the flag \x1b[1m--delete\x1b[0m.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment set-ramping-version [options]\x1b[0m\n\nFor example, to set the Ramping Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n\x1b[1mtemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\x1b[0m\n\nAnd to remove that ramping:\n \n\x1b[1mtemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID \\\n --delete\x1b[0m " + } else { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n`YourDeploymentName.YourBuildID`, or set to \"__unversioned__\", a special\nvalue that represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n`set-current-version` instead.\n\nTo remove a Ramping Version use the flag `--delete`.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment set-ramping-version [options]\n```\n\nFor example, to set the Ramping Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n```\ntemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\n```\n\nAnd to remove that ramping:\n \n```\ntemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID \\\n --delete\n``` " + } + s.Command.Args = cobra.NoArgs + s.Command.Flags().StringVar(&s.DeploymentName, "deployment-name", "", "Deployment name. Only needed when `--version` is `__unversioned__`.") + s.Command.Flags().Float32Var(&s.Percentage, "percentage", 0, "Percentage of tasks redirected to the Ramping Version. Valid range [0,100].") + s.Command.Flags().BoolVar(&s.Delete, "delete", false, "Delete the Ramping Version.") + s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") + s.Command.Flags().BoolVar(&s.IgnoreMissingTaskQueues, "ignore-missing-task-queues", false, "Override protection to accidentally remove task queues.") + s.Command.Flags().BoolVarP(&s.Yes, "yes", "y", false, "Don't prompt to confirm set Ramping Version.") + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Run = func(c *cobra.Command, args []string) { + if err := s.run(cctx, args); err != nil { + cctx.Options.Fail(err) + } + } + return &s +} + +type TemporalWorkerDeploymentUpdateMetadataVersionCommand struct { Parent *TemporalWorkerDeploymentCommand Command cobra.Command - DeploymentReferenceOptions - Metadata []string + DeploymentVersionOptions + Metadata []string + RemoveEntries []string } -func NewTemporalWorkerDeploymentSetCurrentCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentSetCurrentCommand { - var s TemporalWorkerDeploymentSetCurrentCommand +func NewTemporalWorkerDeploymentUpdateMetadataVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentUpdateMetadataVersionCommand { + var s TemporalWorkerDeploymentUpdateMetadataVersionCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true - s.Command.Use = "set-current [flags]" - s.Command.Short = "Change the current Worker Deployment" + s.Command.Use = "update-metadata-version [flags]" + s.Command.Short = "Change user-provided metadata for a Version" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the current Deployment for a given Deployment Series.\nWhen a Deployment is current, Workers of that Deployment will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment Series.\n\n\x1b[1mtemporal worker deployment set-current [options]\x1b[0m\n\nFor example:\n\n\x1b[1mtemporal worker deployment set-current \\\n --series-name YourDeploymentSeriesName \\\n --build-id YourDeploymentBuildId\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\nUpdate metadata associated with a Worker Deployment Version.\n\nFor example:\n\n\x1b[1m temporal worker deployment update-metadata-version \\\n --version YourDeploymentName.YourBuildID \\\n --metadata bar=1 \\\n --metadata foo=true\x1b[0m\n\nThe current metadata is also returned with \x1b[1mdescribe-version\x1b[0m:\n \n\x1b[1m temporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID \\\x1b[0m " } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the current Deployment for a given Deployment Series.\nWhen a Deployment is current, Workers of that Deployment will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment Series.\n\n```\ntemporal worker deployment set-current [options]\n```\n\nFor example:\n\n```\ntemporal worker deployment set-current \\\n --series-name YourDeploymentSeriesName \\\n --build-id YourDeploymentBuildId\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\nUpdate metadata associated with a Worker Deployment Version.\n\nFor example:\n\n```\n temporal worker deployment update-metadata-version \\\n --version YourDeploymentName.YourBuildID \\\n --metadata bar=1 \\\n --metadata foo=true\n```\n\nThe current metadata is also returned with `describe-version`:\n \n```\n temporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID \\\n``` " } s.Command.Args = cobra.NoArgs s.Command.Flags().StringArrayVar(&s.Metadata, "metadata", nil, "Set deployment metadata using `KEY=\"VALUE\"` pairs. Keys must be identifiers, and values must be JSON values. For example: 'YourKey={\"your\": \"value\"}'. Can be passed multiple times.") - s.DeploymentReferenceOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Flags().StringArrayVar(&s.RemoveEntries, "remove-entries", nil, "Keys of entries to be deleted from metadata. Can be passed multiple times.") + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -3416,9 +3569,8 @@ type TemporalWorkflowUpdateOptionsCommand struct { Parent *TemporalWorkflowCommand Command cobra.Command SingleWorkflowOrBatchOptions - VersioningOverrideBehavior StringEnum - VersioningOverrideSeriesName string - VersioningOverrideBuildId string + VersioningOverrideBehavior StringEnum + VersioningOverridePinnedVersion string } func NewTemporalWorkflowUpdateOptionsCommand(cctx *CommandContext, parent *TemporalWorkflowCommand) *TemporalWorkflowUpdateOptionsCommand { @@ -3428,16 +3580,15 @@ func NewTemporalWorkflowUpdateOptionsCommand(cctx *CommandContext, parent *Tempo s.Command.Use = "update-options [flags]" s.Command.Short = "Change Workflow Execution Options" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worflow update-options is experimental. Workflow Execution |\n| properties are subject to change. |\n+---------------------------------------------------------------------+\n\nModify properties of Workflow Executions:\n\n\x1b[1mtemporal workflow update-options [options]\x1b[0m\n\nIt can override the Worker Deployment configuration of a\nWorkflow Execution, which controls Worker Versioning.\n\nFor example, to force Workers in the current Deployment execute the\nnext Workflow Task change behavior to \x1b[1mauto_upgrade\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior auto_upgrade\x1b[0m\n\nor to pin the workflow execution to a Worker Deployment, set behavior\nto \x1b[1mpinned\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior pinned \\\n --versioning-override-series-name YourDeploymentSeriesName \\\n --versioning-override-build-id YourDeploymentBuildId\x1b[0m\n\nTo remove any previous overrides, set the behavior to\n\x1b[1munspecified\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior unspecified\x1b[0m\n\nTo see the current override use \x1b[1mtemporal workflow describe\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worflow update-options is experimental. Workflow Execution |\n| properties are subject to change. |\n+---------------------------------------------------------------------+\n\nModify properties of Workflow Executions:\n\n\x1b[1mtemporal workflow update-options [options]\x1b[0m\n\nIt can override the Worker Deployment configuration of a\nWorkflow Execution, which controls Worker Versioning.\n\nFor example, to force Workers in the current Deployment execute the\nnext Workflow Task change behavior to \x1b[1mauto_upgrade\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior auto_upgrade\x1b[0m\n\nor to pin the workflow execution to a Worker Deployment, set behavior\nto \x1b[1mpinned\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior pinned \\\n --versioning-override-pinned-version \\\n YourDeploymentSeriesName.YourDeploymentBuildId\x1b[0m\n\nTo remove any previous overrides, set the behavior to\n\x1b[1munspecified\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior unspecified\x1b[0m\n\nTo see the current override use \x1b[1mtemporal workflow describe\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worflow update-options is experimental. Workflow Execution |\n| properties are subject to change. |\n+---------------------------------------------------------------------+\n\nModify properties of Workflow Executions:\n\n```\ntemporal workflow update-options [options]\n```\n\nIt can override the Worker Deployment configuration of a\nWorkflow Execution, which controls Worker Versioning.\n\nFor example, to force Workers in the current Deployment execute the\nnext Workflow Task change behavior to `auto_upgrade`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior auto_upgrade\n```\n\nor to pin the workflow execution to a Worker Deployment, set behavior\nto `pinned`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior pinned \\\n --versioning-override-series-name YourDeploymentSeriesName \\\n --versioning-override-build-id YourDeploymentBuildId\n```\n\nTo remove any previous overrides, set the behavior to\n`unspecified`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior unspecified\n```\n\nTo see the current override use `temporal workflow describe`" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worflow update-options is experimental. Workflow Execution |\n| properties are subject to change. |\n+---------------------------------------------------------------------+\n\nModify properties of Workflow Executions:\n\n```\ntemporal workflow update-options [options]\n```\n\nIt can override the Worker Deployment configuration of a\nWorkflow Execution, which controls Worker Versioning.\n\nFor example, to force Workers in the current Deployment execute the\nnext Workflow Task change behavior to `auto_upgrade`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior auto_upgrade\n```\n\nor to pin the workflow execution to a Worker Deployment, set behavior\nto `pinned`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior pinned \\\n --versioning-override-pinned-version \\\n YourDeploymentSeriesName.YourDeploymentBuildId\n```\n\nTo remove any previous overrides, set the behavior to\n`unspecified`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior unspecified\n```\n\nTo see the current override use `temporal workflow describe`" } s.Command.Args = cobra.NoArgs s.VersioningOverrideBehavior = NewStringEnum([]string{"unspecified", "pinned", "auto_upgrade"}, "") s.Command.Flags().Var(&s.VersioningOverrideBehavior, "versioning-override-behavior", "Override the versioning behavior of a Workflow. Accepted values: unspecified, pinned, auto_upgrade. Required.") _ = cobra.MarkFlagRequired(s.Command.Flags(), "versioning-override-behavior") - s.Command.Flags().StringVar(&s.VersioningOverrideSeriesName, "versioning-override-series-name", "", "Override Series Name for a Worker Deployment (Only for pinned).") - s.Command.Flags().StringVar(&s.VersioningOverrideBuildId, "versioning-override-build-id", "", "Override Build ID for a Worker Deployment (Only for pinned).") + s.Command.Flags().StringVar(&s.VersioningOverridePinnedVersion, "versioning-override-pinned-version", "", "Override Pinned Version for a Worker Deployment (Only for pinned).") s.SingleWorkflowOrBatchOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { diff --git a/temporalcli/commands.worker.deployment.go b/temporalcli/commands.worker.deployment.go index 45a44ec04..9e09ac343 100644 --- a/temporalcli/commands.worker.deployment.go +++ b/temporalcli/commands.worker.deployment.go @@ -2,6 +2,7 @@ package temporalcli import ( "fmt" + "strings" "time" "github.com/fatih/color" @@ -10,80 +11,123 @@ import ( "go.temporal.io/sdk/client" ) -type taskQueuesInfosRowType struct { - Name string `json:"name"` - Type string `json:"type"` - FirstPollerTime time.Time `json:"firstPollerTime"` +type versionSummariesRowType struct { + Version string `json:"version"` + DrainageStatus string `json:"drainageStatus"` + CreateTime time.Time `json:"createTime"` } -type deploymentType struct { - SeriesName string `json:"seriesName"` - BuildID string `json:"buildId"` +type formattedRoutingConfigType struct { + CurrentVersion string `json:"currentVersion"` + RampingVersion string `json:"rampingVersion"` + RampingVersionPercentage float32 `json:"rampingVersionPercentage"` + CurrentVersionChangedTime time.Time `json:"currentVersionChangedTime"` + RampingVersionChangedTime time.Time `json:"rampingVersionChangedTime"` + RampingVersionPercentageChangedTime time.Time `json:"rampingVersionPercentageChangedTime"` } -type formattedDeploymentInfoType struct { - Deployment deploymentType `json:"deployment"` - CreateTime time.Time `json:"createTime"` - IsCurrent bool `json:"isCurrent"` - TaskQueuesInfos []taskQueuesInfosRowType `json:"taskQueuesInfos,omitempty"` - Metadata map[string]*common.Payload `json:"metadata,omitempty"` +type formattedWorkerDeploymentInfoType struct { + Name string `json:"name"` + CreateTime time.Time `json:"createTime"` + LastModifierIdentity string `json:"lastModifierIdentity"` + RoutingConfig formattedRoutingConfigType `json:"routingConfig"` + VersionSummaries []versionSummariesRowType `json:"versionSummaries"` } -type formattedDeploymentReachabilityInfoType struct { - DeploymentInfo formattedDeploymentInfoType `json:"deploymentInfo"` - Reachability string `json:"reachability"` - LastUpdateTime time.Time `json:"lastUpdateTime"` +type formattedWorkerDeploymentListEntryType struct { + Name string + CreateTime time.Time + CurrentVersion string `cli:",cardOmitEmpty"` + RampingVersion string + RampingVersionPercentage float32 `cli:",cardOmitEmpty"` } -type formattedDeploymentListEntryType struct { - SeriesName string - BuildID string - CreateTime time.Time - IsCurrent bool +type formattedDrainageInfo struct { + DrainageStatus string `json:"drainageStatus"` + LastChangedTime time.Time `json:"lastChangedTime"` + LastCheckedTime time.Time `json:"lastCheckedTime"` } -type formattedDualDeploymentInfoType struct { - Previous formattedDeploymentInfoType `json:"previous"` - Current formattedDeploymentInfoType `json:"current"` +type formattedTaskQueueInfoRowType struct { + Name string `json:"name"` + Type string `json:"type"` } -func formatTaskQueuesInfos(tqis []client.DeploymentTaskQueueInfo) ([]taskQueuesInfosRowType, error) { - var tqiRows []taskQueuesInfosRowType - for _, tqi := range tqis { - tqTypeStr, err := taskQueueTypeToStr(tqi.Type) +type formattedWorkerDeploymentVersionInfoType struct { + Version string `json:"version"` + CreateTime time.Time `json:"createTime"` + RoutingChangedTime time.Time `json:"routingChangedTime"` + CurrentSinceTime time.Time `json:"currentSinceTime"` + RampingSinceTime time.Time `json:"rampingSinceTime"` + RampPercentage float32 `json:"rampPercentage"` + DrainageInfo formattedDrainageInfo `json:"drainageInfo"` + TaskQueuesInfos []formattedTaskQueueInfoRowType `json:"taskQueuesInfos"` + Metadata map[string]*common.Payload `json:"metadata"` +} + +func drainageStatusToStr(drainage client.WorkerDeploymentVersionDrainageStatus) (string, error) { + switch drainage { + case client.WorkerDeploymentVersionDrainageStatusUnspecified: + return "unspecified", nil + case client.WorkerDeploymentVersionDrainageStatusDraining: + return "draining", nil + case client.WorkerDeploymentVersionDrainageStatusDrained: + return "drained", nil + default: + return "", fmt.Errorf("unrecognized drainage status: %d", drainage) + } +} + +func formatVersionSummaries(vss []client.WorkerDeploymentVersionSummary) ([]versionSummariesRowType, error) { + var vsRows []versionSummariesRowType + for _, vs := range vss { + drainageStr, err := drainageStatusToStr(vs.DrainageStatus) if err != nil { - return tqiRows, err + return vsRows, err } - tqiRows = append(tqiRows, taskQueuesInfosRowType{ - Name: tqi.Name, - Type: tqTypeStr, - FirstPollerTime: tqi.FirstPollerTime, + vsRows = append(vsRows, versionSummariesRowType{ + Version: vs.Version, + CreateTime: vs.CreateTime, + DrainageStatus: drainageStr, }) } - return tqiRows, nil + return vsRows, nil } -func deploymentInfoToRows(deploymentInfo client.DeploymentInfo) (formattedDeploymentInfoType, error) { - tqi, err := formatTaskQueuesInfos(deploymentInfo.TaskQueuesInfos) +func formatRoutingConfig(rc client.WorkerDeploymentRoutingConfig) (formattedRoutingConfigType, error) { + return formattedRoutingConfigType{ + CurrentVersion: rc.CurrentVersion, + RampingVersion: rc.RampingVersion, + RampingVersionPercentage: rc.RampingVersionPercentage, + CurrentVersionChangedTime: rc.CurrentVersionChangedTime, + RampingVersionChangedTime: rc.RampingVersionChangedTime, + RampingVersionPercentageChangedTime: rc.RampingVersionPercentageChangedTime, + }, nil +} + +func workerDeploymentInfoToRows(deploymentInfo client.WorkerDeploymentInfo) (formattedWorkerDeploymentInfoType, error) { + vs, err := formatVersionSummaries(deploymentInfo.VersionSummaries) if err != nil { - return formattedDeploymentInfoType{}, err + return formattedWorkerDeploymentInfoType{}, err } - return formattedDeploymentInfoType{ - Deployment: deploymentType{ - SeriesName: deploymentInfo.Deployment.SeriesName, - BuildID: deploymentInfo.Deployment.BuildID, - }, - CreateTime: deploymentInfo.CreateTime, - IsCurrent: deploymentInfo.IsCurrent, - TaskQueuesInfos: tqi, - Metadata: deploymentInfo.Metadata, + rc, err := formatRoutingConfig(deploymentInfo.RoutingConfig) + if err != nil { + return formattedWorkerDeploymentInfoType{}, err + } + + return formattedWorkerDeploymentInfoType{ + Name: deploymentInfo.Name, + LastModifierIdentity: deploymentInfo.LastModifierIdentity, + CreateTime: deploymentInfo.CreateTime, + RoutingConfig: rc, + VersionSummaries: vs, }, nil } -func printDeploymentInfo(cctx *CommandContext, deploymentInfo client.DeploymentInfo, msg string) error { +func printWorkerDeploymentInfo(cctx *CommandContext, deploymentInfo client.WorkerDeploymentInfo, msg string) error { - fDeploymentInfo, err := deploymentInfoToRows(deploymentInfo) + fDeploymentInfo, err := workerDeploymentInfoToRows(deploymentInfo) if err != nil { return err } @@ -91,32 +135,40 @@ func printDeploymentInfo(cctx *CommandContext, deploymentInfo client.DeploymentI if !cctx.JSONOutput { cctx.Printer.Println(color.MagentaString(msg)) printMe := struct { - SeriesName string - BuildID string - CreateTime time.Time - IsCurrent bool - Metadata map[string]*common.Payload `cli:",cardOmitEmpty"` + Name string + CreateTime time.Time + LastModifierIdentity string `cli:",cardOmitEmpty"` + CurrentVersion string `cli:",cardOmitEmpty"` + RampingVersion string `cli:",cardOmitEmpty"` + RampingVersionPercentage float32 `cli:",cardOmitEmpty"` + CurrentVersionChangedTime time.Time `cli:",cardOmitEmpty"` + RampingVersionChangedTime time.Time `cli:",cardOmitEmpty"` + RampingVersionPercentageChangedTime time.Time `cli:",cardOmitEmpty"` }{ - SeriesName: deploymentInfo.Deployment.SeriesName, - BuildID: deploymentInfo.Deployment.BuildID, - CreateTime: deploymentInfo.CreateTime, - IsCurrent: deploymentInfo.IsCurrent, - Metadata: deploymentInfo.Metadata, + Name: deploymentInfo.Name, + CreateTime: deploymentInfo.CreateTime, + LastModifierIdentity: deploymentInfo.LastModifierIdentity, + CurrentVersion: deploymentInfo.RoutingConfig.CurrentVersion, + RampingVersion: deploymentInfo.RoutingConfig.RampingVersion, + RampingVersionPercentage: deploymentInfo.RoutingConfig.RampingVersionPercentage, + CurrentVersionChangedTime: deploymentInfo.RoutingConfig.CurrentVersionChangedTime, + RampingVersionChangedTime: deploymentInfo.RoutingConfig.RampingVersionChangedTime, + RampingVersionPercentageChangedTime: deploymentInfo.RoutingConfig.RampingVersionPercentageChangedTime, } err := cctx.Printer.PrintStructured(printMe, printer.StructuredOptions{}) if err != nil { return fmt.Errorf("displaying worker deployment info failed: %w", err) } - if len(deploymentInfo.TaskQueuesInfos) > 0 { + if len(deploymentInfo.VersionSummaries) > 0 { cctx.Printer.Println() - cctx.Printer.Println(color.MagentaString("Task Queues:")) + cctx.Printer.Println(color.MagentaString("Version Summaries:")) err := cctx.Printer.PrintStructured( - deploymentInfo.TaskQueuesInfos, + fDeploymentInfo.VersionSummaries, printer.StructuredOptions{Table: &printer.TableOptions{}}, ) if err != nil { - return fmt.Errorf("displaying task queues info failed: %w", err) + return fmt.Errorf("displaying version summaries failed: %w", err) } } @@ -127,153 +179,233 @@ func printDeploymentInfo(cctx *CommandContext, deploymentInfo client.DeploymentI return cctx.Printer.PrintStructured(fDeploymentInfo, printer.StructuredOptions{}) } -func deploymentReachabilityTypeToStr(reachabilityType client.DeploymentReachability) (string, error) { - switch reachabilityType { - case client.DeploymentReachabilityUnspecified: - return "unspecified", nil - case client.DeploymentReachabilityReachable: - return "reachable", nil - case client.DeploymentReachabilityClosedWorkflows: - return "closed", nil - case client.DeploymentReachabilityUnreachable: - return "unreachable", nil - default: - return "", fmt.Errorf("unrecognized deployment reachability type: %d", reachabilityType) +func extractDeploymentName(version string, deploymentName string, failNonQualified bool) (string, error) { + if version == "" || version == "__unversioned__" { + if failNonQualified { + return "", fmt.Errorf( + "invalid deployment version type for this operation, use a fully-qualified version", + ) + } + if deploymentName == "" { + return "", fmt.Errorf( + "specify the deployment name with `--deployment-name` with a non-fully-qualified version", + ) + } + return deploymentName, nil } + splitVersion := strings.SplitN(version, ".", 2) + if len(splitVersion) != 2 { + return "", fmt.Errorf( + "invalid format for worker deployment version %v, not YourDeploymentName.YourBuildID", + version, + ) + } + return splitVersion[0], nil } -func printDeploymentReachabilityInfo(cctx *CommandContext, reachability client.DeploymentReachabilityInfo) error { - fDeploymentInfo, err := deploymentInfoToRows(reachability.DeploymentInfo) - if err != nil { - return err +func formatDrainageInfo(drainageInfo *client.WorkerDeploymentVersionDrainageInfo) (formattedDrainageInfo, error) { + if drainageInfo == nil { + return formattedDrainageInfo{}, nil } - rTypeStr, err := deploymentReachabilityTypeToStr(reachability.Reachability) + drainageStr, err := drainageStatusToStr(drainageInfo.DrainageStatus) if err != nil { - return err + return formattedDrainageInfo{}, err } - fReachabilityInfo := formattedDeploymentReachabilityInfoType{ - DeploymentInfo: fDeploymentInfo, - LastUpdateTime: reachability.LastUpdateTime, - Reachability: rTypeStr, - } + return formattedDrainageInfo{ + DrainageStatus: drainageStr, + LastChangedTime: drainageInfo.LastChangedTime, + LastCheckedTime: drainageInfo.LastCheckedTime, + }, nil +} - if !cctx.JSONOutput { - err := printDeploymentInfo(cctx, reachability.DeploymentInfo, "Worker Deployment:") +func formatTaskQueuesInfos(tqis []client.WorkerDeploymentTaskQueueInfo) ([]formattedTaskQueueInfoRowType, error) { + var tqiRows []formattedTaskQueueInfoRowType + for _, tqi := range tqis { + tqTypeStr, err := taskQueueTypeToStr(tqi.Type) if err != nil { - return err + return tqiRows, err } + tqiRows = append(tqiRows, formattedTaskQueueInfoRowType{ + Name: tqi.Name, + Type: tqTypeStr, + }) + } + return tqiRows, nil +} - cctx.Printer.Println() - cctx.Printer.Println(color.MagentaString("Reachability:")) - printMe := struct { - LastUpdateTime time.Time - Reachability string - }{ - LastUpdateTime: fReachabilityInfo.LastUpdateTime, - Reachability: fReachabilityInfo.Reachability, - } - return cctx.Printer.PrintStructured(printMe, printer.StructuredOptions{}) +func workerDeploymentVersionInfoToRows(deploymentInfo client.WorkerDeploymentVersionInfo) (formattedWorkerDeploymentVersionInfoType, error) { + tqi, err := formatTaskQueuesInfos(deploymentInfo.TaskQueuesInfos) + if err != nil { + return formattedWorkerDeploymentVersionInfoType{}, err } - // json output - return cctx.Printer.PrintStructured(fReachabilityInfo, printer.StructuredOptions{}) + drainage, err := formatDrainageInfo(deploymentInfo.DrainageInfo) + if err != nil { + return formattedWorkerDeploymentVersionInfoType{}, err + } + + return formattedWorkerDeploymentVersionInfoType{ + Version: deploymentInfo.Version, + CreateTime: deploymentInfo.CreateTime, + RoutingChangedTime: deploymentInfo.RoutingChangedTime, + CurrentSinceTime: deploymentInfo.CurrentSinceTime, + RampingSinceTime: deploymentInfo.RampingSinceTime, + RampPercentage: deploymentInfo.RampPercentage, + DrainageInfo: drainage, + TaskQueuesInfos: tqi, + Metadata: deploymentInfo.Metadata, + }, nil } -func printDeploymentSetCurrentResponse(cctx *CommandContext, response client.DeploymentSetCurrentResponse) error { +func printWorkerDeploymentVersionInfo(cctx *CommandContext, deploymentInfo client.WorkerDeploymentVersionInfo, msg string) error { + fDeploymentInfo, err := workerDeploymentVersionInfoToRows(deploymentInfo) + if err != nil { + return err + } if !cctx.JSONOutput { - err := printDeploymentInfo(cctx, response.Previous, "Previous Worker Deployment:") - if err != nil { - return fmt.Errorf("displaying previous worker deployment info failed: %w", err) + cctx.Printer.Println(color.MagentaString(msg)) + var drainageStr string + var drainageLastChangedTime time.Time + var drainageLastCheckedTime time.Time + if deploymentInfo.DrainageInfo != nil { + drainageStr, err = drainageStatusToStr(deploymentInfo.DrainageInfo.DrainageStatus) + if err != nil { + return err + } + drainageLastChangedTime = deploymentInfo.DrainageInfo.LastChangedTime + drainageLastCheckedTime = deploymentInfo.DrainageInfo.LastCheckedTime } - err = printDeploymentInfo(cctx, response.Current, "Current Worker Deployment:") + printMe := struct { + Version string + CreateTime time.Time + RoutingChangedTime time.Time `cli:",cardOmitEmpty"` + CurrentSinceTime time.Time `cli:",cardOmitEmpty"` + RampingSinceTime time.Time `cli:",cardOmitEmpty"` + RampPercentage float32 + DrainageStatus string `cli:",cardOmitEmpty"` + DrainageLastChangedTime time.Time `cli:",cardOmitEmpty"` + DrainageLastCheckedTime time.Time `cli:",cardOmitEmpty"` + Metadata map[string]*common.Payload `cli:",cardOmitEmpty"` + }{ + Version: deploymentInfo.Version, + CreateTime: deploymentInfo.CreateTime, + RoutingChangedTime: deploymentInfo.RoutingChangedTime, + CurrentSinceTime: deploymentInfo.CurrentSinceTime, + RampingSinceTime: deploymentInfo.RampingSinceTime, + RampPercentage: deploymentInfo.RampPercentage, + DrainageStatus: drainageStr, + DrainageLastChangedTime: drainageLastChangedTime, + DrainageLastCheckedTime: drainageLastCheckedTime, + Metadata: deploymentInfo.Metadata, + } + err := cctx.Printer.PrintStructured(printMe, printer.StructuredOptions{}) if err != nil { - return fmt.Errorf("displaying current worker deployment info failed: %w", err) + return fmt.Errorf("displaying worker deployment version info failed: %w", err) + } + + if len(deploymentInfo.TaskQueuesInfos) > 0 { + cctx.Printer.Println() + cctx.Printer.Println(color.MagentaString("Task Queues:")) + err := cctx.Printer.PrintStructured( + fDeploymentInfo.TaskQueuesInfos, + printer.StructuredOptions{Table: &printer.TableOptions{}}, + ) + if err != nil { + return fmt.Errorf("displaying task queues failed: %w", err) + } } return nil } - previous, err := deploymentInfoToRows(response.Previous) - if err != nil { - return fmt.Errorf("displaying previous worker deployment info failed: %w", err) - } - current, err := deploymentInfoToRows(response.Current) - if err != nil { - return fmt.Errorf("displaying current worker deployment info failed: %w", err) - } + // json output + return cctx.Printer.PrintStructured(fDeploymentInfo, printer.StructuredOptions{}) +} - return cctx.Printer.PrintStructured(formattedDualDeploymentInfoType{ - Previous: previous, - Current: current, - }, printer.StructuredOptions{}) +type getDeploymentConflictTokenOptions struct { + safeMode bool + safeModeMessage string + deploymentName string } -func (c *TemporalWorkerDeploymentDescribeCommand) run(cctx *CommandContext, args []string) error { - cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) +func (c *TemporalWorkerDeploymentCommand) getConflictToken(cctx *CommandContext, options *getDeploymentConflictTokenOptions) ([]byte, error) { + cl, err := c.Parent.ClientOptions.dialClient(cctx) if err != nil { - return err + return nil, err } defer cl.Close() - if c.ReportReachability { - // Expensive call, rate-limited by target method - resp, err := cl.DeploymentClient().GetReachability(cctx, client.DeploymentGetReachabilityOptions{ - Deployment: client.Deployment{ - SeriesName: c.SeriesName, - BuildID: c.BuildId, - }, - }) - if err != nil { - return fmt.Errorf("error describing worker deployment with reachability: %w", err) - } + dHandle := cl.WorkerDeploymentClient().GetHandle(options.deploymentName) - err = printDeploymentReachabilityInfo(cctx, resp) - if err != nil { - return err + resp, err := dHandle.Describe(cctx, client.WorkerDeploymentDescribeOptions{}) + if err != nil { + return nil, fmt.Errorf("unable to get deployment conflict token: %w", err) + } + + if options.safeMode { + // duplicate `cctx.promptYes` check to avoid printing deployment info with json + if cctx.JSONOutput { + return nil, fmt.Errorf("must bypass prompts when using JSON output") } - } else { - resp, err := cl.DeploymentClient().Describe(cctx, client.DeploymentDescribeOptions{ - Deployment: client.Deployment{ - SeriesName: c.SeriesName, - BuildID: c.BuildId, - }, - }) + err = printWorkerDeploymentInfo(cctx, resp.Info, "Worker Deployment Before Update:") if err != nil { - return fmt.Errorf("error describing worker deployment: %w", err) + return nil, fmt.Errorf("displaying deployment failed: %w", err) } - err = printDeploymentInfo(cctx, resp.DeploymentInfo, "Worker Deployment:") + + yes, err := cctx.promptYes( + fmt.Sprintf("Continue with set %v? y/N", options.safeModeMessage), + false, + ) if err != nil { - return err + return nil, err + } else if !yes { + return nil, fmt.Errorf("user denied confirmation") } - } - return nil + return resp.ConflictToken, nil } -func (c *TemporalWorkerDeploymentGetCurrentCommand) run(cctx *CommandContext, args []string) error { +func (c *TemporalWorkerDeploymentDescribeCommand) run(cctx *CommandContext, args []string) error { cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) if err != nil { return err } defer cl.Close() - resp, err := cl.DeploymentClient().GetCurrent(cctx, client.DeploymentGetCurrentOptions{ - SeriesName: c.SeriesName, - }) + dHandle := cl.WorkerDeploymentClient().GetHandle(c.Name) + resp, err := dHandle.Describe(cctx, client.WorkerDeploymentDescribeOptions{}) if err != nil { - return fmt.Errorf("error getting the current deployment: %w", err) + return fmt.Errorf("error describing worker deployment: %w", err) } + err = printWorkerDeploymentInfo(cctx, resp.Info, "Worker Deployment:") + if err != nil { + return err + } + + return nil +} - err = printDeploymentInfo(cctx, resp.DeploymentInfo, "Current Worker Deployment:") +func (c *TemporalWorkerDeploymentDeleteCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) if err != nil { return err } + defer cl.Close() + _, err = cl.WorkerDeploymentClient().Delete(cctx, client.WorkerDeploymentDeleteOptions{ + Name: c.Name, + Identity: c.Identity, + }) + if err != nil { + return fmt.Errorf("error deleting worker deployment: %w", err) + } + + cctx.Printer.Println("Successfully deleted worker deployment") return nil } @@ -284,9 +416,7 @@ func (c *TemporalWorkerDeploymentListCommand) run(cctx *CommandContext, args []s } defer cl.Close() - res, err := cl.DeploymentClient().List(cctx, client.DeploymentListOptions{ - SeriesName: c.SeriesName, - }) + res, err := cl.WorkerDeploymentClient().List(cctx, client.WorkerDeploymentListOptions{}) if err != nil { return err } @@ -300,31 +430,37 @@ func (c *TemporalWorkerDeploymentListCommand) run(cctx *CommandContext, args []s } // make artificial "pages" so we get better aligned columns - page := make([]*formattedDeploymentListEntryType, 0, 100) + page := make([]*formattedWorkerDeploymentListEntryType, 0, 100) for res.HasNext() { entry, err := res.Next() if err != nil { return err } - listEntry := formattedDeploymentInfoType{ - Deployment: deploymentType{ - SeriesName: entry.Deployment.SeriesName, - BuildID: entry.Deployment.BuildID, - }, - CreateTime: entry.CreateTime, - IsCurrent: entry.IsCurrent, + rc, err := formatRoutingConfig(entry.RoutingConfig) + if err != nil { + return err + } + listEntry := formattedWorkerDeploymentInfoType{ + Name: entry.Name, + CreateTime: entry.CreateTime, + RoutingConfig: rc, } if cctx.JSONOutput { // For JSON dump one line of JSON per deployment _ = cctx.Printer.PrintStructured(listEntry, printer.StructuredOptions{}) } else { + rampingVersion := "" + if listEntry.RoutingConfig.RampingVersion != "" { + rampingVersion = listEntry.RoutingConfig.RampingVersion + } // For non-JSON, we are doing a table for each page - page = append(page, &formattedDeploymentListEntryType{ - SeriesName: listEntry.Deployment.SeriesName, - BuildID: listEntry.Deployment.BuildID, - CreateTime: listEntry.CreateTime, - IsCurrent: listEntry.IsCurrent, + page = append(page, &formattedWorkerDeploymentListEntryType{ + Name: listEntry.Name, + CreateTime: listEntry.CreateTime, + CurrentVersion: listEntry.RoutingConfig.CurrentVersion, + RampingVersion: rampingVersion, + RampingVersionPercentage: listEntry.RoutingConfig.RampingVersionPercentage, }) if len(page) == cap(page) { _ = cctx.Printer.PrintStructured(page, printTableOpts) @@ -342,36 +478,184 @@ func (c *TemporalWorkerDeploymentListCommand) run(cctx *CommandContext, args []s return nil } -func (c *TemporalWorkerDeploymentSetCurrentCommand) run(cctx *CommandContext, args []string) error { +func (c *TemporalWorkerDeploymentDeleteVersionCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, "", true) + if err != nil { + return err + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + _, err = dHandle.DeleteVersion(cctx, client.WorkerDeploymentDeleteVersionOptions{ + Version: c.Version, + SkipDrainage: c.SkipDrainage, + Identity: c.Identity, + }) + if err != nil { + return fmt.Errorf("error deleting worker deployment version: %w", err) + } + + cctx.Printer.Println("Successfully deleted worker deployment version") + return nil +} + +func (c *TemporalWorkerDeploymentDescribeVersionCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, "", true) + if err != nil { + return err + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + + resp, err := dHandle.DescribeVersion(cctx, client.WorkerDeploymentDescribeVersionOptions{ + Version: c.Version, + }) + if err != nil { + return fmt.Errorf("error describing worker deployment version: %w", err) + } + + err = printWorkerDeploymentVersionInfo(cctx, resp.Info, "Worker Deployment Version:") + if err != nil { + return err + } + + return nil +} + +func (c *TemporalWorkerDeploymentSetCurrentVersionCommand) run(cctx *CommandContext, args []string) error { cl, err := c.Parent.Parent.dialClient(cctx) if err != nil { return err } defer cl.Close() + name, err := extractDeploymentName(c.Version, c.DeploymentName, false) + if err != nil { + return err + } + + token, err := c.Parent.getConflictToken(cctx, &getDeploymentConflictTokenOptions{ + safeMode: !c.Yes, + safeModeMessage: "Current", + deploymentName: name, + }) + if err != nil { + return err + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + _, err = dHandle.SetCurrentVersion(cctx, client.WorkerDeploymentSetCurrentVersionOptions{ + Version: c.Version, + Identity: c.Identity, + IgnoreMissingTaskQueues: c.IgnoreMissingTaskQueues, + ConflictToken: token, + }) + if err != nil { + return fmt.Errorf("error setting the current worker deployment version: %w", err) + } + + cctx.Printer.Println("Successfully setting the current worker deployment version") + return nil +} + +func (c *TemporalWorkerDeploymentSetRampingVersionCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, c.DeploymentName, false) + if err != nil { + return err + } + + token, err := c.Parent.getConflictToken(cctx, &getDeploymentConflictTokenOptions{ + safeMode: !c.Yes, + safeModeMessage: "Ramping", + deploymentName: name, + }) + if err != nil { + return err + } + + version := c.Version + percentage := c.Percentage + if c.Delete { + version = "" + percentage = 0.0 + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + _, err = dHandle.SetRampingVersion(cctx, client.WorkerDeploymentSetRampingVersionOptions{ + Version: version, + Percentage: percentage, + ConflictToken: token, + Identity: c.Identity, + IgnoreMissingTaskQueues: c.IgnoreMissingTaskQueues, + }) + if err != nil { + return fmt.Errorf("error setting the ramping worker deployment version: %w", err) + } + + cctx.Printer.Println("Successfully setting the ramping worker deployment version") + return nil +} + +func (c *TemporalWorkerDeploymentUpdateMetadataVersionCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, "", true) + if err != nil { + return err + } + metadata, err := stringKeysJSONValues(c.Metadata, false) if err != nil { return fmt.Errorf("invalid metadata values: %w", err) } - resp, err := cl.DeploymentClient().SetCurrent(cctx, client.DeploymentSetCurrentOptions{ - Deployment: client.Deployment{ - SeriesName: c.SeriesName, - BuildID: c.BuildId, - }, - MetadataUpdate: client.DeploymentMetadataUpdate{ + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + response, err := dHandle.UpdateVersionMetadata(cctx, client.WorkerDeploymentUpdateVersionMetadataOptions{ + Version: c.Version, + MetadataUpdate: client.WorkerDeploymentMetadataUpdate{ UpsertEntries: metadata, + RemoveEntries: c.RemoveEntries, }, }) + if err != nil { - return fmt.Errorf("error setting the current worker deployment: %w", err) + return err + } + + cctx.Printer.Println(color.MagentaString("Metadata:")) + printMe := struct { + Metadata map[string]*common.Payload `cli:",cardOmitEmpty"` + }{ + Metadata: response.Metadata, } - err = printDeploymentSetCurrentResponse(cctx, resp) + err = cctx.Printer.PrintStructured(printMe, printer.StructuredOptions{}) if err != nil { - return err + return fmt.Errorf("displaying metadata failed: %w", err) } - cctx.Printer.Println("Successfully setting the current worker deployment") + cctx.Printer.Println("Successfully updating metadata for worker deployment version") + return nil } diff --git a/temporalcli/commands.worker.deployment_test.go b/temporalcli/commands.worker.deployment_test.go index 08c61309d..3ebdcbddc 100644 --- a/temporalcli/commands.worker.deployment_test.go +++ b/temporalcli/commands.worker.deployment_test.go @@ -3,32 +3,65 @@ package temporalcli_test import ( "encoding/base64" "encoding/json" + "fmt" "sort" + "strings" "time" "github.com/google/uuid" + "github.com/stretchr/testify/assert" "go.temporal.io/api/common/v1" + "go.temporal.io/sdk/worker" + "go.temporal.io/sdk/workflow" ) -type jsonTaskQueuesInfosRowType struct { - Name string `json:"name"` - Type string `json:"type"` - FirstPollerTime time.Time `json:"firstPollerTime"` +type jsonVersionSummariesRowType struct { + Version string `json:"version"` + DrainageStatus string `json:"drainageStatus"` + CreateTime time.Time `json:"createTime"` } -type jsonDeploymentType struct { - SeriesName string `json:"seriesName"` - BuildID string `json:"buildId"` +type jsonRoutingConfigType struct { + CurrentVersion string `json:"currentVersion"` + RampingVersion string `json:"rampingVersion"` + RampingVersionPercentage float32 `json:"rampingVersionPercentage"` + CurrentVersionChangedTime time.Time `json:"currentVersionChangedTime"` + RampingVersionChangedTime time.Time `json:"rampingVersionChangedTime"` + RampingVersionPercentageChangedTime time.Time `json:"rampingVersionPercentageChangedTime"` } type jsonDeploymentInfoType struct { - Deployment jsonDeploymentType `json:"deployment"` - CreateTime time.Time `json:"createTime"` - IsCurrent bool `json:"isCurrent"` - TaskQueuesInfos []jsonTaskQueuesInfosRowType `json:"taskQueuesInfos,omitempty"` - Metadata map[string]*common.Payload `json:"metadata,omitempty"` + Name string `json:"name"` + CreateTime time.Time `json:"createTime"` + LastModifierIdentity string `json:"lastModifierIdentity"` + RoutingConfig jsonRoutingConfigType `json:"routingConfig"` + VersionSummaries []jsonVersionSummariesRowType `json:"versionSummaries"` } +type jsonDrainageInfo struct { + DrainageStatus string `json:"drainageStatus"` + LastChangedTime time.Time `json:"lastChangedTime"` + LastCheckedTime time.Time `json:"lastCheckedTime"` +} + +type jsonTaskQueueInfoRowType struct { + Name string `json:"name"` + Type string `json:"type"` +} + +type jsonDeploymentVersionInfoType struct { + Version string `json:"version"` + CreateTime time.Time `json:"createTime"` + RoutingChangedTime time.Time `json:"routingChangedTime"` + CurrentSinceTime time.Time `json:"currentSinceTime"` + RampingSinceTime time.Time `json:"rampingSinceTime"` + RampPercentage float32 `json:"rampPercentage"` + DrainageInfo jsonDrainageInfo `json:"drainageInfo"` + TaskQueuesInfos []jsonTaskQueueInfoRowType `json:"taskQueuesInfos"` + Metadata map[string]*common.Payload `json:"metadata"` +} + +/* type jsonDeploymentReachabilityInfoType struct { DeploymentInfo jsonDeploymentInfoType `json:"deploymentInfo"` Reachability string `json:"reachability"` @@ -40,152 +73,480 @@ type jsonDeploymentListEntryType struct { CreateTime time.Time `json:"createTime"` IsCurrent bool `json:"isCurrent"` } +*/ -func (s *SharedServerSuite) TestDeployment_Set_Current() { - seriesName := uuid.NewString() +func (s *SharedServerSuite) TestDeployment_Set_Current_Version() { + deploymentName := uuid.NewString() buildId := uuid.NewString() + version := deploymentName + "." + buildId + w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w.Stop() + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId, - "--metadata", "bar=1", + "--version", version, + "--yes", ) s.NoError(res.Err) res = s.Execute( - "worker", "deployment", "get-current", + "worker", "deployment", "describe", "--address", s.Address(), - "--series-name", seriesName, + "--name", deploymentName, ) s.NoError(res.Err) - s.ContainsOnSameLine(res.Stdout.String(), "SeriesName", seriesName) - s.ContainsOnSameLine(res.Stdout.String(), "BuildID", buildId) - s.ContainsOnSameLine(res.Stdout.String(), "IsCurrent", "true") - s.ContainsOnSameLine(res.Stdout.String(), "Metadata", "data:\"1\"") + s.ContainsOnSameLine(res.Stdout.String(), "Name", deploymentName) + s.ContainsOnSameLine(res.Stdout.String(), "CurrentVersion", version) // json res = s.Execute( - "worker", "deployment", "get-current", + "worker", "deployment", "describe", "--address", s.Address(), - "--series-name", seriesName, + "--name", deploymentName, "--output", "json", ) s.NoError(res.Err) var jsonOut jsonDeploymentInfoType s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) - s.Equal(jsonDeploymentType{SeriesName: seriesName, BuildID: buildId}, jsonOut.Deployment) - s.True(jsonOut.IsCurrent) + s.Equal(deploymentName, jsonOut.Name) + s.Equal(version, jsonOut.RoutingConfig.CurrentVersion) + + // set metadata + res = s.Execute( + "worker", "deployment", "update-metadata-version", + "--address", s.Address(), + "--version", version, + "--metadata", "bar=1", + "--output", "json", + ) + s.NoError(res.Err) + var jsonVersionOut jsonDeploymentVersionInfoType + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonVersionOut)) + // "1" is "MQ==" - s.Equal("MQ==", base64.StdEncoding.EncodeToString(jsonOut.Metadata["bar"].GetData())) + s.Equal("MQ==", base64.StdEncoding.EncodeToString(jsonVersionOut.Metadata["bar"].GetData())) // "json/plain" is "anNvbi9wbGFpbg==" - s.Equal("anNvbi9wbGFpbg==", base64.StdEncoding.EncodeToString(jsonOut.Metadata["bar"].GetMetadata()["encoding"])) + s.Equal("anNvbi9wbGFpbg==", base64.StdEncoding.EncodeToString(jsonVersionOut.Metadata["bar"].GetMetadata()["encoding"])) + + // remove metadata + res = s.Execute( + "worker", "deployment", "update-metadata-version", + "--address", s.Address(), + "--version", version, + "--remove-entries", "bar", + "--output", "json", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version, + "--output", "json", + ) + s.NoError(res.Err) + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonVersionOut)) + s.Nil(jsonVersionOut.Metadata) +} + +func filterByNamePrefix(jsonOut []jsonDeploymentInfoType, prefix string) []jsonDeploymentInfoType { + result := []jsonDeploymentInfoType{} + for i := range jsonOut { + if strings.HasPrefix(jsonOut[i].Name, prefix) { + result = append(result, jsonOut[i]) + } + } + return result } func (s *SharedServerSuite) TestDeployment_List() { - seriesName := uuid.NewString() + prefix := uuid.NewString() + deploymentName1 := prefix + "a" + uuid.NewString() + deploymentName2 := prefix + "b" + uuid.NewString() buildId1 := uuid.NewString() buildId2 := uuid.NewString() + version1 := deploymentName1 + "." + buildId1 + version2 := deploymentName2 + "." + buildId2 + + w1 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version1, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w1.Stop() + + w2 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version2, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w2.Stop() + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName1) + assert.Contains(t, res.Stdout.String(), deploymentName2) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version1, + ) + assert.NoError(t, res.Err) + res = s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version2, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, + "--version", version1, + "--yes", ) s.NoError(res.Err) res = s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId2, + "--version", version2, + "--yes", ) s.NoError(res.Err) res = s.Execute( "worker", "deployment", "list", "--address", s.Address(), - "--series-name", seriesName, ) s.NoError(res.Err) - s.ContainsOnSameLine(res.Stdout.String(), seriesName, buildId1, "false") - s.ContainsOnSameLine(res.Stdout.String(), seriesName, buildId2, "true") + s.ContainsOnSameLine(res.Stdout.String(), deploymentName1, version1) + s.ContainsOnSameLine(res.Stdout.String(), deploymentName2, version2) // json res = s.Execute( "worker", "deployment", "list", "--address", s.Address(), - "--series-name", seriesName, "--output", "json", ) s.NoError(res.Err) - var jsonOut []jsonDeploymentListEntryType + var jsonOut []jsonDeploymentInfoType s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) + jsonOut = filterByNamePrefix(jsonOut, prefix) sort.Slice(jsonOut, func(i, j int) bool { - return jsonOut[i].CreateTime.Before(jsonOut[j].CreateTime) + return jsonOut[i].Name < jsonOut[j].Name }) - s.Equal(len(jsonOut), 2) - s.Equal(jsonDeploymentType{SeriesName: seriesName, BuildID: buildId1}, jsonOut[0].Deployment) - s.True(!jsonOut[0].IsCurrent) - s.Equal(jsonDeploymentType{SeriesName: seriesName, BuildID: buildId2}, jsonOut[1].Deployment) - s.True(jsonOut[1].IsCurrent) + s.Equal(2, len(jsonOut)) + s.Equal(deploymentName1, jsonOut[0].Name) + s.Equal(version1, jsonOut[0].RoutingConfig.CurrentVersion) + s.Equal(deploymentName2, jsonOut[1].Name) + s.Equal(version2, jsonOut[1].RoutingConfig.CurrentVersion) } -func (s *SharedServerSuite) TestDeployment_Describe_Reachability() { - seriesName := uuid.NewString() - buildId1 := uuid.NewString() - buildId2 := uuid.NewString() +func (s *SharedServerSuite) TestDeployment_Describe_Drainage() { + deploymentName := uuid.NewString() + buildId1 := "a" + uuid.NewString() + buildId2 := "b" + uuid.NewString() + version1 := deploymentName + "." + buildId1 + version2 := deploymentName + "." + buildId2 + + w1 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version1, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w1.Stop() + + w2 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version2, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w2.Stop() + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version1, + ) + assert.NoError(t, res.Err) + res = s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version2, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", + "--address", s.Address(), + "--version", version1, + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, + "--name", deploymentName, ) s.NoError(res.Err) + s.ContainsOnSameLine(res.Stdout.String(), "CurrentVersion", version1) + fmt.Print("hello") res = s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId2, + "--version", version2, + "--yes", ) s.NoError(res.Err) res = s.Execute( "worker", "deployment", "describe", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, - "--report-reachability", + "--name", deploymentName, ) s.NoError(res.Err) - s.ContainsOnSameLine(res.Stdout.String(), "SeriesName", seriesName) - s.ContainsOnSameLine(res.Stdout.String(), "BuildID", buildId1) - s.ContainsOnSameLine(res.Stdout.String(), "IsCurrent", "false") - s.ContainsOnSameLine(res.Stdout.String(), "Reachability", "unreachable") + s.ContainsOnSameLine(res.Stdout.String(), "CurrentVersion", version2) + s.ContainsOnSameLine(res.Stdout.String(), version1, "draining") + s.ContainsOnSameLine(res.Stdout.String(), version2, "unspecified") // json res = s.Execute( "worker", "deployment", "describe", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId2, - "--report-reachability", + "--name", deploymentName, + "--output", "json", + ) + s.NoError(res.Err) + + var jsonOut jsonDeploymentInfoType + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) + s.Equal(deploymentName, jsonOut.Name) + sort.Slice(jsonOut.VersionSummaries, func(i, j int) bool { + return jsonOut.VersionSummaries[i].Version < jsonOut.VersionSummaries[j].Version + }) + + s.Equal(2, len(jsonOut.VersionSummaries)) + s.Equal("draining", jsonOut.VersionSummaries[0].DrainageStatus) + s.Equal(version1, jsonOut.VersionSummaries[0].Version) + s.Equal("unspecified", jsonOut.VersionSummaries[1].DrainageStatus) + s.Equal(version2, jsonOut.VersionSummaries[1].Version) +} + +func (s *SharedServerSuite) TestDeployment_Ramping() { + deploymentName := uuid.NewString() + buildId1 := "a" + uuid.NewString() + buildId2 := "b" + uuid.NewString() + version1 := deploymentName + "." + buildId1 + version2 := deploymentName + "." + buildId2 + + w1 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version1, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w1.Stop() + + w2 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version2, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w2.Stop() + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version1, + ) + assert.NoError(t, res.Err) + res = s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version2, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) + + res := s.Execute( + "worker", "deployment", "set-current-version", + "--address", s.Address(), + "--version", version1, + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "set-ramping-version", + "--address", s.Address(), + "--version", version2, + "--percentage", "12.5", + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe", + "--address", s.Address(), + "--name", deploymentName, + ) + s.NoError(res.Err) + + s.ContainsOnSameLine(res.Stdout.String(), "CurrentVersion", version1) + s.ContainsOnSameLine(res.Stdout.String(), "RampingVersion", version2) + s.ContainsOnSameLine(res.Stdout.String(), "RampingVersionPercentage", "12.5") + + // setting version2 as current also removes the ramp + res = s.Execute( + "worker", "deployment", "set-current-version", + "--address", s.Address(), + "--version", version2, + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe", + "--address", s.Address(), + "--name", deploymentName, "--output", "json", ) s.NoError(res.Err) - var jsonOut jsonDeploymentReachabilityInfoType + var jsonOut jsonDeploymentInfoType s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) - s.Equal(jsonDeploymentType{SeriesName: seriesName, BuildID: buildId2}, jsonOut.DeploymentInfo.Deployment) - s.True(jsonOut.DeploymentInfo.IsCurrent) - s.Equal(jsonOut.Reachability, "reachable") + s.Equal(deploymentName, jsonOut.Name) + s.Empty(jsonOut.RoutingConfig.RampingVersion) + s.Equal(version2, jsonOut.RoutingConfig.CurrentVersion) + + //same with explicit delete + res = s.Execute( + "worker", "deployment", "set-ramping-version", + "--address", s.Address(), + "--version", version1, + "--percentage", "10.1", + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe", + "--address", s.Address(), + "--name", deploymentName, + ) + s.NoError(res.Err) + + s.ContainsOnSameLine(res.Stdout.String(), "CurrentVersion", version2) + s.ContainsOnSameLine(res.Stdout.String(), "RampingVersion", version1) + s.ContainsOnSameLine(res.Stdout.String(), "RampingVersionPercentage", "10.1") + + res = s.Execute( + "worker", "deployment", "set-ramping-version", + "--address", s.Address(), + "--version", version1, + "--delete", + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe", + "--address", s.Address(), + "--name", deploymentName, + "--output", "json", + ) + s.NoError(res.Err) + + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) + s.Equal(deploymentName, jsonOut.Name) + s.Empty(jsonOut.RoutingConfig.RampingVersion) + s.Equal(version2, jsonOut.RoutingConfig.CurrentVersion) + } diff --git a/temporalcli/commands.workflow.go b/temporalcli/commands.workflow.go index 421fa354b..ae189678d 100644 --- a/temporalcli/commands.workflow.go +++ b/temporalcli/commands.workflow.go @@ -15,7 +15,6 @@ import ( "github.com/temporalio/cli/temporalcli/internal/printer" "go.temporal.io/api/batch/v1" "go.temporal.io/api/common/v1" - deploymentpb "go.temporal.io/api/deployment/v1" "go.temporal.io/api/enums/v1" "go.temporal.io/api/query/v1" sdkpb "go.temporal.io/api/sdk/v1" @@ -103,20 +102,14 @@ func (c *TemporalWorkflowUpdateOptionsCommand) run(cctx *CommandContext, args [] defer cl.Close() if c.VersioningOverrideBehavior.Value == "unspecified" || c.VersioningOverrideBehavior.Value == "auto_upgrade" { - if c.VersioningOverrideSeriesName != "" { - return fmt.Errorf("cannot set deployment series name with %v behavior", c.VersioningOverrideBehavior) - } - if c.VersioningOverrideBuildId != "" { - return fmt.Errorf("cannot set deployment build ID with %v behavior", c.VersioningOverrideBehavior) + if c.VersioningOverridePinnedVersion != "" { + return fmt.Errorf("cannot set pinned version with %v behavior", c.VersioningOverrideBehavior) } } if c.VersioningOverrideBehavior.Value == "pinned" { - if c.VersioningOverrideSeriesName == "" { - return fmt.Errorf("missing deployment series name with 'pinned' behavior") - } - if c.VersioningOverrideBuildId == "" { - return fmt.Errorf("missing deployment build ID with 'pinned' behavior") + if c.VersioningOverridePinnedVersion == "" { + return fmt.Errorf("missing version with 'pinned' behavior") } } @@ -145,11 +138,8 @@ func (c *TemporalWorkflowUpdateOptionsCommand) run(cctx *CommandContext, args [] RunId: exec.RunId, WorkflowExecutionOptionsChanges: client.WorkflowExecutionOptionsChanges{ VersioningOverride: &client.VersioningOverride{ - Behavior: behavior, - Deployment: client.Deployment{ - SeriesName: c.VersioningOverrideSeriesName, - BuildID: c.VersioningOverrideBuildId, - }, + Behavior: behavior, + PinnedVersion: c.VersioningOverridePinnedVersion, }, }, }) @@ -178,22 +168,13 @@ func (c *TemporalWorkflowUpdateOptionsCommand) run(cctx *CommandContext, args [] ) } - deployment := &deploymentpb.Deployment{ - SeriesName: c.VersioningOverrideSeriesName, - BuildId: c.VersioningOverrideBuildId, - } - if c.VersioningOverrideSeriesName == "" && c.VersioningOverrideBuildId == "" { - // auto_upgrade needs a `nil` pointer - deployment = nil - } - batchReq.Operation = &workflowservice.StartBatchOperationRequest_UpdateWorkflowOptionsOperation{ UpdateWorkflowOptionsOperation: &batch.BatchOperationUpdateWorkflowExecutionOptions{ Identity: clientIdentity(), WorkflowExecutionOptions: &workflowpb.WorkflowExecutionOptions{ VersioningOverride: &workflowpb.VersioningOverride{ - Behavior: behavior, - Deployment: deployment, + Behavior: behavior, + PinnedVersion: c.VersioningOverridePinnedVersion, }, }, UpdateMask: protoMask, diff --git a/temporalcli/commands.workflow_test.go b/temporalcli/commands.workflow_test.go index 8ece140c6..8e479c82f 100644 --- a/temporalcli/commands.workflow_test.go +++ b/temporalcli/commands.workflow_test.go @@ -429,7 +429,9 @@ func (s *SharedServerSuite) TestWorkflow_Cancel_SingleWorkflowSuccess() { func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Override() { buildId1 := uuid.NewString() buildId2 := uuid.NewString() - seriesName := uuid.NewString() + deploymentName := uuid.NewString() + version1 := deploymentName + "." + buildId1 + version2 := deploymentName + "." + buildId2 // Workflow that waits to be canceled. waitingWorkflow := func(ctx workflow.Context) error { ctx.Done().Receive(ctx, nil) @@ -437,10 +439,9 @@ func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Overrid } w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ Worker: worker.Options{ - BuildID: buildId1, - UseBuildIDForVersioning: true, DeploymentOptions: worker.DeploymentOptions{ - DeploymentSeriesName: seriesName, + UseVersioning: true, + Version: version1, DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, }, }, @@ -448,11 +449,29 @@ func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Overrid }) defer w.Stop() + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version1, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) + res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, + "--version", version1, + "--yes", ) s.NoError(res.Err) @@ -481,7 +500,7 @@ func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Overrid "-w", run.GetID(), ) assert.NoError(t, res.Err) - assert.Contains(t, res.Stdout.String(), buildId1) + assert.Contains(t, res.Stdout.String(), version1) assert.Contains(t, res.Stdout.String(), "Pinned") } }, 30*time.Second, 100*time.Millisecond) @@ -492,8 +511,7 @@ func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Overrid "--address", s.Address(), "--query", "CustomKeywordField = '"+searchAttr+"'", "--versioning-override-behavior", "pinned", - "--versioning-override-series-name", seriesName, - "--versioning-override-build-id", buildId2, + "--versioning-override-pinned-version", version2, ) s.NoError(res.Err) @@ -512,7 +530,7 @@ func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Overrid assert.NoError(t, temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo assert.NotNil(t, versioningInfo.VersioningOverride) - assert.Equal(t, seriesName+"."+buildId2, versioningInfo.VersioningOverride.PinnedVersion) + assert.Equal(t, version2, versioningInfo.VersioningOverride.PinnedVersion) } }, 30*time.Second, 100*time.Millisecond) } @@ -520,7 +538,10 @@ func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Overrid func (s *SharedServerSuite) TestWorkflow_Update_Options_Versioning_Override() { buildId1 := uuid.NewString() buildId2 := uuid.NewString() - seriesName := uuid.NewString() + deploymentName := uuid.NewString() + version1 := deploymentName + "." + buildId1 + version2 := deploymentName + "." + buildId2 + // Workflow that waits to be canceled. waitingWorkflow := func(ctx workflow.Context) error { ctx.Done().Receive(ctx, nil) @@ -528,10 +549,9 @@ func (s *SharedServerSuite) TestWorkflow_Update_Options_Versioning_Override() { } w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ Worker: worker.Options{ - BuildID: buildId1, - UseBuildIDForVersioning: true, DeploymentOptions: worker.DeploymentOptions{ - DeploymentSeriesName: seriesName, + UseVersioning: true, + Version: version1, DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, }, }, @@ -539,11 +559,29 @@ func (s *SharedServerSuite) TestWorkflow_Update_Options_Versioning_Override() { }) defer w.Stop() + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version1, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) + res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, + "--version", version1, + "--yes", ) s.NoError(res.Err) @@ -562,7 +600,7 @@ func (s *SharedServerSuite) TestWorkflow_Update_Options_Versioning_Override() { "-w", run.GetID(), ) assert.NoError(t, res.Err) - assert.Contains(t, res.Stdout.String(), buildId1) + assert.Contains(t, res.Stdout.String(), version1) assert.Contains(t, res.Stdout.String(), "Pinned") }, 30*time.Second, 100*time.Millisecond) @@ -571,8 +609,7 @@ func (s *SharedServerSuite) TestWorkflow_Update_Options_Versioning_Override() { "--address", s.Address(), "-w", run.GetID(), "--versioning-override-behavior", "pinned", - "--versioning-override-series-name", seriesName, - "--versioning-override-build-id", buildId2, + "--versioning-override-pinned-version", version2, ) s.NoError(res.Err) @@ -584,10 +621,7 @@ func (s *SharedServerSuite) TestWorkflow_Update_Options_Versioning_Override() { s.NoError(res.Err) s.ContainsOnSameLine(res.Stdout.String(), "OverrideBehavior", "Pinned") - // TODO(antlai-temporal): replace by new Deployment API - // These fields are deprecated, and not populated in latest server - // s.ContainsOnSameLine(res.Stdout.String(), "OverrideDeploymentSeriesName", seriesName) - // s.ContainsOnSameLine(res.Stdout.String(), "OverrideDeploymentBuildID", buildId2) + s.ContainsOnSameLine(res.Stdout.String(), "OverridePinnedVersion", version2) // remove override res = s.Execute( diff --git a/temporalcli/commands.workflow_view.go b/temporalcli/commands.workflow_view.go index 3ca20cd37..f416a82aa 100644 --- a/temporalcli/commands.workflow_view.go +++ b/temporalcli/commands.workflow_view.go @@ -140,23 +140,17 @@ func (c *TemporalWorkflowDescribeCommand) run(cctx *CommandContext, args []strin cctx.Printer.Println() vInfo := info.VersioningInfo _ = cctx.Printer.PrintStructured(struct { - Behavior string - DeploymentSeriesName string - DeploymentBuildID string - OverrideBehavior string `cli:",cardOmitEmpty"` - OverrideDeploymentSeriesName string `cli:",cardOmitEmpty"` - OverrideDeploymentBuildID string `cli:",cardOmitEmpty"` - TransitionDeploymentSeriesName string `cli:",cardOmitEmpty"` - TransitionDeploymentBuildID string `cli:",cardOmitEmpty"` + Behavior string + Version string + OverrideBehavior string `cli:",cardOmitEmpty"` + OverridePinnedVersion string `cli:",cardOmitEmpty"` + TransitionVersion string `cli:",cardOmitEmpty"` }{ - Behavior: vInfo.Behavior.String(), - DeploymentSeriesName: vInfo.Deployment.GetSeriesName(), - DeploymentBuildID: vInfo.Deployment.GetBuildId(), - OverrideBehavior: vInfo.VersioningOverride.GetBehavior().String(), - OverrideDeploymentSeriesName: vInfo.VersioningOverride.GetDeployment().GetSeriesName(), - OverrideDeploymentBuildID: vInfo.VersioningOverride.GetDeployment().GetBuildId(), - TransitionDeploymentSeriesName: vInfo.DeploymentTransition.GetDeployment().GetSeriesName(), - TransitionDeploymentBuildID: vInfo.DeploymentTransition.GetDeployment().GetBuildId(), + Behavior: vInfo.Behavior.String(), + Version: vInfo.GetVersion(), + OverrideBehavior: vInfo.VersioningOverride.GetBehavior().String(), + OverridePinnedVersion: vInfo.VersioningOverride.GetPinnedVersion(), + TransitionVersion: vInfo.VersionTransition.GetVersion(), }, printer.StructuredOptions{}) } diff --git a/temporalcli/commands.workflow_view_test.go b/temporalcli/commands.workflow_view_test.go index 8ad7a80cc..3348012c3 100644 --- a/temporalcli/commands.workflow_view_test.go +++ b/temporalcli/commands.workflow_view_test.go @@ -550,18 +550,18 @@ func (s *SharedServerSuite) TestWorkflow_Count() { func (s *SharedServerSuite) TestWorkflow_Describe_Deployment() { buildId := uuid.NewString() - seriesName := uuid.NewString() + deploymentName := uuid.NewString() // Workflow that waits to be canceled. waitingWorkflow := func(ctx workflow.Context) error { ctx.Done().Receive(ctx, nil) return ctx.Err() } + version := deploymentName + "." + buildId w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ Worker: worker.Options{ - BuildID: buildId, - UseBuildIDForVersioning: true, DeploymentOptions: worker.DeploymentOptions{ - DeploymentSeriesName: seriesName, + UseVersioning: true, + Version: version, DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, }, }, @@ -569,11 +569,29 @@ func (s *SharedServerSuite) TestWorkflow_Describe_Deployment() { }) defer w.Stop() + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) + res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId, + "--version", version, + "--yes", ) s.NoError(res.Err) @@ -592,16 +610,13 @@ func (s *SharedServerSuite) TestWorkflow_Describe_Deployment() { "-w", run.GetID(), ) assert.NoError(t, res.Err) - assert.Contains(t, res.Stdout.String(), buildId) + assert.Contains(t, res.Stdout.String(), version) assert.Contains(t, res.Stdout.String(), "Pinned") }, 30*time.Second, 100*time.Millisecond) out := res.Stdout.String() s.ContainsOnSameLine(out, "Behavior", "Pinned") - // TODO(antlai-temporal): replace by new Deployment API - // These fields are deprecated, and not populated in latest server - //s.ContainsOnSameLine(out, "DeploymentBuildID", buildId) - //s.ContainsOnSameLine(out, "DeploymentSeriesName", seriesName) + s.ContainsOnSameLine(out, "Version", version) s.ContainsOnSameLine(out, "OverrideBehavior", "Unspecified") // json @@ -617,12 +632,8 @@ func (s *SharedServerSuite) TestWorkflow_Describe_Deployment() { s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo s.Equal("Pinned", versioningInfo.Behavior.String()) - // TODO(antlai-temporal): replace by new Deployment API - // These fields are deprecated, and not populated in latest server - // s.Equal(buildId, versioningInfo.Deployment.BuildId) - // s.Equal(seriesName, versioningInfo.Deployment.SeriesName) + s.Equal(version, versioningInfo.Version) s.Nil(versioningInfo.VersioningOverride) - s.Nil(versioningInfo.DeploymentTransition) } func (s *SharedServerSuite) TestWorkflow_Describe_NexusOperationAndCallback() { diff --git a/temporalcli/commands_test.go b/temporalcli/commands_test.go index 467f2c9bb..74606eef2 100644 --- a/temporalcli/commands_test.go +++ b/temporalcli/commands_test.go @@ -371,6 +371,7 @@ func StartDevServer(t *testing.T, options DevServerOptions) *DevServer { d.Options.DynamicConfigValues["frontend.workerVersioningDataAPIs"] = true d.Options.DynamicConfigValues["frontend.workerVersioningWorkflowAPIs"] = true d.Options.DynamicConfigValues["system.enableDeployments"] = true + d.Options.DynamicConfigValues["system.enableDeploymentVersions"] = true d.Options.DynamicConfigValues["worker.buildIdScavengerEnabled"] = true d.Options.DynamicConfigValues["frontend.enableUpdateWorkflowExecution"] = true d.Options.DynamicConfigValues["frontend.MaxConcurrentBatchOperationPerNamespace"] = 1000 diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index 249930ab3..21e4b3c5e 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -672,7 +672,7 @@ commands: - worker deployment - name: temporal worker deployment - summary: Describe, list, and operate on Worker Deployments + summary: Describe, list, and operate on Worker Deployments and Versions description: | +---------------------------------------------------------------------+ | CAUTION: Worker Deployment is experimental. Deployment commands are | @@ -690,17 +690,40 @@ commands: ``` temporal worker deployment list ``` + + Lists the Deployments in the client's namespace. + + Arguments can be Worker Deployment Versions associated with + a Deployment, using a fully qualified Version identifier that + concatenates the Deployment Name and the Build ID with the + reserved separator ".". + + For example: + + ``` + temporal worker deployment set-current-version \ + --version YourDeploymentName.YourBuildID + ``` + + Sets the current Deployment Version for a given Deployment. + docs: description-header: >- - Temporal Deployment commands enable operations on Worker Deployments, - such as describe, list, set-current, and get-current, simplifying - versioning and management of workers. + Temporal Deployment commands enable operations on Worker Deployments + that simplify versioning and management of workers, + such as describe, list, delete, and also operations that refer to Worker + Deployment Versions within them, such as describe-version, + delete-version, set-current-version, or set-ramping-version. keywords: - worker deployment - worker deployment describe - worker deployment list - - worker deployment get-current - - worker deployment set-current + - worker deployment delete + - worker deployment describe-version + - worker deployment set-current-version + - worker deployment set-ramping-version + - worker deployment delete-version + - worker deployment update-metadata-version - name: temporal worker deployment describe summary: Show properties of a Worker Deployment @@ -710,59 +733,54 @@ commands: | subject to change. | +---------------------------------------------------------------------+ - Describes properties of a Worker Deployment, such as whether it is - current, the non-empty list of its task queues, custom metadata if - present, and reachability status when requested. + Describe properties of a Worker Deployment, such as the versions + associated with it, routing information of new or existing tasks + executed by this deployment, or its creation time. ``` temporal worker deployment describe [options] ``` - For example, to also include reachability information: + For example, to describe a deployment `YourDeploymentName` in the default + namespace: ``` temporal worker deployment describe \ - --series-name YourDeploymentSeriesName \ - --build-id YourDeploymentBuildId \ - --report-reachability + --name YourDeploymentName ``` option-sets: - - deployment-reference - options: - - name: report-reachability - type: bool - description: | - Include reachability information of a Worker Deployment. + - deployment-name - - name: temporal worker deployment get-current - summary: Show the current Worker Deployment + - name: temporal worker deployment delete + summary: Delete a Worker Deployment description: | +---------------------------------------------------------------------+ | CAUTION: Worker Deployment is experimental. Deployment commands are | | subject to change. | +---------------------------------------------------------------------+ - Gets the current Worker Deployment for a Deployment Series Name. - When a Deployment is current, Workers of that Deployment will receive - tasks from new Workflows and from existing AutoUpgrade Workflows that - are running on this Deployment Series. + Remove a Worker Deployment given its Deployment Name. + A Deployment can only be deleted if it has no Version in it. ``` - temporal worker deployment get-current [options] + temporal worker deployment delete [options] ``` - For example: + For example, setting the user identity that removed the deployment: ``` - temporal worker deployment get-current \ - --series-name YourDeploymentSeriesName + temporal worker deployment delete \ + --name YourDeploymentName \ + --identity YourIdentity + ``` + option-sets: + - deployment-name options: - - name: series-name + - name: identity type: string - description: Series Name for the current Worker Deployment. - required: true - + description: Identity of the user submitting this request. + - name: temporal worker deployment list summary: Enumerate Worker Deployments in the client's namespace description: | @@ -771,51 +789,248 @@ commands: | subject to change. | +---------------------------------------------------------------------+ - List existing Worker Deployments in the client's namespace, optionally - filtering them by Deployment Series Name. - + List existing Worker Deployments in the client's namespace. ``` temporal worker deployment list [options] ``` - For example, adding an optional filter: + For example, listing Deployments in YourDeploymentNamespace: ``` temporal worker deployment list \ - --series-name YourDeploymentSeriesName + --namespace YourDeploymentNamespace + ``` + + - name: temporal worker deployment describe-version + summary: Show properties of a Worker Deployment Version + description: | + +---------------------------------------------------------------------+ + | CAUTION: Worker Deployment is experimental. Deployment commands are | + | subject to change. | + +---------------------------------------------------------------------+ + + Describe properties of a Worker Deployment Version, such as the task + queues polled by workers in this Deployment Version, or drainage + information required to safely decommission workers, or user-provided + metadata, or its creation/modification time. + + ``` + temporal worker deployment describe-version [options] + ``` + + For example, to describe a deployment version in a deployment + `YourDeploymentName`, with Build ID `YourBuildID`, and in the default + namespace: + ``` + temporal worker deployment describe-version \ + --version YourDeploymentName.YourBuildID + ``` + option-sets: + - deployment-version + + - name: temporal worker deployment delete-version + summary: Delete a Worker Deployment Version + description: | + +---------------------------------------------------------------------+ + | CAUTION: Worker Deployment is experimental. Deployment commands are | + | subject to change. | + +---------------------------------------------------------------------+ + + Remove a Worker Deployment Version given its fully-qualified identifier. + This is rarely needed during normal operation + since unused Versions are eventually garbage collected. + The client can delete a Version only when all of the following conditions + are met: + - It is not the Current or Ramping Version for this Deployment. + - It has no active pollers, i.e., none of the task queues in the + Version have pollers. + - It is not draining. This requirement can be ignored with the option + `--skip-drainage`. + + ``` + temporal worker deployment delete-version [options] + ``` + + For example, skipping the drainage restriction: + + ``` + temporal worker deployment delete-version \ + --version YourDeploymentName.YourBuildID \ + --skip-drainage + ``` + option-sets: + - deployment-version options: - - name: series-name + - name: identity + type: string + description: Identity of the user submitting this request. + - name: skip-drainage + type: bool + description: Ignore the deletion requirement of not draining. + + - name: temporal worker deployment set-current-version + summary: Make a Worker Deployment Version Current for a Deployment + description: | + +---------------------------------------------------------------------+ + | CAUTION: Worker Deployment is experimental. Deployment commands are | + | subject to change. | + +---------------------------------------------------------------------+ + + Set the Current Version for a Deployment. + When a Version is current, Workers of that Deployment Version will receive + tasks from new Workflows, and from existing AutoUpgrade Workflows that + are running on this Deployment. + + If not all the expected Task Queues are being polled by Workers in the + new Version the request will fail. To override this protection use + `--ignore-missing-task-queues`. Note that this would ignore task queues + in a deployment that are not yet discovered, leading to inconsistent task + queue configuration. + + ``` + temporal worker deployment set-current-version [options] + ``` + + For example, to set the Current Version of a deployment + `YourDeploymentName`, with a version with Build ID `YourBuildID`, and + in the default namespace: + + ``` + temporal worker deployment set-current-version \ + --version YourDeploymentName.YourBuildID + ``` + + The target of set-current-version can also be `__unversioned__`, which + moves tasks to unversioned workers, but in this case we also need to + specify the Deployment Name. + + ``` + temporal worker deployment set-current-version \ + --version __unversioned__ \ + --deployment-name YourDeploymentName + ``` + option-sets: + - deployment-version + options: + - name: deployment-name type: string - description: Series Name to filter Worker Deployments. + description: | + Deployment name. + Only needed when `--version` is `__unversioned__` or empty. + - name: identity + type: string + description: Identity of the user submitting this request. + - name: ignore-missing-task-queues + type: bool + description: Override protection to accidentally remove task queues. + - name: yes + short: y + type: bool + description: Don't prompt to confirm set Current Version. - - name: temporal worker deployment set-current - summary: Change the current Worker Deployment + - name: temporal worker deployment set-ramping-version + summary: Change Version Ramping settings for a Worker Deployment description: | +---------------------------------------------------------------------+ - | CAUTION: Worker deployment is experimental. Deployment commands are | + | CAUTION: Worker Deployment is experimental. Deployment commands are | | subject to change. | +---------------------------------------------------------------------+ - Sets the current Deployment for a given Deployment Series. - When a Deployment is current, Workers of that Deployment will receive - tasks from new Workflows and from existing AutoUpgrade Workflows that - are running on this Deployment Series. + Set the Ramping Version and Percentage for a Deployment. + + The Ramping Version can be set to a fully-qualified Version of the form + `YourDeploymentName.YourBuildID`, or set to "__unversioned__", a special + value that represents all the unversioned workers. + + The Ramping Percentage is a float with values in the range [0, 100]. + A value of 100 does not make the Ramping Version Current, use + `set-current-version` instead. + + To remove a Ramping Version use the flag `--delete`. + + If not all the expected Task Queues are being polled by Workers in the + new Ramping Version the request will fail. To override this protection use + `--ignore-missing-task-queues`. Note that this would ignore task queues + in a deployment that are not yet discovered, leading to inconsistent task + queue configuration. + + ``` + temporal worker deployment set-ramping-version [options] + ``` + + For example, to set the Ramping Version of a deployment + `YourDeploymentName`, with a version with Build ID `YourBuildID`, with + 10 percent of tasks redirected to this version, and + using the default namespace: ``` - temporal worker deployment set-current [options] + temporal worker deployment set-ramping-version \ + --version YourDeploymentName.YourBuildID + --percentage 10.0 ``` + And to remove that ramping: + + ``` + temporal worker deployment set-ramping-version \ + --version YourDeploymentName.YourBuildID \ + --delete + ``` + option-sets: + - deployment-version + options: + - name: deployment-name + type: string + description: | + Deployment name. + Only needed when `--version` is `__unversioned__`. + - name: percentage + type: float + description: | + Percentage of tasks redirected to the Ramping Version. + Valid range [0,100]. + - name: delete + type: bool + description: Delete the Ramping Version. + - name: identity + type: string + description: Identity of the user submitting this request. + - name: ignore-missing-task-queues + type: bool + description: Override protection to accidentally remove task queues. + - name: yes + short: y + type: bool + description: Don't prompt to confirm set Ramping Version. + + - name: temporal worker deployment update-metadata-version + summary: Change user-provided metadata for a Version + description: | + +---------------------------------------------------------------------+ + | CAUTION: Worker Deployment is experimental. Deployment commands are | + | subject to change. | + +---------------------------------------------------------------------+ + Update metadata associated with a Worker Deployment Version. + For example: ``` - temporal worker deployment set-current \ - --series-name YourDeploymentSeriesName \ - --build-id YourDeploymentBuildId + temporal worker deployment update-metadata-version \ + --version YourDeploymentName.YourBuildID \ + --metadata bar=1 \ + --metadata foo=true + ``` + + The current metadata is also returned with `describe-version`: + ``` + temporal worker deployment describe-version \ + --version YourDeploymentName.YourBuildID \ + ``` option-sets: - - deployment-reference + - deployment-version options: - name: metadata type: string[] @@ -824,7 +1039,12 @@ commands: Keys must be identifiers, and values must be JSON values. For example: 'YourKey={"your": "value"}'. Can be passed multiple times. - + - name: remove-entries + type: string[] + description: | + Keys of entries to be deleted from metadata. + Can be passed multiple times. + - name: temporal env summary: Manage environments description: | @@ -2376,8 +2596,7 @@ commands: summary: Manage Task Queue Build ID handling (Experimental) description: | +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ Provides commands to add, list, remove, or replace Worker Build ID assignment @@ -2419,8 +2638,7 @@ commands: ``` +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: source-build-id @@ -2461,8 +2679,7 @@ commands: override this validation. +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: build-id @@ -2494,8 +2711,7 @@ commands: Use the `--force` option to override this validation. +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: rule-index @@ -2525,8 +2741,7 @@ commands: ``` +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: source-build-id @@ -2559,10 +2774,8 @@ commands: Build ID. You may add at most one redirect rule for each source Build ID. Redirect rules require that a target Build ID is fully compatible with the source Build ID. - +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ - name: temporal task-queue versioning insert-assignment-rule @@ -2581,8 +2794,7 @@ commands: If you do not specify a `--rule-index`, this command inserts at index 0. +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: build-id @@ -2637,8 +2849,7 @@ commands: Percent may vary between 0 and 100 (default). +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: build-id @@ -2679,8 +2890,7 @@ commands: ``` +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: source-build-id @@ -2976,8 +3186,8 @@ commands: temporal workflow update-options \ --workflow-id YourWorkflowId \ --versioning-override-behavior pinned \ - --versioning-override-series-name YourDeploymentSeriesName \ - --versioning-override-build-id YourDeploymentBuildId + --versioning-override-pinned-version \ + YourDeploymentSeriesName.YourDeploymentBuildId ``` To remove any previous overrides, set the behavior to @@ -3003,12 +3213,9 @@ commands: - unspecified - pinned - auto_upgrade - - name: versioning-override-series-name - type: string - description: Override Series Name for a Worker Deployment (Only for pinned). - - name: versioning-override-build-id + - name: versioning-override-pinned-version type: string - description: Override Build ID for a Worker Deployment (Only for pinned). + description: Override Pinned Version for a Worker Deployment (Only for pinned). - name: temporal workflow query summary: Retrieve Workflow Execution state @@ -3608,6 +3815,24 @@ option-sets: short: r description: Run ID. + - name: deployment-name + options: + - name: name + type: string + short: d + description: Name for a Worker Deployment. + required: true + + - name: deployment-version + options: + - name: version + type: string + short: v + description: | + Fully-qualified name for a Worker Deployment Version. + Use the format `YourDeploymentName.YourBuildID`. + required: true + - name: deployment-reference options: - name: series-name