1/*
2Copyright 2018 The Doctl Authors All rights reserved.
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6    http://www.apache.org/licenses/LICENSE-2.0
7Unless required by applicable law or agreed to in writing, software
8distributed under the License is distributed on an "AS IS" BASIS,
9WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10See the License for the specific language governing permissions and
11limitations under the License.
12*/
13
14package commands
15
16import (
17	"github.com/digitalocean/doctl"
18	"github.com/digitalocean/doctl/commands/displayers"
19	"github.com/digitalocean/doctl/do"
20	"github.com/digitalocean/godo"
21	"github.com/spf13/cobra"
22)
23
24// Tags creates the tag commands hierarchy.
25func Tags() *Command {
26	cmd := &Command{
27		Command: &cobra.Command{
28			Use:   "tag",
29			Short: "Display commands to manage tags",
30			Long: `The sub-commands of ` + "`" + `doctl compute tag` + "`" + ` manage the tags on your account.
31
32A tag is a label that can be applied to a resource (currently Droplets, images,
33volumes, volume snapshots, and database clusters) in order to better organize or
34facilitate the lookups and actions on it.
35
36Tags have two attributes: a user defined name attribute and an embedded
37resources attribute with information about resources that have been tagged.`,
38		},
39	}
40
41	CmdBuilder(cmd, RunCmdTagCreate, "create <tag-name>", "Create a tag", `Use this command to create a new tag.`, Writer)
42
43	CmdBuilder(cmd, RunCmdTagGet, "get <tag-name>", "Retrieve information about a tag", `Use this command to retrieve a tag, display a count of how many resources are tagged with it, and show the most recently tagged resource.`, Writer,
44		displayerType(&displayers.Tag{}))
45
46	CmdBuilder(cmd, RunCmdTagList, "list", "List all tags", `Use this command to retrieve a list of all the tags in your account.`, Writer,
47		aliasOpt("ls"), displayerType(&displayers.Tag{}))
48
49	cmdRunTagDelete := CmdBuilder(cmd, RunCmdTagDelete, "delete <tag-name>...", "Delete a tag", `Use this command to delete a tag.
50
51Deleting a tag also removes the tag from all the resources that had been tagged with it.`, Writer)
52	AddBoolFlag(cmdRunTagDelete, doctl.ArgForce, doctl.ArgShortForce, false, "Delete tag without confirmation prompt")
53
54	return cmd
55}
56
57// RunCmdTagCreate runs tag create.
58func RunCmdTagCreate(c *CmdConfig) error {
59	err := ensureOneArg(c)
60	if err != nil {
61		return err
62	}
63
64	name := c.Args[0]
65	ts := c.Tags()
66
67	tcr := &godo.TagCreateRequest{Name: name}
68	t, err := ts.Create(tcr)
69	if err != nil {
70		return err
71	}
72
73	return c.Display(&displayers.Tag{Tags: do.Tags{*t}})
74}
75
76// RunCmdTagGet runs tag get.
77func RunCmdTagGet(c *CmdConfig) error {
78	err := ensureOneArg(c)
79	if err != nil {
80		return err
81	}
82
83	name := c.Args[0]
84	ts := c.Tags()
85	t, err := ts.Get(name)
86	if err != nil {
87		return err
88	}
89
90	return c.Display(&displayers.Tag{Tags: do.Tags{*t}})
91}
92
93// RunCmdTagList runs tag list.
94func RunCmdTagList(c *CmdConfig) error {
95	ts := c.Tags()
96	tags, err := ts.List()
97	if err != nil {
98		return err
99	}
100
101	return c.Display(&displayers.Tag{Tags: tags})
102}
103
104// RunCmdTagDelete runs tag delete.
105func RunCmdTagDelete(c *CmdConfig) error {
106	if len(c.Args) < 1 {
107		return doctl.NewMissingArgsErr(c.NS)
108	}
109
110	force, err := c.Doit.GetBool(c.NS, doctl.ArgForce)
111	if err != nil {
112		return err
113	}
114
115	if force || AskForConfirmDelete("tag", len(c.Args)) == nil {
116		for id := range c.Args {
117			name := c.Args[id]
118			ts := c.Tags()
119			if err := ts.Delete(name); err != nil {
120				return err
121			}
122		}
123	} else {
124		return errOperationAborted
125	}
126
127	return nil
128}
129