forked from argoproj/argo-cd
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support --inline flag in 'argocd admin app/proj generate-spec' …
…commands (argoproj#6804) Signed-off-by: Alexander Matyushentsev <[email protected]>
- Loading branch information
Alexander Matyushentsev
authored
Jul 26, 2021
1 parent
75a5f79
commit fb357de
Showing
9 changed files
with
166 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package admin | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"os" | ||
|
||
"github.com/argoproj/gitops-engine/pkg/utils/kube" | ||
"github.com/ghodss/yaml" | ||
v1 "k8s.io/api/core/v1" | ||
|
||
ioutil "github.com/argoproj/argo-cd/v2/util/io" | ||
) | ||
|
||
func getOutWriter(inline bool, filePath string) (io.Writer, io.Closer, error) { | ||
if !inline { | ||
return os.Stdout, ioutil.NopCloser, nil | ||
} | ||
|
||
if filePath == "" { | ||
return nil, nil, errors.New("The file path must be specified using flag '--file'") | ||
} | ||
|
||
err := os.Rename(filePath, fmt.Sprintf("%s.back", filePath)) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
fileOut, err := os.Create(filePath) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
return fileOut, fileOut, nil | ||
} | ||
|
||
// PrintResources prints a single resource in YAML or JSON format to stdout according to the output format | ||
func PrintResources(output string, out io.Writer, resources ...interface{}) error { | ||
for i, resource := range resources { | ||
filteredResource, err := omitFields(resource) | ||
if err != nil { | ||
return err | ||
} | ||
resources[i] = filteredResource | ||
} | ||
var obj interface{} = resources | ||
if len(resources) == 1 { | ||
obj = resources[0] | ||
} | ||
|
||
switch output { | ||
case "json": | ||
jsonBytes, err := json.MarshalIndent(obj, "", " ") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, _ = fmt.Fprintln(out, string(jsonBytes)) | ||
case "yaml": | ||
yamlBytes, err := yaml.Marshal(obj) | ||
if err != nil { | ||
return err | ||
} | ||
// marshaled YAML already ends with the new line character | ||
_, _ = fmt.Fprint(out, string(yamlBytes)) | ||
default: | ||
return fmt.Errorf("unknown output format: %s", output) | ||
} | ||
return nil | ||
} | ||
|
||
// omit fields such as status, creationTimestamp and metadata.namespace in k8s objects | ||
func omitFields(resource interface{}) (interface{}, error) { | ||
jsonBytes, err := json.Marshal(resource) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
toMap := make(map[string]interface{}) | ||
err = json.Unmarshal([]byte(string(jsonBytes)), &toMap) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
delete(toMap, "status") | ||
if v, ok := toMap["metadata"]; ok { | ||
if metadata, ok := v.(map[string]interface{}); ok { | ||
delete(metadata, "creationTimestamp") | ||
delete(metadata, "namespace") | ||
} | ||
} | ||
return toMap, nil | ||
} | ||
|
||
// ConvertSecretData converts kubernetes secret's data to stringData | ||
func ConvertSecretData(secret *v1.Secret) { | ||
secret.Kind = kube.SecretKind | ||
secret.APIVersion = "v1" | ||
secret.StringData = map[string]string{} | ||
for k, v := range secret.Data { | ||
secret.StringData[k] = string(v) | ||
} | ||
secret.Data = map[string][]byte{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package admin | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"testing" | ||
|
||
"github.com/argoproj/argo-cd/v2/util/io" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestGetOutWriter_InlineOff(t *testing.T) { | ||
out, closer, err := getOutWriter(false, "") | ||
require.NoError(t, err) | ||
defer io.Close(closer) | ||
|
||
assert.Equal(t, os.Stdout, out) | ||
} | ||
|
||
func TestGetOutWriter_InlineOn(t *testing.T) { | ||
tmpFile, err := ioutil.TempFile("", "") | ||
require.NoError(t, err) | ||
defer func() { | ||
_ = os.Remove(tmpFile.Name()) | ||
_ = os.Remove(fmt.Sprintf("%s.back", tmpFile.Name())) | ||
}() | ||
|
||
out, closer, err := getOutWriter(true, tmpFile.Name()) | ||
require.NoError(t, err) | ||
defer io.Close(closer) | ||
|
||
assert.Equal(t, tmpFile.Name(), out.(*os.File).Name()) | ||
_, err = os.Stat(fmt.Sprintf("%s.back", tmpFile.Name())) | ||
assert.NoError(t, err, "Back file must be created") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,85 +1,6 @@ | ||
package util | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/ghodss/yaml" | ||
v1 "k8s.io/api/core/v1" | ||
|
||
"github.com/argoproj/gitops-engine/pkg/utils/kube" | ||
) | ||
|
||
var ( | ||
LogFormat string | ||
LogLevel string | ||
) | ||
|
||
// PrintResource prints a single resource in YAML or JSON format to stdout according to the output format | ||
func PrintResources(resources []interface{}, output string) error { | ||
for i, resource := range resources { | ||
filteredResource, err := omitFields(resource) | ||
if err != nil { | ||
return err | ||
} | ||
resources[i] = filteredResource | ||
} | ||
var obj interface{} = resources | ||
if len(resources) == 1 { | ||
obj = resources[0] | ||
} | ||
|
||
switch output { | ||
case "json": | ||
jsonBytes, err := json.MarshalIndent(obj, "", " ") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println(string(jsonBytes)) | ||
case "yaml": | ||
yamlBytes, err := yaml.Marshal(obj) | ||
if err != nil { | ||
return err | ||
} | ||
// marshaled YAML already ends with the new line character | ||
fmt.Print(string(yamlBytes)) | ||
default: | ||
return fmt.Errorf("unknown output format: %s", output) | ||
} | ||
return nil | ||
} | ||
|
||
// omit fields such as status, creationTimestamp and metadata.namespace in k8s objects | ||
func omitFields(resource interface{}) (interface{}, error) { | ||
jsonBytes, err := json.Marshal(resource) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
toMap := make(map[string]interface{}) | ||
err = json.Unmarshal([]byte(string(jsonBytes)), &toMap) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
delete(toMap, "status") | ||
if v, ok := toMap["metadata"]; ok { | ||
if metadata, ok := v.(map[string]interface{}); ok { | ||
delete(metadata, "creationTimestamp") | ||
delete(metadata, "namespace") | ||
} | ||
} | ||
return toMap, nil | ||
} | ||
|
||
// ConvertSecretData converts kubernetes secret's data to stringData | ||
func ConvertSecretData(secret *v1.Secret) { | ||
secret.Kind = kube.SecretKind | ||
secret.APIVersion = "v1" | ||
secret.StringData = map[string]string{} | ||
for k, v := range secret.Data { | ||
secret.StringData[k] = string(v) | ||
} | ||
secret.Data = map[string][]byte{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters