Skip to content

Commit

Permalink
enable opslevel get tag --type resource alias [key]
Browse files Browse the repository at this point in the history
  • Loading branch information
Taimoor Ahmad committed Sep 14, 2023
1 parent e40a684 commit 6ef2fe7
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 1 deletion.
88 changes: 88 additions & 0 deletions src/cmd/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"reflect"
"strings"

"github.com/opslevel/cli/common"
Expand All @@ -13,6 +14,42 @@ import (
"github.com/spf13/cobra"
)

type TaggableResourceFetchFunction func(id opslevel.ID) (any, error)

var TaggableResourceFetchFunctions = map[opslevel.TaggableResource]TaggableResourceFetchFunction{
opslevel.TaggableResourceService: func(id opslevel.ID) (any, error) { return getClientGQL().GetService(id) },
opslevel.TaggableResourceRepository: func(id opslevel.ID) (any, error) { return getClientGQL().GetRepository(id) },
opslevel.TaggableResourceTeam: func(id opslevel.ID) (any, error) { return getClientGQL().GetTeam(id) },
opslevel.TaggableResourceUser: func(id opslevel.ID) (any, error) { return getClientGQL().GetUser(string(id)) },
opslevel.TaggableResourceDomain: func(id opslevel.ID) (any, error) { return getClientGQL().GetDomain(string(id)) },
opslevel.TaggableResourceSystem: func(id opslevel.ID) (any, error) { return getClientGQL().GetSystem(string(id)) },
opslevel.TaggableResourceInfrastructureresource: func(id opslevel.ID) (any, error) { return getClientGQL().GetInfrastructure(string(id)) },
}

type TaggableResourceFetchAliasFunction func(alias string) (any, error)

var TaggableResourceFetchAliasFunctions = map[opslevel.TaggableResource]TaggableResourceFetchAliasFunction{
opslevel.TaggableResourceService: func(alias string) (any, error) { return getClientGQL().GetServiceWithAlias(alias) },
opslevel.TaggableResourceRepository: func(alias string) (any, error) { return getClientGQL().GetRepositoryWithAlias(alias) },
opslevel.TaggableResourceTeam: func(alias string) (any, error) { return getClientGQL().GetTeamWithAlias(alias) },
opslevel.TaggableResourceUser: func(alias string) (any, error) { return getClientGQL().GetUser(alias) },
opslevel.TaggableResourceDomain: func(alias string) (any, error) { return getClientGQL().GetDomain(alias) },
opslevel.TaggableResourceSystem: func(alias string) (any, error) { return getClientGQL().GetSystem(alias) },
opslevel.TaggableResourceInfrastructureresource: func(alias string) (any, error) { return getClientGQL().GetInfrastructure(alias) },
}

func GetTags(obj interface{}) (*opslevel.TagConnection, error) {
// call Elem because input is a ptr
v := reflect.ValueOf(obj).Elem()
tagsField := v.FieldByName("Tags")

if tagsField.IsValid() {
return tagsField.Interface().(*opslevel.TagConnection), nil
} else {
return nil, errors.New("reflection error")
}
}

var resourceType string

var createTagCmd = &cobra.Command{
Expand Down Expand Up @@ -68,6 +105,54 @@ opslevel create tag --type=Team ID|ALIAS KEY VALUE
},
}

var getObjectTagCmd = &cobra.Command{
Use: "tag --type=RESOURCE_TYPE RESOURCE_ID [KEY]",
Short: "Get values of tags on objects",
Long: "Get values of tags on objects",
Example: `
opslevel get tag --type=Service ID|ALIAS KEY # search for values of a specific key
opslevel get tag --type=Team ID|ALIAS | jq 'from_entries' # values of all keys
`,
Args: cobra.MinimumNArgs(1),
ArgAliases: []string{"RESOURCE_ID", "KEY"},
Run: func(cmd *cobra.Command, args []string) {
err := validateResourceTypeArg()
cobra.CheckErr(err)

resource := args[0]
singleTag := len(args) == 2
var tagKey string
if singleTag {
tagKey = args[1]
}

var result any
if opslevel.IsID(resource) {
id := opslevel.ID(resource)
result, err = TaggableResourceFetchFunctions[opslevel.TaggableResource(resourceType)](id)
} else {
alias := args[0]
result, err = TaggableResourceFetchAliasFunctions[opslevel.TaggableResource(resourceType)](alias)
}

tags, err := GetTags(result)
cobra.CheckErr(err)

var output []opslevel.Tag
for _, tag := range tags.Nodes {
if !singleTag || tagKey == tag.Key {
output = append(output, tag)
}
}

if singleTag && len(output) == 0 {
err := fmt.Errorf("tag with key '%s' not found on %s '%s'", tagKey, resourceType, resource)
cobra.CheckErr(err)
}
common.PrettyPrint(output)
},
}

var updateTagCmd = &cobra.Command{
Use: "tag TAG_ID KEY VALUE",
Short: "Update a tag",
Expand Down Expand Up @@ -117,6 +202,9 @@ func init() {
createTagCmd.Flags().StringVar(&resourceType, "type", "", "resource type")
createTagCmd.Flags().Bool("assign", false, "assign a tag instead of creating it")

getCmd.AddCommand(getObjectTagCmd)
getObjectTagCmd.Flags().StringVar(&resourceType, "type", "", "resource type")

updateCmd.AddCommand(updateTagCmd)

deleteCmd.AddCommand(deleteTagCmd)
Expand Down

0 comments on commit 6ef2fe7

Please sign in to comment.