diff --git a/api/handlers/tags.go b/api/handlers/tags.go index 6a9e0932..3bd364c0 100644 --- a/api/handlers/tags.go +++ b/api/handlers/tags.go @@ -39,6 +39,57 @@ func (h *HandlersApi) AllTagsHandler(w http.ResponseWriter, r *http.Request) { h.Inc(metricAPITagsOK) } +// TagEnvHandler - GET Handler to return one tag for one environment as JSON +func (h *HandlersApi) TagEnvHandler(w http.ResponseWriter, r *http.Request) { + h.Inc(metricAPITagsReq) + utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAPI, settings.NoEnvironmentID), false) + // Extract environment + envVar := r.PathValue("env") + if envVar == "" { + apiErrorResponse(w, "error getting environment", http.StatusBadRequest, nil) + h.Inc(metricAPITagsErr) + return + } + // Extract tag name + tagVar := r.PathValue("name") + if tagVar == "" { + apiErrorResponse(w, "error getting tag name", http.StatusBadRequest, nil) + h.Inc(metricAPITagsErr) + return + } + // Get environment by UUID + env, err := h.Envs.GetByUUID(envVar) + if err != nil { + if err.Error() == "record not found" { + apiErrorResponse(w, "environment not found", http.StatusNotFound, err) + } else { + apiErrorResponse(w, "error getting environment", http.StatusInternalServerError, err) + } + h.Inc(metricAPIEnvsErr) + return + } + // Get context data and check access + ctx := r.Context().Value(ContextKey(contextAPI)).(ContextValue) + if !h.Users.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { + apiErrorResponse(w, "no access", http.StatusForbidden, fmt.Errorf("attempt to use API by user %s", ctx[ctxUser])) + h.Inc(metricAPITagsErr) + return + } + // Get tag + exist, tag := h.Tags.ExistsGet(tagVar, env.ID) + if !exist { + apiErrorResponse(w, "error getting tag", http.StatusInternalServerError, err) + h.Inc(metricAPITagsErr) + return + } + // Serialize and serve JSON + if h.Settings.DebugService(settings.ServiceAPI) { + log.Debug().Msg("DebugService: Returned tag") + } + utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, tag) + h.Inc(metricAPITagsOK) +} + // TagsEnvHandler - GET Handler to return tags for one environment as JSON func (h *HandlersApi) TagsEnvHandler(w http.ResponseWriter, r *http.Request) { h.Inc(metricAPITagsReq) diff --git a/api/main.go b/api/main.go index b8ee408f..ed9fdab8 100644 --- a/api/main.go +++ b/api/main.go @@ -604,6 +604,7 @@ func osctrlAPIService() { // API: tags by environment muxAPI.Handle("GET "+_apiPath(apiTagsPath), handlerAuthCheck(http.HandlerFunc(handlersApi.AllTagsHandler))) muxAPI.Handle("GET "+_apiPath(apiTagsPath)+"/{env}", handlerAuthCheck(http.HandlerFunc(handlersApi.TagsEnvHandler))) + muxAPI.Handle("GET "+_apiPath(apiTagsPath)+"/{env}/{name}", handlerAuthCheck(http.HandlerFunc(handlersApi.TagEnvHandler))) muxAPI.Handle("POST "+_apiPath(apiTagsPath)+"/{env}/{action}", handlerAuthCheck(http.HandlerFunc(handlersApi.TagsActionHandler))) // API: settings by environment muxAPI.Handle("GET "+_apiPath(apiSettingsPath), handlerAuthCheck(http.HandlerFunc(handlersApi.SettingsHandler))) diff --git a/cli/api-tag.go b/cli/api-tag.go new file mode 100644 index 00000000..8246418d --- /dev/null +++ b/cli/api-tag.go @@ -0,0 +1,129 @@ +package main + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/jmpsec/osctrl/tags" + "github.com/jmpsec/osctrl/types" +) + +// GetAllTags to retrieve all tags from osctrl +func (api *OsctrlAPI) GetAllTags() ([]tags.AdminTag, error) { + var tgs []tags.AdminTag + reqURL := fmt.Sprintf("%s%s%s", api.Configuration.URL, APIPath, APITags) + rawTgs, err := api.GetGeneric(reqURL, nil) + if err != nil { + return tgs, fmt.Errorf("error api request - %v - %s", err, string(rawTgs)) + } + if err := json.Unmarshal(rawTgs, &tgs); err != nil { + return tgs, fmt.Errorf("can not parse body - %v", err) + } + return tgs, nil +} + +// GetTags to retrieve tags from osctrl by environment +func (api *OsctrlAPI) GetTags(env string) ([]tags.AdminTag, error) { + var tgs []tags.AdminTag + reqURL := fmt.Sprintf("%s%s%s/%s", api.Configuration.URL, APIPath, APITags, env) + rawTgs, err := api.GetGeneric(reqURL, nil) + if err != nil { + return tgs, fmt.Errorf("error api request - %v - %s", err, string(rawTgs)) + } + if err := json.Unmarshal(rawTgs, &tgs); err != nil { + return tgs, fmt.Errorf("can not parse body - %v", err) + } + return tgs, nil +} + +// GetTag to retrieve a tag from osctrl by environment and name +func (api *OsctrlAPI) GetTag(env, name string) (tags.AdminTag, error) { + var t tags.AdminTag + reqURL := fmt.Sprintf("%s%s%s/%s/%s", api.Configuration.URL, APIPath, APITags, env, name) + rawT, err := api.GetGeneric(reqURL, nil) + if err != nil { + return t, fmt.Errorf("error api request - %v - %s", err, string(rawT)) + } + if err := json.Unmarshal(rawT, &t); err != nil { + return t, fmt.Errorf("can not parse body - %v", err) + } + return t, nil +} + +// AddTag to add a tag to osctrl +func (api *OsctrlAPI) AddTag(envUUID, name, color, icon, description string, tagType uint) (types.ApiGenericResponse, error) { + var r types.ApiGenericResponse + t := types.ApiTagsRequest{ + Name: name, + Description: description, + Color: color, + Icon: icon, + EnvUUID: envUUID, + TagType: tagType, + } + reqURL := fmt.Sprintf("%s%s%s/%s/%s", api.Configuration.URL, APIPath, APITags, envUUID, tags.ActionAdd) + jsonMessage, err := json.Marshal(t) + if err != nil { + return r, fmt.Errorf("error marshaling data - %v", err) + } + jsonParam := strings.NewReader(string(jsonMessage)) + rawT, err := api.PostGeneric(reqURL, jsonParam) + if err != nil { + return r, fmt.Errorf("error api request - %v", err) + } + if err := json.Unmarshal(rawT, &r); err != nil { + return r, fmt.Errorf("can not parse body - %v", err) + } + return r, nil +} + +// DeleteTag to delete a tag from osctrl +func (api *OsctrlAPI) DeleteTag(envUUID, name string) (types.ApiGenericResponse, error) { + var r types.ApiGenericResponse + t := types.ApiTagsRequest{ + Name: name, + EnvUUID: envUUID, + } + reqURL := fmt.Sprintf("%s%s%s/%s/%s", api.Configuration.URL, APIPath, APITags, envUUID, tags.ActionRemove) + jsonMessage, err := json.Marshal(t) + if err != nil { + return r, fmt.Errorf("error marshaling data - %v", err) + } + jsonParam := strings.NewReader(string(jsonMessage)) + rawT, err := api.PostGeneric(reqURL, jsonParam) + if err != nil { + return r, fmt.Errorf("error api request - %v", err) + } + if err := json.Unmarshal(rawT, &r); err != nil { + return r, fmt.Errorf("can not parse body - %v", err) + } + return r, nil +} + +// EditTag to edit a tag from osctrl +func (api *OsctrlAPI) EditTag(envUUID, name, color, icon, description string, tagType uint) (types.ApiGenericResponse, error) { + var r types.ApiGenericResponse + t := types.ApiTagsRequest{ + Name: name, + Description: description, + Color: color, + Icon: icon, + EnvUUID: envUUID, + TagType: tagType, + } + reqURL := fmt.Sprintf("%s%s%s/%s/%s", api.Configuration.URL, APIPath, APITags, envUUID, tags.ActionEdit) + jsonMessage, err := json.Marshal(t) + if err != nil { + return r, fmt.Errorf("error marshaling data - %v", err) + } + jsonParam := strings.NewReader(string(jsonMessage)) + rawT, err := api.PostGeneric(reqURL, jsonParam) + if err != nil { + return r, fmt.Errorf("error api request - %v", err) + } + if err := json.Unmarshal(rawT, &r); err != nil { + return r, fmt.Errorf("can not parse body - %v", err) + } + return r, nil +} diff --git a/cli/api.go b/cli/api.go index f97cfc4a..c0ddaad3 100644 --- a/cli/api.go +++ b/cli/api.go @@ -28,6 +28,8 @@ const ( APIUSers = "/users" // APIEnvironments for the environments path APIEnvironments = "/environments" + // APITags for the tags path + APITags = "/tags" // APILogin for the login path APILogin = "/login" // JSONApplication for Content-Type headers diff --git a/cli/main.go b/cli/main.go index 4665c28a..594ec7aa 100644 --- a/cli/main.go +++ b/cli/main.go @@ -1145,19 +1145,14 @@ func init() { Usage: "Tag an existing node", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "uuid", + Name: "uuid, u", Aliases: []string{"u"}, Usage: "Node UUID to be tagged", }, &cli.StringFlag{ - Name: "env", - Aliases: []string{"e"}, - Usage: "Environment to be used", - }, - &cli.StringFlag{ - Name: "tag-value", - Aliases: []string{"T"}, - Usage: "Tag value to be used. It will be created if does not exist", + Name: "name", + Aliases: []string{"n"}, + Usage: "Tag name to be used. It will be created if does not exist", }, &cli.StringFlag{ Name: "tag-type", @@ -1521,24 +1516,34 @@ func init() { &cli.StringFlag{ Name: "name", Aliases: []string{"n"}, - Usage: "Tage name to be added", + Usage: "Tage name to be used", + }, + &cli.StringFlag{ + Name: "env-uuid", + Aliases: []string{"e"}, + Usage: "Environment UUID to be used", + }, + &cli.StringFlag{ + Name: "icon", + Aliases: []string{"i"}, + Value: tags.DefaultTagIcon, + Usage: "Fontawesome icon to be used", }, &cli.StringFlag{ Name: "color", Aliases: []string{"c"}, - Value: "", - Usage: "Tag color to be added", + Usage: "HTML color to be used. If not provided it will be randomly generated", }, &cli.StringFlag{ Name: "description, d", Aliases: []string{"d"}, - Usage: "Tag description to be added", + Usage: "Tag description to be used", }, &cli.StringFlag{ - Name: "icon, i", - Aliases: []string{"i"}, - Value: "", - Usage: "Tag icon to be added", + Name: "tag-type", + Aliases: []string{"t", "type"}, + Value: "custom", + Usage: "Tag type to be used. It can be 'env', 'uuid', 'platform', 'localname' and 'custom'", }, }, Action: cliWrapper(addTag), @@ -1551,22 +1556,32 @@ func init() { &cli.StringFlag{ Name: "name", Aliases: []string{"n"}, - Usage: "Tage name to be edited", + Usage: "Tage name to be used", + }, + &cli.StringFlag{ + Name: "env-uuid", + Aliases: []string{"e"}, + Usage: "Environment UUID to be used", + }, + &cli.StringFlag{ + Name: "icon", + Aliases: []string{"i"}, + Usage: "Fontawesome icon to be used", }, &cli.StringFlag{ Name: "color", Aliases: []string{"c"}, - Usage: "Tag color to be edited", + Usage: "HTML color to be used. If not provided it will be randomly generated", }, &cli.StringFlag{ - Name: "description", + Name: "description, d", Aliases: []string{"d"}, - Usage: "Tag description to be edited", + Usage: "Tag description to be used", }, &cli.StringFlag{ - Name: "icon", - Aliases: []string{"i"}, - Usage: "Tag icon to be edited", + Name: "tag-type", + Aliases: []string{"t", "type"}, + Usage: "Tag type to be used. It can be 'env', 'uuid', 'platform', 'localname' and 'custom'", }, }, Action: cliWrapper(editTag), @@ -1581,14 +1596,32 @@ func init() { Aliases: []string{"n"}, Usage: "Tag name to be deleted", }, + &cli.StringFlag{ + Name: "env-uuid", + Aliases: []string{"e"}, + Usage: "Environment UUID to be used", + }, }, Action: cliWrapper(deleteTag), }, { Name: "list", Aliases: []string{"l"}, - Usage: "List all tags", - Action: cliWrapper(listTags), + Usage: "List all tags by environment", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "env-uuid", + Aliases: []string{"e"}, + Usage: "Environment UUID to be used", + }, + }, + Action: cliWrapper(listTagsByEnv), + }, + { + Name: "list-all", + Aliases: []string{"L"}, + Usage: "List all tags in osctrl", + Action: cliWrapper(listAllTags), }, { Name: "show", @@ -1600,6 +1633,11 @@ func init() { Aliases: []string{"n"}, Usage: "Tag name to be displayed", }, + &cli.StringFlag{ + Name: "env-uuid", + Aliases: []string{"e"}, + Usage: "Environment UUID to be used", + }, }, Action: cliWrapper(showTag), }, diff --git a/cli/node.go b/cli/node.go index d160fb41..ad8e5f52 100644 --- a/cli/node.go +++ b/cli/node.go @@ -25,6 +25,7 @@ func nodesToData(nds []nodes.OsqueryNode, header []string) [][]string { return data } +// Helper function to convert a node into the data expected for output func nodeToData(n nodes.OsqueryNode, header []string) [][]string { var data [][]string if header != nil { diff --git a/cli/tag.go b/cli/tag.go index afcfc11c..3aa99520 100644 --- a/cli/tag.go +++ b/cli/tag.go @@ -1,23 +1,314 @@ package main -import "github.com/urfave/cli/v2" +import ( + "encoding/csv" + "encoding/json" + "fmt" + "os" + "strings" + + "github.com/jmpsec/osctrl/tags" + "github.com/olekukonko/tablewriter" + "github.com/urfave/cli/v2" +) + +// Helper function to convert a slice of tags into the data expected for output +func tagsToData(tgs []tags.AdminTag, header []string) [][]string { + var data [][]string + if header != nil { + data = append(data, header) + } + for _, n := range tgs { + data = append(data, tagToData(n, nil)...) + } + return data +} + +// Helper function to convert a tag into the data expected for output +func tagToData(t tags.AdminTag, header []string) [][]string { + var data [][]string + if header != nil { + data = append(data, header) + } + _t := []string{ + t.CreatedAt.String(), + t.Name, + t.Description, + t.Color, + t.Icon, + //t.EnvironmentID, + t.CreatedBy, + stringifyBool(t.AutoTag), + tags.TagTypeDecorator(t.TagType), + } + data = append(data, _t) + return data +} func addTag(c *cli.Context) error { + // Get values from flags + env := c.String("env-uuid") + if env == "" { + fmt.Println("❌ environment is required") + os.Exit(1) + } + name := c.String("name") + if name == "" { + fmt.Println("❌ tag name is required") + os.Exit(1) + } + color := c.String("color") + if color == "" { + color = tags.RandomColor() + } + icon := c.String("icon") + if icon == "" { + icon = tags.DefaultTagIcon + } + description := c.String("description") + tagType := c.String("tag-type") + if dbFlag { + e, err := envs.Get(env) + if err != nil { + return fmt.Errorf("❌ error env get - %s", err) + } + // TODO - Use the correct user + if err := tagsmgr.NewTag(name, description, color, icon, appName, e.ID, false, tags.TagTypeParser(tagType)); err != nil { + return fmt.Errorf("❌ %s", err) + } + } else if apiFlag { + _, err := osctrlAPI.AddTag(env, name, color, icon, description, tags.TagTypeParser(tagType)) + if err != nil { + return fmt.Errorf("❌ %s", err) + } + } + if !silentFlag { + fmt.Printf("✅ tag %s updated successfully\n", name) + } return nil } func deleteTag(c *cli.Context) error { + // Get values from flags + env := c.String("env-uuid") + if env == "" { + fmt.Println("❌ environment is required") + os.Exit(1) + } + name := c.String("name") + if name == "" { + fmt.Println("❌ tag name is required") + os.Exit(1) + } + if dbFlag { + e, err := envs.Get(env) + if err != nil { + return fmt.Errorf("❌ error env get - %s", err) + } + if err := tagsmgr.DeleteGet(name, e.ID); err != nil { + return fmt.Errorf("❌ %s", err) + } + } else if apiFlag { + _, err := osctrlAPI.DeleteTag(env, name) + if err != nil { + return fmt.Errorf("❌ %s", err) + } + } + if !silentFlag { + fmt.Printf("✅ tag %s deleted successfully\n", name) + } return nil } func editTag(c *cli.Context) error { + // Get values from flags + env := c.String("env-uuid") + if env == "" { + fmt.Println("❌ environment is required") + os.Exit(1) + } + name := c.String("name") + if name == "" { + fmt.Println("❌ tag name is required") + os.Exit(1) + } + color := c.String("color") + icon := c.String("icon") + description := c.String("description") + tagType := c.String("tag-type") + if dbFlag { + e, err := envs.Get(env) + if err != nil { + return fmt.Errorf("❌ error env get - %s", err) + } + t, err := tagsmgr.Get(name, e.ID) + if err != nil { + return fmt.Errorf("❌ %s", err) + } + if description != "" && description != t.Description { + if err := tagsmgr.ChangeDescription(&t, description); err != nil { + return fmt.Errorf("❌ %s", err) + } + } + if color != "" && color != t.Color { + if err := tagsmgr.ChangeColor(&t, color); err != nil { + return fmt.Errorf("❌ %s", err) + } + } + if icon != "" && icon != t.Icon { + if err := tagsmgr.ChangeIcon(&t, icon); err != nil { + return fmt.Errorf("❌ %s", err) + } + } + if tagType != "" && tagType != tags.TagTypeDecorator(t.TagType) { + if err := tagsmgr.ChangeTagType(&t, tags.TagTypeParser(tagType)); err != nil { + return fmt.Errorf("❌ %s", err) + } + } + } else if apiFlag { + t, err := osctrlAPI.GetTag(env, name) + if err != nil { + return fmt.Errorf("❌ %s", err) + } + tt := t.TagType + if tagType != "" && strings.ToUpper(tagType) != strings.ToUpper(tags.TagTypeDecorator(t.TagType)) { + tt = tags.TagTypeParser(tagType) + } + _, err = osctrlAPI.EditTag(env, name, color, icon, description, tt) + if err != nil { + return fmt.Errorf("❌ %s", err) + } + } + if !silentFlag { + fmt.Printf("✅ tag %s updated successfully\n", name) + } return nil } func showTag(c *cli.Context) error { + // Get values from flags + env := c.String("env-uuid") + if env == "" { + fmt.Println("❌ environment is required") + os.Exit(1) + } + name := c.String("name") + if name == "" { + fmt.Println("❌ tag name is required") + os.Exit(1) + } + var t tags.AdminTag + if dbFlag { + e, err := envs.Get(env) + if err != nil { + return fmt.Errorf("❌ error env get - %s", err) + } + t, err = tagsmgr.Get(name, e.ID) + if err != nil { + return fmt.Errorf("❌ %s", err) + } + } else if apiFlag { + t, err = osctrlAPI.GetTag(env, name) + if err != nil { + return fmt.Errorf("❌ %s", err) + } + } + fmt.Printf("Tag: %s\n", t.Name) + fmt.Printf("Description: %s\n", t.Description) + fmt.Printf("Color: %s\n", t.Color) + fmt.Printf("Icon: %s\n", t.Icon) + fmt.Printf("Created: %s\n", t.CreatedAt.String()) + fmt.Printf("CreatedBy: %s\n", t.CreatedBy) + fmt.Printf("AutoTag: %s\n", stringifyBool(t.AutoTag)) + fmt.Printf("TagType: %s\n", tags.TagTypeDecorator(t.TagType)) + fmt.Println() + return nil +} + +func helperListTags(tgs []tags.AdminTag) error { + header := []string{ + "Created", + "Name", + "Description", + "Color", + "Icon", + "CreatedBy", + "AutoTag", + "TagType", + } + // Prepare output + if formatFlag == jsonFormat { + jsonRaw, err := json.Marshal(tgs) + if err != nil { + return fmt.Errorf("error marshaling - %s", err) + } + fmt.Println(string(jsonRaw)) + } else if formatFlag == csvFormat { + data := tagsToData(tgs, header) + w := csv.NewWriter(os.Stdout) + if err := w.WriteAll(data); err != nil { + return fmt.Errorf("error writting csv - %s", err) + } + } else if formatFlag == prettyFormat { + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader(header) + if len(tgs) > 0 { + fmt.Printf("Existing tags (%d):\n", len(tgs)) + data := tagsToData(tgs, nil) + table.AppendBulk(data) + } else { + fmt.Println("No tags") + } + table.Render() + } + return nil +} + +func listTagsByEnv(c *cli.Context) error { + // Get values from flags + env := c.String("env-uuid") + if env == "" { + fmt.Println("❌ environment is required") + os.Exit(1) + } + // Retrieve data + var tgs []tags.AdminTag + if dbFlag { + e, err := envs.Get(env) + if err != nil { + return fmt.Errorf("❌ error env get - %s", err) + } + tgs, err = tagsmgr.GetByEnv(e.ID) + if err != nil { + return fmt.Errorf("❌ %s", err) + } + } else if apiFlag { + tgs, err = osctrlAPI.GetTags(env) + if err != nil { + return fmt.Errorf("❌ %s", err) + } + } + if err := helperListTags(tgs); err != nil { + return fmt.Errorf("❌ %s", err) + } return nil } -func listTags(c *cli.Context) error { +func listAllTags(c *cli.Context) error { + var tgs []tags.AdminTag + if dbFlag { + tgs, err = tagsmgr.All() + if err != nil { + return fmt.Errorf("❌ %s", err) + } + } else if apiFlag { + tgs, err = osctrlAPI.GetAllTags() + if err != nil { + return fmt.Errorf("❌ %s", err) + } + } + if err := helperListTags(tgs); err != nil { + return fmt.Errorf("❌ %s", err) + } return nil } diff --git a/tags/tags.go b/tags/tags.go index 947106d2..7d370b1d 100644 --- a/tags/tags.go +++ b/tags/tags.go @@ -26,10 +26,12 @@ const ( TagTypeLocalname uint = 3 // TagTypeCustom as tag type for custom tags TagTypeCustom uint = 4 + // TagTypeUnknown as tag type for unknown tags + TagTypeUnknown uint = 5 // ActionAdd as action to add a tag - ActionAdd string = "add" + ActionAdd string = "add" // ActionEdit as action to edit a tag - ActionEdit string = "edit" + ActionEdit string = "edit" // ActionRemove as action to remove a tag ActionRemove string = "remove" ) diff --git a/tags/utils.go b/tags/utils.go index 439e6a5e..9ec97043 100644 --- a/tags/utils.go +++ b/tags/utils.go @@ -3,9 +3,27 @@ package tags import ( "fmt" "math/rand" + "strings" "time" ) +const ( + // TagTypeEnvironmentStr is the tag type for environment + TagTypeEnvironmentStr = "Environment" + // TagTypeEnvStr is the tag type for shortened environment + TagTypeEnvStr = "Env" + // TagTypeUUIDStr is the tag type for UUID + TagTypeUUIDStr = "UUID" + // TagTypePlatformStr is the tag type for platform + TagTypePlatformStr = "Platform" + // TagTypeLocalnameStr is the tag type for localname + TagTypeLocalnameStr = "Localname" + // TagTypeCustomStr is the tag type for custom + TagTypeCustomStr = "Custom" + // TagTypeUnknownStr is the tag type for unknown + TagTypeUnknownStr = "Unknown" +) + // Helper to generate a random color in hex for HTML func RandomColor() string { r := rand.New(rand.NewSource(time.Now().UnixNano())) @@ -28,17 +46,35 @@ func GetHex(num int) string { // Helper to convert the tag type to a string func TagTypeDecorator(tagType uint) string { switch tagType { - case 0: - return "Environment" - case 1: - return "UUID" - case 2: - return "Platform" - case 3: - return "Localname" - case 4: - return "Custom" + case TagTypeEnv: + return TagTypeEnvironmentStr + case TagTypeUUID: + return TagTypeUUIDStr + case TagTypePlatform: + return TagTypePlatformStr + case TagTypeLocalname: + return TagTypeLocalnameStr + case TagTypeCustom: + return TagTypeCustomStr + default: + return TagTypeUnknownStr + } +} + +// Helper to convert the tag type string to a uint +func TagTypeParser(tagType string) uint { + switch strings.ToUpper(tagType) { + case strings.ToUpper(TagTypeEnvStr): + return TagTypeEnv + case strings.ToUpper(TagTypeUUIDStr): + return TagTypeUUID + case strings.ToUpper(TagTypePlatformStr): + return TagTypePlatform + case strings.ToUpper(TagTypeLocalnameStr): + return TagTypeLocalname + case strings.ToUpper(TagTypeCustomStr): + return TagTypeCustom default: - return "Unknown" + return TagTypeUnknown } } diff --git a/tags/utils_test.go b/tags/utils_test.go index e0fc0e86..55761fd2 100644 --- a/tags/utils_test.go +++ b/tags/utils_test.go @@ -26,3 +26,13 @@ func TestTagTypeDecorator(t *testing.T) { assert.Equal(t, "Custom", TagTypeDecorator(4)) assert.Equal(t, "Unknown", TagTypeDecorator(5)) } + +func TestTagTypeParser(t *testing.T) { + assert.Equal(t, uint(0), TagTypeParser("Env")) + assert.Equal(t, uint(1), TagTypeParser("UUID")) + assert.Equal(t, uint(2), TagTypeParser("Platform")) + assert.Equal(t, uint(3), TagTypeParser("Localname")) + assert.Equal(t, uint(4), TagTypeParser("Custom")) + assert.Equal(t, uint(5), TagTypeParser("Unknown")) + assert.Equal(t, uint(5), TagTypeParser("Invalid")) +}