mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-05 04:55:22 +00:00
RM support for Escaped bool, float, null (#7118)
* RM support for Escaped bool, float, null Signed-off-by: Anshul Ahuja <anshul.ahu@gmail.com> * fix ci Signed-off-by: Anshul Ahuja <anshul.ahu@gmail.com> --------- Signed-off-by: Anshul Ahuja <anshul.ahu@gmail.com>
This commit is contained in:
@@ -19,30 +19,37 @@ type JSONPatch struct {
|
||||
}
|
||||
|
||||
func (p *JSONPatch) ToString() string {
|
||||
if addQuotes(p.Value) {
|
||||
if addQuotes(&p.Value) {
|
||||
return fmt.Sprintf(`{"op": "%s", "from": "%s", "path": "%s", "value": "%s"}`, p.Operation, p.From, p.Path, p.Value)
|
||||
}
|
||||
return fmt.Sprintf(`{"op": "%s", "from": "%s", "path": "%s", "value": %s}`, p.Operation, p.From, p.Path, p.Value)
|
||||
}
|
||||
|
||||
func addQuotes(value string) bool {
|
||||
if value == "" {
|
||||
func addQuotes(value *string) bool {
|
||||
if *value == "" {
|
||||
return true
|
||||
}
|
||||
// if value is escaped, remove escape and add quotes
|
||||
// this is useful for scenarios where boolean, null and numbers are required to be set as string.
|
||||
if strings.HasPrefix(*value, "\"") && strings.HasSuffix(*value, "\"") {
|
||||
*value = strings.TrimPrefix(*value, "\"")
|
||||
*value = strings.TrimSuffix(*value, "\"")
|
||||
return true
|
||||
}
|
||||
// if value is null, then don't add quotes
|
||||
if value == "null" {
|
||||
if *value == "null" {
|
||||
return false
|
||||
}
|
||||
// if value is a boolean, then don't add quotes
|
||||
if _, err := strconv.ParseBool(value); err == nil {
|
||||
if strings.ToLower(*value) == "true" || strings.ToLower(*value) == "false" {
|
||||
return false
|
||||
}
|
||||
// if value is a json object or array, then don't add quotes.
|
||||
if strings.HasPrefix(value, "{") || strings.HasPrefix(value, "[") {
|
||||
if strings.HasPrefix(*value, "{") || strings.HasPrefix(*value, "[") {
|
||||
return false
|
||||
}
|
||||
// if value is a number, then don't add quotes
|
||||
if _, err := strconv.ParseFloat(value, 64); err == nil {
|
||||
if _, err := strconv.ParseFloat(*value, 64); err == nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -256,6 +256,64 @@ func TestGetResourceModifiersFromConfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
cm9 := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-configmap",
|
||||
Namespace: "test-namespace",
|
||||
},
|
||||
Data: map[string]string{
|
||||
"sub.yml": "version: v1\nresourceModifierRules:\n- conditions:\n groupResource: deployments.apps\n resourceNameRegex: \"^test-.*$\"\n namespaces:\n - bar\n - foo\n patches:\n - operation: replace\n path: \"/value/bool\"\n value: \"\\\"true\\\"\"\n\n\n",
|
||||
},
|
||||
}
|
||||
|
||||
rules9 := &ResourceModifiers{
|
||||
Version: "v1",
|
||||
ResourceModifierRules: []ResourceModifierRule{
|
||||
{
|
||||
Conditions: Conditions{
|
||||
GroupResource: "deployments.apps",
|
||||
ResourceNameRegex: "^test-.*$",
|
||||
Namespaces: []string{"bar", "foo"},
|
||||
},
|
||||
Patches: []JSONPatch{
|
||||
{
|
||||
Operation: "replace",
|
||||
Path: "/value/bool",
|
||||
Value: `"true"`,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
cm10 := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-configmap",
|
||||
Namespace: "test-namespace",
|
||||
},
|
||||
Data: map[string]string{
|
||||
"sub.yml": "version: v1\nresourceModifierRules:\n- conditions:\n groupResource: deployments.apps\n resourceNameRegex: \"^test-.*$\"\n namespaces:\n - bar\n - foo\n patches:\n - operation: replace\n path: \"/value/bool\"\n value: \"true\"\n\n\n",
|
||||
},
|
||||
}
|
||||
|
||||
rules10 := &ResourceModifiers{
|
||||
Version: "v1",
|
||||
ResourceModifierRules: []ResourceModifierRule{
|
||||
{
|
||||
Conditions: Conditions{
|
||||
GroupResource: "deployments.apps",
|
||||
ResourceNameRegex: "^test-.*$",
|
||||
Namespaces: []string{"bar", "foo"},
|
||||
},
|
||||
Patches: []JSONPatch{
|
||||
{
|
||||
Operation: "replace",
|
||||
Path: "/value/bool",
|
||||
Value: "true",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type args struct {
|
||||
cm *v1.ConfigMap
|
||||
@@ -338,6 +396,22 @@ func TestGetResourceModifiersFromConfig(t *testing.T) {
|
||||
want: rules8,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "bool value as string",
|
||||
args: args{
|
||||
cm: cm9,
|
||||
},
|
||||
want: rules9,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "bool value as bool",
|
||||
args: args{
|
||||
cm: cm10,
|
||||
},
|
||||
want: rules10,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -480,7 +554,24 @@ func TestResourceModifiers_ApplyResourceModifierRules(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cmTrue := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"data": map[string]interface{}{
|
||||
"test": "true",
|
||||
},
|
||||
},
|
||||
}
|
||||
cmFalse := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"data": map[string]interface{}{
|
||||
"test": "false",
|
||||
},
|
||||
},
|
||||
}
|
||||
type fields struct {
|
||||
Version string
|
||||
ResourceModifierRules []ResourceModifierRule
|
||||
@@ -496,6 +587,33 @@ func TestResourceModifiers_ApplyResourceModifierRules(t *testing.T) {
|
||||
wantErr bool
|
||||
wantObj *unstructured.Unstructured
|
||||
}{
|
||||
{
|
||||
name: "configmap true false string",
|
||||
fields: fields{
|
||||
Version: "v1",
|
||||
ResourceModifierRules: []ResourceModifierRule{
|
||||
{
|
||||
Conditions: Conditions{
|
||||
GroupResource: "configmaps",
|
||||
ResourceNameRegex: ".*",
|
||||
},
|
||||
Patches: []JSONPatch{
|
||||
{
|
||||
Operation: "replace",
|
||||
Path: "/data/test",
|
||||
Value: `"false"`,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
obj: cmTrue.DeepCopy(),
|
||||
groupResource: "configmaps",
|
||||
},
|
||||
wantErr: false,
|
||||
wantObj: cmFalse.DeepCopy(),
|
||||
},
|
||||
{
|
||||
name: "Invalid Regex throws error",
|
||||
fields: fields{
|
||||
|
||||
Reference in New Issue
Block a user