github.com/argoproj/argo-cd/v2@v2.10.5/util/kube/kube_test.go (about)

     1  package kube
     2  
     3  import (
     4  	"encoding/json"
     5  	"log"
     6  	"os"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	apiv1 "k8s.io/api/core/v1"
    11  	extv1beta1 "k8s.io/api/extensions/v1beta1"
    12  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    13  	"sigs.k8s.io/yaml"
    14  
    15  	"github.com/argoproj/argo-cd/v2/common"
    16  )
    17  
    18  const depWithoutSelector = `
    19  apiVersion: extensions/v1beta1
    20  kind: Deployment
    21  metadata:
    22    name: nginx-deployment
    23  spec:
    24    template:
    25      metadata:
    26        labels:
    27          app: nginx
    28      spec:
    29        containers:
    30        - image: nginx:1.7.9
    31          name: nginx
    32          ports:
    33          - containerPort: 80
    34  `
    35  
    36  const depWithSelector = `
    37  apiVersion: extensions/v1beta1
    38  kind: Deployment
    39  metadata:
    40    name: nginx-deployment
    41  spec:
    42    selector:
    43      matchLabels:
    44        app: nginx
    45    template:
    46      metadata:
    47        labels:
    48          app: nginx
    49      spec:
    50        containers:
    51        - image: nginx:1.7.9
    52          name: nginx
    53          ports:
    54          - containerPort: 80
    55  `
    56  
    57  func TestSetLabels(t *testing.T) {
    58  	for _, yamlStr := range []string{depWithoutSelector, depWithSelector} {
    59  		var obj unstructured.Unstructured
    60  		err := yaml.Unmarshal([]byte(yamlStr), &obj)
    61  		assert.Nil(t, err)
    62  
    63  		err = SetAppInstanceLabel(&obj, common.LabelKeyAppInstance, "my-app")
    64  		assert.Nil(t, err)
    65  
    66  		manifestBytes, err := json.MarshalIndent(obj.Object, "", "  ")
    67  		assert.Nil(t, err)
    68  		log.Println(string(manifestBytes))
    69  
    70  		var depV1Beta1 extv1beta1.Deployment
    71  		err = json.Unmarshal(manifestBytes, &depV1Beta1)
    72  		assert.Nil(t, err)
    73  
    74  		// the following makes sure we are not falling into legacy code which injects labels
    75  		if yamlStr == depWithoutSelector {
    76  			assert.Nil(t, depV1Beta1.Spec.Selector)
    77  		} else if yamlStr == depWithSelector {
    78  			assert.Equal(t, 1, len(depV1Beta1.Spec.Selector.MatchLabels))
    79  			assert.Equal(t, "nginx", depV1Beta1.Spec.Selector.MatchLabels["app"])
    80  		}
    81  		assert.Equal(t, 1, len(depV1Beta1.Spec.Template.Labels))
    82  		assert.Equal(t, "nginx", depV1Beta1.Spec.Template.Labels["app"])
    83  	}
    84  }
    85  
    86  func TestSetLegacyLabels(t *testing.T) {
    87  	for _, yamlStr := range []string{depWithoutSelector, depWithSelector} {
    88  		var obj unstructured.Unstructured
    89  		err := yaml.Unmarshal([]byte(yamlStr), &obj)
    90  		assert.Nil(t, err)
    91  
    92  		err = SetAppInstanceLabel(&obj, common.LabelKeyLegacyApplicationName, "my-app")
    93  		assert.Nil(t, err)
    94  
    95  		manifestBytes, err := json.MarshalIndent(obj.Object, "", "  ")
    96  		assert.Nil(t, err)
    97  		log.Println(string(manifestBytes))
    98  
    99  		var depV1Beta1 extv1beta1.Deployment
   100  		err = json.Unmarshal(manifestBytes, &depV1Beta1)
   101  		assert.Nil(t, err)
   102  		assert.Equal(t, 1, len(depV1Beta1.Spec.Selector.MatchLabels))
   103  		assert.Equal(t, "nginx", depV1Beta1.Spec.Selector.MatchLabels["app"])
   104  		assert.Equal(t, 2, len(depV1Beta1.Spec.Template.Labels))
   105  		assert.Equal(t, "nginx", depV1Beta1.Spec.Template.Labels["app"])
   106  		assert.Equal(t, "my-app", depV1Beta1.Spec.Template.Labels[common.LabelKeyLegacyApplicationName])
   107  	}
   108  }
   109  
   110  func TestSetLegacyJobLabel(t *testing.T) {
   111  	yamlBytes, err := os.ReadFile("testdata/job.yaml")
   112  	assert.Nil(t, err)
   113  	var obj unstructured.Unstructured
   114  	err = yaml.Unmarshal(yamlBytes, &obj)
   115  	assert.Nil(t, err)
   116  	err = SetAppInstanceLabel(&obj, common.LabelKeyLegacyApplicationName, "my-app")
   117  	assert.Nil(t, err)
   118  
   119  	manifestBytes, err := json.MarshalIndent(obj.Object, "", "  ")
   120  	assert.Nil(t, err)
   121  	log.Println(string(manifestBytes))
   122  
   123  	job := unstructured.Unstructured{}
   124  	err = json.Unmarshal(manifestBytes, &job)
   125  	assert.Nil(t, err)
   126  
   127  	labels := job.GetLabels()
   128  	assert.Equal(t, "my-app", labels[common.LabelKeyLegacyApplicationName])
   129  
   130  	templateLabels, ok, err := unstructured.NestedMap(job.UnstructuredContent(), "spec", "template", "metadata", "labels")
   131  	assert.True(t, ok)
   132  	assert.Nil(t, err)
   133  	assert.Equal(t, "my-app", templateLabels[common.LabelKeyLegacyApplicationName])
   134  }
   135  
   136  func TestSetSvcLabel(t *testing.T) {
   137  	yamlBytes, err := os.ReadFile("testdata/svc.yaml")
   138  	assert.Nil(t, err)
   139  	var obj unstructured.Unstructured
   140  	err = yaml.Unmarshal(yamlBytes, &obj)
   141  	assert.Nil(t, err)
   142  	err = SetAppInstanceLabel(&obj, common.LabelKeyAppInstance, "my-app")
   143  	assert.Nil(t, err)
   144  
   145  	manifestBytes, err := json.MarshalIndent(obj.Object, "", "  ")
   146  	assert.Nil(t, err)
   147  	log.Println(string(manifestBytes))
   148  
   149  	var s apiv1.Service
   150  	err = json.Unmarshal(manifestBytes, &s)
   151  	assert.Nil(t, err)
   152  
   153  	log.Println(s.Name)
   154  	log.Println(s.ObjectMeta)
   155  	assert.Equal(t, "my-app", s.ObjectMeta.Labels[common.LabelKeyAppInstance])
   156  }
   157  
   158  func TestIsValidResourceName(t *testing.T) {
   159  	assert.True(t, IsValidResourceName("guestbook-ui"))
   160  	assert.True(t, IsValidResourceName("guestbook-ui1"))
   161  	assert.False(t, IsValidResourceName("Guestbook-ui"))
   162  	assert.False(t, IsValidResourceName("-guestbook-ui"))
   163  }
   164  
   165  func TestSetAppInstanceAnnotation(t *testing.T) {
   166  	yamlBytes, err := os.ReadFile("testdata/svc.yaml")
   167  	assert.Nil(t, err)
   168  	var obj unstructured.Unstructured
   169  	err = yaml.Unmarshal(yamlBytes, &obj)
   170  	assert.Nil(t, err)
   171  	err = SetAppInstanceAnnotation(&obj, common.LabelKeyAppInstance, "my-app")
   172  	assert.Nil(t, err)
   173  
   174  	manifestBytes, err := json.MarshalIndent(obj.Object, "", "  ")
   175  	assert.Nil(t, err)
   176  	log.Println(string(manifestBytes))
   177  
   178  	var s apiv1.Service
   179  	err = json.Unmarshal(manifestBytes, &s)
   180  	assert.Nil(t, err)
   181  
   182  	log.Println(s.Name)
   183  	log.Println(s.ObjectMeta)
   184  	assert.Equal(t, "my-app", s.ObjectMeta.Annotations[common.LabelKeyAppInstance])
   185  }
   186  
   187  func TestSetAppInstanceAnnotationWithInvalidData(t *testing.T) {
   188  	yamlBytes, err := os.ReadFile("testdata/svc-with-invalid-data.yaml")
   189  	assert.Nil(t, err)
   190  	var obj unstructured.Unstructured
   191  	err = yaml.Unmarshal(yamlBytes, &obj)
   192  	assert.Nil(t, err)
   193  	err = SetAppInstanceAnnotation(&obj, common.LabelKeyAppInstance, "my-app")
   194  	assert.Error(t, err)
   195  	assert.Equal(t, "failed to get annotations from target object /v1, Kind=Service /my-service: .metadata.annotations accessor error: contains non-string key in the map: <nil> is of the type <nil>, expected string", err.Error())
   196  }
   197  
   198  func TestGetAppInstanceAnnotation(t *testing.T) {
   199  	yamlBytes, err := os.ReadFile("testdata/svc.yaml")
   200  	assert.Nil(t, err)
   201  	var obj unstructured.Unstructured
   202  	err = yaml.Unmarshal(yamlBytes, &obj)
   203  	assert.Nil(t, err)
   204  	err = SetAppInstanceAnnotation(&obj, common.LabelKeyAppInstance, "my-app")
   205  	assert.Nil(t, err)
   206  
   207  	annotation, err := GetAppInstanceAnnotation(&obj, common.LabelKeyAppInstance)
   208  	assert.Nil(t, err)
   209  	assert.Equal(t, "my-app", annotation)
   210  }
   211  
   212  func TestGetAppInstanceAnnotationWithInvalidData(t *testing.T) {
   213  	yamlBytes, err := os.ReadFile("testdata/svc-with-invalid-data.yaml")
   214  	assert.Nil(t, err)
   215  	var obj unstructured.Unstructured
   216  	err = yaml.Unmarshal(yamlBytes, &obj)
   217  	assert.Nil(t, err)
   218  
   219  	_, err = GetAppInstanceAnnotation(&obj, "valid-annotation")
   220  	assert.Error(t, err)
   221  	assert.Equal(t, "failed to get annotations from target object /v1, Kind=Service /my-service: .metadata.annotations accessor error: contains non-string key in the map: <nil> is of the type <nil>, expected string", err.Error())
   222  }
   223  
   224  func TestGetAppInstanceLabel(t *testing.T) {
   225  	yamlBytes, err := os.ReadFile("testdata/svc.yaml")
   226  	assert.Nil(t, err)
   227  	var obj unstructured.Unstructured
   228  	err = yaml.Unmarshal(yamlBytes, &obj)
   229  	assert.Nil(t, err)
   230  	err = SetAppInstanceLabel(&obj, common.LabelKeyAppInstance, "my-app")
   231  	assert.Nil(t, err)
   232  	label, err := GetAppInstanceLabel(&obj, common.LabelKeyAppInstance)
   233  	assert.Nil(t, err)
   234  	assert.Equal(t, "my-app", label)
   235  }
   236  
   237  func TestGetAppInstanceLabelWithInvalidData(t *testing.T) {
   238  	yamlBytes, err := os.ReadFile("testdata/svc-with-invalid-data.yaml")
   239  	assert.Nil(t, err)
   240  	var obj unstructured.Unstructured
   241  	err = yaml.Unmarshal(yamlBytes, &obj)
   242  	assert.Nil(t, err)
   243  	_, err = GetAppInstanceLabel(&obj, "valid-label")
   244  	assert.Error(t, err)
   245  	assert.Equal(t, "failed to get labels for /v1, Kind=Service /my-service: .metadata.labels accessor error: contains non-string key in the map: <nil> is of the type <nil>, expected string", err.Error())
   246  }
   247  
   248  func TestRemoveLabel(t *testing.T) {
   249  	yamlBytes, err := os.ReadFile("testdata/svc.yaml")
   250  	assert.Nil(t, err)
   251  	var obj unstructured.Unstructured
   252  	err = yaml.Unmarshal(yamlBytes, &obj)
   253  	assert.Nil(t, err)
   254  	obj.SetLabels(map[string]string{"test": "value"})
   255  
   256  	err = RemoveLabel(&obj, "test")
   257  	assert.Nil(t, err)
   258  
   259  	assert.Nil(t, obj.GetLabels())
   260  }
   261  
   262  func TestRemoveLabelWithInvalidData(t *testing.T) {
   263  	yamlBytes, err := os.ReadFile("testdata/svc-with-invalid-data.yaml")
   264  	assert.Nil(t, err)
   265  	var obj unstructured.Unstructured
   266  	err = yaml.Unmarshal(yamlBytes, &obj)
   267  	assert.Nil(t, err)
   268  
   269  	err = RemoveLabel(&obj, "valid-label")
   270  	assert.Error(t, err)
   271  	assert.Equal(t, "failed to get labels for /v1, Kind=Service /my-service: .metadata.labels accessor error: contains non-string key in the map: <nil> is of the type <nil>, expected string", err.Error())
   272  }