github.com/argoproj/argo-cd@v1.8.7/controller/cache/info_test.go (about)

     1  package cache
     2  
     3  import (
     4  	"sort"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/argoproj/gitops-engine/pkg/utils/kube"
     9  	"github.com/argoproj/pkg/errors"
    10  	"github.com/ghodss/yaml"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	v1 "k8s.io/api/core/v1"
    14  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    15  
    16  	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
    17  )
    18  
    19  func strToUnstructured(jsonStr string) *unstructured.Unstructured {
    20  	obj := make(map[string]interface{})
    21  	err := yaml.Unmarshal([]byte(jsonStr), &obj)
    22  	errors.CheckError(err)
    23  	return &unstructured.Unstructured{Object: obj}
    24  }
    25  
    26  var (
    27  	testService = strToUnstructured(`
    28    apiVersion: v1
    29    kind: Service
    30    metadata:
    31      name: helm-guestbook
    32      namespace: default
    33      resourceVersion: "123"
    34      uid: "4"
    35    spec:
    36      selector:
    37        app: guestbook
    38      type: LoadBalancer
    39    status:
    40      loadBalancer:
    41        ingress:
    42        - hostname: localhost`)
    43  
    44  	testIngress = strToUnstructured(`
    45    apiVersion: extensions/v1beta1
    46    kind: Ingress
    47    metadata:
    48      name: helm-guestbook
    49      namespace: default
    50      uid: "4"
    51    spec:
    52      backend:
    53        serviceName: not-found-service
    54        servicePort: 443
    55      rules:
    56      - host: helm-guestbook.com
    57        http:
    58          paths:
    59          - backend:
    60              serviceName: helm-guestbook
    61              servicePort: 443
    62            path: /
    63          - backend:
    64              serviceName: helm-guestbook
    65              servicePort: https
    66            path: /
    67      tls:
    68      - host: helm-guestbook.com
    69      secretName: my-tls-secret
    70    status:
    71      loadBalancer:
    72        ingress:
    73        - ip: 107.178.210.11`)
    74  
    75  	testIngressWildCardPath = strToUnstructured(`
    76    apiVersion: extensions/v1beta1
    77    kind: Ingress
    78    metadata:
    79      name: helm-guestbook
    80      namespace: default
    81      uid: "4"
    82    spec:
    83      backend:
    84        serviceName: not-found-service
    85        servicePort: 443
    86      rules:
    87      - host: helm-guestbook.com
    88        http:
    89          paths:
    90          - backend:
    91              serviceName: helm-guestbook
    92              servicePort: 443
    93            path: /*
    94          - backend:
    95              serviceName: helm-guestbook
    96              servicePort: https
    97            path: /*
    98      tls:
    99      - host: helm-guestbook.com
   100      secretName: my-tls-secret
   101    status:
   102      loadBalancer:
   103        ingress:
   104        - ip: 107.178.210.11`)
   105  
   106  	testIngressWithoutTls = strToUnstructured(`
   107    apiVersion: extensions/v1beta1
   108    kind: Ingress
   109    metadata:
   110      name: helm-guestbook
   111      namespace: default
   112      uid: "4"
   113    spec:
   114      backend:
   115        serviceName: not-found-service
   116        servicePort: 443
   117      rules:
   118      - host: helm-guestbook.com
   119        http:
   120          paths:
   121          - backend:
   122              serviceName: helm-guestbook
   123              servicePort: 443
   124            path: /
   125          - backend:
   126              serviceName: helm-guestbook
   127              servicePort: https
   128            path: /
   129    status:
   130      loadBalancer:
   131        ingress:
   132        - ip: 107.178.210.11`)
   133  
   134  	testIstioVirtualService = strToUnstructured(`
   135  apiVersion: networking.istio.io/v1alpha3
   136  kind: VirtualService
   137  metadata:
   138    name: hello-world
   139    namespace: demo
   140  spec:
   141    http:
   142      - match:
   143          - uri:
   144              prefix: "/1"
   145        route:
   146          - destination:
   147              host: service_full.demo.svc.cluster.local
   148          - destination:
   149              host: service_namespace.namespace
   150      - match:
   151          - uri:
   152              prefix: "/2"
   153        route:
   154          - destination:
   155              host: service
   156  `)
   157  )
   158  
   159  func TestGetPodInfo(t *testing.T) {
   160  	pod := strToUnstructured(`
   161    apiVersion: v1
   162    kind: Pod
   163    metadata:
   164      name: helm-guestbook-pod
   165      namespace: default
   166      ownerReferences:
   167      - apiVersion: extensions/v1beta1
   168        kind: ReplicaSet
   169        name: helm-guestbook-rs
   170      resourceVersion: "123"
   171      labels:
   172        app: guestbook
   173    spec:
   174      containers:
   175      - image: bar`)
   176  
   177  	info := &ResourceInfo{}
   178  	populateNodeInfo(pod, info)
   179  	assert.Equal(t, []v1alpha1.InfoItem{{Name: "Containers", Value: "0/1"}}, info.Info)
   180  	assert.Equal(t, []string{"bar"}, info.Images)
   181  	assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{Labels: map[string]string{"app": "guestbook"}}, info.NetworkingInfo)
   182  }
   183  
   184  func TestGetServiceInfo(t *testing.T) {
   185  	info := &ResourceInfo{}
   186  	populateNodeInfo(testService, info)
   187  	assert.Equal(t, 0, len(info.Info))
   188  	assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
   189  		TargetLabels: map[string]string{"app": "guestbook"},
   190  		Ingress:      []v1.LoadBalancerIngress{{Hostname: "localhost"}},
   191  	}, info.NetworkingInfo)
   192  }
   193  
   194  func TestGetIstioVirtualServiceInfo(t *testing.T) {
   195  	info := &ResourceInfo{}
   196  	populateNodeInfo(testIstioVirtualService, info)
   197  	assert.Equal(t, 0, len(info.Info))
   198  	require.NotNil(t, info.NetworkingInfo)
   199  	require.NotNil(t, info.NetworkingInfo.TargetRefs)
   200  	assert.Contains(t, info.NetworkingInfo.TargetRefs, v1alpha1.ResourceRef{
   201  		Kind:      kube.ServiceKind,
   202  		Name:      "service_full",
   203  		Namespace: "demo",
   204  	})
   205  	assert.Contains(t, info.NetworkingInfo.TargetRefs, v1alpha1.ResourceRef{
   206  		Kind:      kube.ServiceKind,
   207  		Name:      "service_namespace",
   208  		Namespace: "namespace",
   209  	})
   210  	assert.Contains(t, info.NetworkingInfo.TargetRefs, v1alpha1.ResourceRef{
   211  		Kind:      kube.ServiceKind,
   212  		Name:      "service",
   213  		Namespace: "demo",
   214  	})
   215  }
   216  
   217  func TestGetIngressInfo(t *testing.T) {
   218  	info := &ResourceInfo{}
   219  	populateNodeInfo(testIngress, info)
   220  	assert.Equal(t, 0, len(info.Info))
   221  	sort.Slice(info.NetworkingInfo.TargetRefs, func(i, j int) bool {
   222  		return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0
   223  	})
   224  	assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
   225  		Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}},
   226  		TargetRefs: []v1alpha1.ResourceRef{{
   227  			Namespace: "default",
   228  			Group:     "",
   229  			Kind:      kube.ServiceKind,
   230  			Name:      "not-found-service",
   231  		}, {
   232  			Namespace: "default",
   233  			Group:     "",
   234  			Kind:      kube.ServiceKind,
   235  			Name:      "helm-guestbook",
   236  		}},
   237  		ExternalURLs: []string{"https://helm-guestbook.com/"},
   238  	}, info.NetworkingInfo)
   239  }
   240  
   241  func TestGetIngressInfoWildCardPath(t *testing.T) {
   242  	info := &ResourceInfo{}
   243  	populateNodeInfo(testIngressWildCardPath, info)
   244  	assert.Equal(t, 0, len(info.Info))
   245  	sort.Slice(info.NetworkingInfo.TargetRefs, func(i, j int) bool {
   246  		return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0
   247  	})
   248  	assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
   249  		Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}},
   250  		TargetRefs: []v1alpha1.ResourceRef{{
   251  			Namespace: "default",
   252  			Group:     "",
   253  			Kind:      kube.ServiceKind,
   254  			Name:      "not-found-service",
   255  		}, {
   256  			Namespace: "default",
   257  			Group:     "",
   258  			Kind:      kube.ServiceKind,
   259  			Name:      "helm-guestbook",
   260  		}},
   261  		ExternalURLs: []string{"https://helm-guestbook.com/"},
   262  	}, info.NetworkingInfo)
   263  }
   264  
   265  func TestGetIngressInfoWithoutTls(t *testing.T) {
   266  	info := &ResourceInfo{}
   267  	populateNodeInfo(testIngressWithoutTls, info)
   268  	assert.Equal(t, 0, len(info.Info))
   269  	sort.Slice(info.NetworkingInfo.TargetRefs, func(i, j int) bool {
   270  		return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0
   271  	})
   272  	assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
   273  		Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}},
   274  		TargetRefs: []v1alpha1.ResourceRef{{
   275  			Namespace: "default",
   276  			Group:     "",
   277  			Kind:      kube.ServiceKind,
   278  			Name:      "not-found-service",
   279  		}, {
   280  			Namespace: "default",
   281  			Group:     "",
   282  			Kind:      kube.ServiceKind,
   283  			Name:      "helm-guestbook",
   284  		}},
   285  		ExternalURLs: []string{"http://helm-guestbook.com/"},
   286  	}, info.NetworkingInfo)
   287  }
   288  
   289  func TestGetIngressInfoNoHost(t *testing.T) {
   290  	ingress := strToUnstructured(`
   291    apiVersion: extensions/v1beta1
   292    kind: Ingress
   293    metadata:
   294      name: helm-guestbook
   295      namespace: default
   296    spec:
   297      rules:
   298      - http:
   299          paths:
   300          - backend:
   301              serviceName: helm-guestbook
   302              servicePort: 443
   303            path: /
   304      tls:
   305      - secretName: my-tls
   306    status:
   307      loadBalancer:
   308        ingress:
   309        - ip: 107.178.210.11`)
   310  
   311  	info := &ResourceInfo{}
   312  	populateNodeInfo(ingress, info)
   313  
   314  	assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
   315  		Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}},
   316  		TargetRefs: []v1alpha1.ResourceRef{{
   317  			Namespace: "default",
   318  			Group:     "",
   319  			Kind:      kube.ServiceKind,
   320  			Name:      "helm-guestbook",
   321  		}},
   322  		ExternalURLs: []string{"https://107.178.210.11/"},
   323  	}, info.NetworkingInfo)
   324  }
   325  func TestExternalUrlWithSubPath(t *testing.T) {
   326  	ingress := strToUnstructured(`
   327    apiVersion: extensions/v1beta1
   328    kind: Ingress
   329    metadata:
   330      name: helm-guestbook
   331      namespace: default
   332    spec:
   333      rules:
   334      - http:
   335          paths:
   336          - backend:
   337              serviceName: helm-guestbook
   338              servicePort: 443
   339            path: /my/sub/path/
   340      tls:
   341      - secretName: my-tls
   342    status:
   343      loadBalancer:
   344        ingress:
   345        - ip: 107.178.210.11`)
   346  
   347  	info := &ResourceInfo{}
   348  	populateNodeInfo(ingress, info)
   349  
   350  	expectedExternalUrls := []string{"https://107.178.210.11/my/sub/path/"}
   351  	assert.Equal(t, expectedExternalUrls, info.NetworkingInfo.ExternalURLs)
   352  }
   353  func TestExternalUrlWithMultipleSubPaths(t *testing.T) {
   354  	ingress := strToUnstructured(`
   355    apiVersion: extensions/v1beta1
   356    kind: Ingress
   357    metadata:
   358      name: helm-guestbook
   359      namespace: default
   360    spec:
   361      rules:
   362      - host: helm-guestbook.com
   363        http:
   364          paths:
   365          - backend:
   366              serviceName: helm-guestbook
   367              servicePort: 443
   368            path: /my/sub/path/
   369          - backend:
   370              serviceName: helm-guestbook-2
   371              servicePort: 443
   372            path: /my/sub/path/2
   373          - backend:
   374              serviceName: helm-guestbook-3
   375              servicePort: 443
   376      tls:
   377      - secretName: my-tls
   378    status:
   379      loadBalancer:
   380        ingress:
   381        - ip: 107.178.210.11`)
   382  
   383  	info := &ResourceInfo{}
   384  	populateNodeInfo(ingress, info)
   385  
   386  	expectedExternalUrls := []string{"https://helm-guestbook.com/my/sub/path/", "https://helm-guestbook.com/my/sub/path/2", "https://helm-guestbook.com"}
   387  	actualURLs := info.NetworkingInfo.ExternalURLs
   388  	sort.Strings(expectedExternalUrls)
   389  	sort.Strings(actualURLs)
   390  	assert.Equal(t, expectedExternalUrls, actualURLs)
   391  }
   392  func TestExternalUrlWithNoSubPath(t *testing.T) {
   393  	ingress := strToUnstructured(`
   394    apiVersion: extensions/v1beta1
   395    kind: Ingress
   396    metadata:
   397      name: helm-guestbook
   398      namespace: default
   399    spec:
   400      rules:
   401      - http:
   402          paths:
   403          - backend:
   404              serviceName: helm-guestbook
   405              servicePort: 443
   406      tls:
   407      - secretName: my-tls
   408    status:
   409      loadBalancer:
   410        ingress:
   411        - ip: 107.178.210.11`)
   412  
   413  	info := &ResourceInfo{}
   414  	populateNodeInfo(ingress, info)
   415  
   416  	expectedExternalUrls := []string{"https://107.178.210.11"}
   417  	assert.Equal(t, expectedExternalUrls, info.NetworkingInfo.ExternalURLs)
   418  }
   419  
   420  func TestExternalUrlWithNetworkingApi(t *testing.T) {
   421  	ingress := strToUnstructured(`
   422    apiVersion: networking.k8s.io/v1beta1
   423    kind: Ingress
   424    metadata:
   425      name: helm-guestbook
   426      namespace: default
   427    spec:
   428      rules:
   429      - http:
   430          paths:
   431          - backend:
   432              serviceName: helm-guestbook
   433              servicePort: 443
   434      tls:
   435      - secretName: my-tls
   436    status:
   437      loadBalancer:
   438        ingress:
   439        - ip: 107.178.210.11`)
   440  
   441  	info := &ResourceInfo{}
   442  	populateNodeInfo(ingress, info)
   443  
   444  	expectedExternalUrls := []string{"https://107.178.210.11"}
   445  	assert.Equal(t, expectedExternalUrls, info.NetworkingInfo.ExternalURLs)
   446  }