From e741601ddaf55df38bc6806286824bb11dd1d4da Mon Sep 17 00:00:00 2001 From: Mahsa ghoreishi Date: Wed, 13 Apr 2022 15:57:54 -0400 Subject: [PATCH 1/2] issue 130 remove aliases after deletion of a resource --- cmd/delete.go | 2 ++ external/aliases/aliases.go | 48 +++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/cmd/delete.go b/cmd/delete.go index ed9038a2..63f8b0d7 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -3,6 +3,7 @@ package cmd import ( "context" "fmt" + "github.com/elasticpath/epcc-cli/external/aliases" "github.com/elasticpath/epcc-cli/external/completion" "github.com/elasticpath/epcc-cli/external/httpclient" "github.com/elasticpath/epcc-cli/external/json" @@ -110,5 +111,6 @@ func deleteResource(args []string) (*http.Response, error) { } defer resp.Body.Close() + aliases.DeleteAliasesById(args[len(args)-1], resource.JsonApiType) return resp, nil } diff --git a/external/aliases/aliases.go b/external/aliases/aliases.go index 17fc0eb9..65c59296 100644 --- a/external/aliases/aliases.go +++ b/external/aliases/aliases.go @@ -78,6 +78,54 @@ func SaveAliasesForResources(jsonTxt string) { } +func DeleteAliasesById(id string, jsonApiType string) { + profileDirectory := GetAliasDataDirectory() + filelock.Lock() + defer filelock.Unlock() + + aliasFile := getAliasFileForJsonApiType(profileDirectory, jsonApiType) + data, err := ioutil.ReadFile(aliasFile) + if err != nil { + log.Debugf("Could not read %s, error %s", aliasFile, err) + data = []byte{} + } else { + } + + aliasMap := map[string]string{} + + err = yaml.Unmarshal(data, aliasMap) + if err != nil { + log.Debugf("Could not unmarshall existing file %s, error %s", data, err) + } + + for key, value := range aliasMap { + if value == id { + delete(aliasMap, key) + } + } + + // We will write to a temp file and then rename, to prevent data loss. rename's in the same folder are likely atomic in most settings. + // Although we should probably sync on the file as well, that might be too much overhead, and I was too lazy to rewrite this + // https://github.com/golang/go/issues/20599 + tmpFileName := aliasFile + "." + uuid.New().String() + + marshal, err := yaml.Marshal(aliasMap) + + if err != nil { + log.Warnf("Could not save aliases for %s, error %v", tmpFileName, err) + } + + err = ioutil.WriteFile(tmpFileName, marshal, 0600) + if err != nil { + log.Warnf("Could not save aliases for %s, error %v", tmpFileName, err) + } + + err = os.Rename(tmpFileName, aliasFile) + if err != nil { + log.Warnf("Could not save aliases for %s, error %v", tmpFileName, err) + } +} + // This function saves all the aliases for a specific resource. func saveAliasesForResource(profileDirectory string, jsonApiType string, aliases map[string]string) { filelock.Lock() From 061000f08c06e6f1e8dff9472545f3c85c673c87 Mon Sep 17 00:00:00 2001 From: Mahsa ghoreishi Date: Wed, 13 Apr 2022 16:51:37 -0400 Subject: [PATCH 2/2] fixes --- cmd/delete-all.go | 3 ++ cmd/delete.go | 9 ++-- external/aliases/aliases.go | 99 ++++++++++++------------------------- 3 files changed, 41 insertions(+), 70 deletions(-) diff --git a/cmd/delete-all.go b/cmd/delete-all.go index 34f46e06..a063c619 100644 --- a/cmd/delete-all.go +++ b/cmd/delete-all.go @@ -3,11 +3,13 @@ package cmd import ( json2 "encoding/json" "fmt" + "github.com/elasticpath/epcc-cli/external/aliases" "github.com/elasticpath/epcc-cli/external/completion" "github.com/elasticpath/epcc-cli/external/resources" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "io/ioutil" + "os" "sync" ) @@ -47,6 +49,7 @@ var DeleteAll = &cobra.Command{ return fmt.Errorf("Problem getting page of ids for resource %s", args[0]) } } + os.Remove(aliases.GetAliasFileForJsonApiType(aliases.GetAliasDataDirectory(), resource.JsonApiType)) return nil }, diff --git a/cmd/delete.go b/cmd/delete.go index 63f8b0d7..f85a2497 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -19,8 +19,12 @@ var delete = &cobra.Command{ Short: "Deletes a single resource.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - resp, err := deleteResource(args) + resource, ok := resources.GetResourceByName(args[0]) + if !ok { + return fmt.Errorf("Could not find resource %s", args[0]) + } + resp, err := deleteResource(args) if err != nil { return err } @@ -35,7 +39,7 @@ var delete = &cobra.Command{ if resp.StatusCode >= 400 && resp.StatusCode <= 600 { log.Println(resp.Status) } - + aliases.DeleteAliasesById(args[len(args)-1], resource.JsonApiType) return json.PrintJson(string(body)) }, @@ -111,6 +115,5 @@ func deleteResource(args []string) (*http.Response, error) { } defer resp.Body.Close() - aliases.DeleteAliasesById(args[len(args)-1], resource.JsonApiType) return resp, nil } diff --git a/external/aliases/aliases.go b/external/aliases/aliases.go index 65c59296..23741b23 100644 --- a/external/aliases/aliases.go +++ b/external/aliases/aliases.go @@ -32,7 +32,7 @@ func GetAliasDataDirectory() string { } func GetAliasesForJsonApiType(jsonApiType string) map[string]string { profileDirectory := GetAliasDataDirectory() - aliasFile := getAliasFileForJsonApiType(profileDirectory, jsonApiType) + aliasFile := GetAliasFileForJsonApiType(profileDirectory, jsonApiType) aliasMap := map[string]string{} @@ -71,24 +71,22 @@ func SaveAliasesForResources(jsonTxt string) { log.Tracef("All aliases: %s", results) - profileDirectory := GetAliasDataDirectory() for resourceType, aliases := range results { - saveAliasesForResource(profileDirectory, resourceType, aliases) + saveAliasesForResource(resourceType, aliases) } } -func DeleteAliasesById(id string, jsonApiType string) { +func modifyAliases(jsonApiType string, fn func(map[string]string)) map[string]string { profileDirectory := GetAliasDataDirectory() filelock.Lock() defer filelock.Unlock() - aliasFile := getAliasFileForJsonApiType(profileDirectory, jsonApiType) + aliasFile := GetAliasFileForJsonApiType(profileDirectory, jsonApiType) data, err := ioutil.ReadFile(aliasFile) if err != nil { log.Debugf("Could not read %s, error %s", aliasFile, err) data = []byte{} - } else { } aliasMap := map[string]string{} @@ -97,20 +95,13 @@ func DeleteAliasesById(id string, jsonApiType string) { if err != nil { log.Debugf("Could not unmarshall existing file %s, error %s", data, err) } - - for key, value := range aliasMap { - if value == id { - delete(aliasMap, key) - } - } - + fn(aliasMap) // We will write to a temp file and then rename, to prevent data loss. rename's in the same folder are likely atomic in most settings. // Although we should probably sync on the file as well, that might be too much overhead, and I was too lazy to rewrite this // https://github.com/golang/go/issues/20599 tmpFileName := aliasFile + "." + uuid.New().String() marshal, err := yaml.Marshal(aliasMap) - if err != nil { log.Warnf("Could not save aliases for %s, error %v", tmpFileName, err) } @@ -124,72 +115,46 @@ func DeleteAliasesById(id string, jsonApiType string) { if err != nil { log.Warnf("Could not save aliases for %s, error %v", tmpFileName, err) } + return aliasMap } - -// This function saves all the aliases for a specific resource. -func saveAliasesForResource(profileDirectory string, jsonApiType string, aliases map[string]string) { - filelock.Lock() - defer filelock.Unlock() - - aliasFile := getAliasFileForJsonApiType(profileDirectory, jsonApiType) - data, err := ioutil.ReadFile(aliasFile) - if err != nil { - log.Debugf("Could not read %s, error %s", aliasFile, err) - data = []byte{} - } else { - } - - aliasMap := map[string]string{} - - err = yaml.Unmarshal(data, aliasMap) - if err != nil { - log.Debugf("Could not unmarshall existing file %s, error %s", data, err) - } - - for key, value := range aliases { - key0 := strings.Split(key, "=")[0] - for oldKey, oldValue := range aliasMap { - oldKey0 := strings.Split(oldKey, "=")[0] - oldKey1 := strings.Split(oldKey, "=")[1] - if oldValue == value && oldKey0 == key0 { - delete(aliasMap, oldKey0+"="+oldKey1) +func DeleteAliasesById(id string, jsonApiType string) { + modifyAliases(jsonApiType, func(m map[string]string) { + for key, value := range m { + if value == id { + delete(m, key) } } - } - - for key, value := range aliases { - aliasMap[key] = value - } - - // We will write to a temp file and then rename, to prevent data loss. rename's in the same folder are likely atomic in most settings. - // Although we should probably sync on the file as well, that might be too much overhead, and I was too lazy to rewrite this - // https://github.com/golang/go/issues/20599 - tmpFileName := aliasFile + "." + uuid.New().String() - - marshal, err := yaml.Marshal(aliasMap) + }, + ) - if err != nil { - log.Warnf("Could not save aliases for %s, error %v", tmpFileName, err) - } +} - err = ioutil.WriteFile(tmpFileName, marshal, 0600) - if err != nil { - log.Warnf("Could not save aliases for %s, error %v", tmpFileName, err) - } +// This function saves all the aliases for a specific resource. +func saveAliasesForResource(jsonApiType string, aliases map[string]string) { + modifyAliases(jsonApiType, func(aliasMap map[string]string) { + for key, value := range aliases { + key0 := strings.Split(key, "=")[0] + for oldKey, oldValue := range aliasMap { + oldKey0 := strings.Split(oldKey, "=")[0] + oldKey1 := strings.Split(oldKey, "=")[1] + if oldValue == value && oldKey0 == key0 { + delete(aliasMap, oldKey0+"="+oldKey1) + } + } + } - err = os.Rename(tmpFileName, aliasFile) - if err != nil { - log.Warnf("Could not save aliases for %s, error %v", tmpFileName, err) - } + for key, value := range aliases { + aliasMap[key] = value + } + }) } -func getAliasFileForJsonApiType(profileDirectory string, resourceType string) string { +func GetAliasFileForJsonApiType(profileDirectory string, resourceType string) string { aliasFile := fmt.Sprintf("%s/aliases_%s.yml", profileDirectory, resourceType) return aliasFile } func visitResources(data map[string]interface{}, prefix string, results map[string]map[string]string) { - if typeObj, typeKeyExists := data["type"]; typeKeyExists { if idObj, idKeyExists := data["id"]; idKeyExists { if typeKeyValue, typeKeyIsString := typeObj.(string); typeKeyIsString {