pulumi/pkg/cmd/pulumi/stack_tag.go
CyrusNajmabadi 66bd3f4aa8
Breaking changes due to Feature 2.0 work
* Make `async:true` the default for `invoke` calls (#3750)

* Switch away from native grpc impl. (#3728)

* Remove usage of the 'deasync' library from @pulumi/pulumi. (#3752)

* Only retry as long as we get unavailable back.  Anything else continues. (#3769)

* Handle all errors for now. (#3781)


* Do not assume --yes was present when using pulumi in non-interactive mode (#3793)

* Upgrade all paths for sdk and pkg to v2

* Backport C# invoke classes and other recent gen changes (#4288)

Adjust C# generation

* Replace IDeployment with a sealed class (#4318)

Replace IDeployment with a sealed class

* .NET: default to args subtype rather than Args.Empty (#4320)

* Adding system namespace for Dotnet code gen

This is required for using Obsolute attributes for deprecations

```
Iam/InstanceProfile.cs(142,10): error CS0246: The type or namespace name 'ObsoleteAttribute' could not be found (are you missing a using directive or an assembly reference?) [/Users/stack72/code/go/src/github.com/pulumi/pulumi-aws/sdk/dotnet/Pulumi.Aws.csproj]
Iam/InstanceProfile.cs(142,10): error CS0246: The type or namespace name 'Obsolete' could not be found (are you missing a using directive or an assembly reference?) [/Users/stack72/code/go/src/github.com/pulumi/pulumi-aws/sdk/dotnet/Pulumi.Aws.csproj]
```

* Fix the nullability of config type properties in C# codegen (#4379)
2020-04-14 09:30:25 +01:00

204 lines
4.9 KiB
Go

// Copyright 2016-2018, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"sort"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/pulumi/pulumi/pkg/v2/backend"
"github.com/pulumi/pulumi/pkg/v2/backend/display"
"github.com/pulumi/pulumi/sdk/v2/go/common/apitype"
"github.com/pulumi/pulumi/sdk/v2/go/common/util/cmdutil"
)
func newStackTagCmd() *cobra.Command {
var stack string
cmd := &cobra.Command{
Use: "tag",
Short: "Manage stack tags",
Long: "Manage stack tags\n" +
"\n" +
"Stacks have associated metadata in the form of tags. Each tag consists of a name\n" +
"and value. The `get`, `ls`, `rm`, and `set` commands can be used to manage tags.\n" +
"Some tags are automatically assigned based on the environment each time a stack\n" +
"is updated.\n",
Args: cmdutil.NoArgs,
}
cmd.PersistentFlags().StringVarP(
&stack, "stack", "s", "", "The name of the stack to operate on. Defaults to the current stack")
cmd.AddCommand(newStackTagGetCmd(&stack))
cmd.AddCommand(newStackTagLsCmd(&stack))
cmd.AddCommand(newStackTagRmCmd(&stack))
cmd.AddCommand(newStackTagSetCmd(&stack))
return cmd
}
func newStackTagGetCmd(stack *string) *cobra.Command {
return &cobra.Command{
Use: "get <name>",
Short: "Get a single stack tag value",
Args: cmdutil.SpecificArgs([]string{"name"}),
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
name := args[0]
opts := display.Options{
Color: cmdutil.GetGlobalColorization(),
}
s, err := requireStack(*stack, false, opts, true /*setCurrent*/)
if err != nil {
return err
}
tags, err := backend.GetStackTags(commandContext(), s)
if err != nil {
return err
}
if value, ok := tags[name]; ok {
fmt.Printf("%v\n", value)
return nil
}
return errors.Errorf(
"stack tag '%s' not found for stack '%s'", name, s.Ref())
}),
}
}
func newStackTagLsCmd(stack *string) *cobra.Command {
var jsonOut bool
cmd := &cobra.Command{
Use: "ls",
Short: "List all stack tags",
Args: cmdutil.NoArgs,
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
opts := display.Options{
Color: cmdutil.GetGlobalColorization(),
}
s, err := requireStack(*stack, false, opts, true /*setCurrent*/)
if err != nil {
return err
}
tags, err := backend.GetStackTags(commandContext(), s)
if err != nil {
return err
}
if jsonOut {
return printJSON(tags)
}
printStackTags(tags)
return nil
}),
}
cmd.PersistentFlags().BoolVarP(
&jsonOut, "json", "j", false, "Emit output as JSON")
return cmd
}
func printStackTags(tags map[apitype.StackTagName]string) {
var names []string
for n := range tags {
names = append(names, n)
}
sort.Strings(names)
rows := []cmdutil.TableRow{}
for _, name := range names {
rows = append(rows, cmdutil.TableRow{Columns: []string{name, tags[name]}})
}
cmdutil.PrintTable(cmdutil.Table{
Headers: []string{"NAME", "VALUE"},
Rows: rows,
})
}
func newStackTagRmCmd(stack *string) *cobra.Command {
return &cobra.Command{
Use: "rm <name>",
Short: "Remove a stack tag",
Args: cmdutil.SpecificArgs([]string{"name"}),
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
name := args[0]
opts := display.Options{
Color: cmdutil.GetGlobalColorization(),
}
s, err := requireStack(*stack, false, opts, true /*setCurrent*/)
if err != nil {
return err
}
ctx := commandContext()
tags, err := backend.GetStackTags(ctx, s)
if err != nil {
return err
}
delete(tags, name)
return backend.UpdateStackTags(ctx, s, tags)
}),
}
}
func newStackTagSetCmd(stack *string) *cobra.Command {
return &cobra.Command{
Use: "set <name> <value>",
Short: "Set a stack tag",
Args: cmdutil.SpecificArgs([]string{"name", "value"}),
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
name := args[0]
value := args[1]
opts := display.Options{
Color: cmdutil.GetGlobalColorization(),
}
s, err := requireStack(*stack, false, opts, true /*setCurrent*/)
if err != nil {
return err
}
ctx := commandContext()
tags, err := backend.GetStackTags(ctx, s)
if err != nil {
return err
}
if tags == nil {
tags = make(map[apitype.StackTagName]string)
}
tags[name] = value
return backend.UpdateStackTags(ctx, s, tags)
}),
}
}