Parcourir la source

preliminary unit test for specrel

sunguroku il y a 5 ans
Parent
commit
29f28e19fa

+ 7 - 3
dashboard/src/main/home/dashboard/expanded-chart/graph/GraphDisplay.tsx

@@ -92,17 +92,21 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
 
     let edges = [] as EdgeType[];
     components.map((c: ResourceType) => {
-      c.Relations.ControlRels.map((rel: any) => {
+      c.Relations?.ControlRels?.map((rel: any) => {
         if (rel.Source == c.ID) {
           edges.push({ type: "ControlRel", source: rel.Source, target: rel.Target });
         }
       })
-      c.Relations.LabelRels.map((rel: any) => {
+      c.Relations?.LabelRels?.map((rel: any) => {
         if (rel.Source == c.ID) {
           edges.push({ type: "LabelRel", source: rel.Source, target: rel.Target });
         }
       })
-
+      c.Relations?.SpecRels?.map((rel: any) => {
+        if (rel.Source == c.ID) {
+          edges.push({ type: "SpecRel", source: rel.Source, target: rel.Target });
+        }
+      })
       this.setState({ edges });
     });
     this.setState({ nodes });

+ 2 - 1
dashboard/src/shared/rosettaStone.tsx

@@ -9,5 +9,6 @@ export const kindToIcon: any = {
 
 export const edgeColors: any = {
   'LabelRel': '#949EFF',
-  'ControlRel': '#fcb603'
+  'ControlRel': '#fcb603',
+  'SpecRel': '#32a852'
 };

+ 7 - 2
internal/helm/grapher/object.go

@@ -18,14 +18,19 @@ func ParseObjs(objs []map[string]interface{}) []Object {
 	for i, obj := range objs {
 		kind := getField(obj, "kind").(string)
 		name := getField(obj, "metadata", "name").(string)
-		namespace := getField(obj, "metadata", "namespace").(string)
+
+		namespace := getField(obj, "metadata", "namespace")
+
+		if namespace == nil {
+			namespace = ""
+		}
 
 		// First add the object that appears on the YAML
 		parsedObj := Object{
 			ID:        i,
 			Kind:      kind,
 			Name:      name,
-			Namespace: namespace,
+			Namespace: namespace.(string),
 			RawYAML:   obj,
 			Relations: Relations{
 				ControlRels: []ControlRel{},

+ 29 - 11
internal/helm/grapher/relation.go

@@ -171,14 +171,22 @@ func (parsed *ParsedObjs) GetSpecRel() {
 		case "ClusterRoleBinding", "RoleBinding":
 			tid = parsed.findRBACTargets(o.ID, o.RawYAML)
 		case "Ingress":
-			// service and resource are mutually exclusive backend types.
-			kind := "Service"
-			name := getField(o.RawYAML, "spec", "rules", "http", "paths", "backend", "service", "name")
-			if name == nil {
-				name = getField(o.RawYAML, "spec", "rules", "http", "paths", "backend", "resource", "name")
-				kind = getField(o.RawYAML, "spec", "rules", "http", "paths", "backend", "resource", "kind").(string)
+			rules := getField(o.RawYAML, "spec", "rules")
+			for _, r := range rules.([]interface{}) {
+				http := getField(r.(map[string]interface{}), "http")
+				paths := getField(http.(map[string]interface{}), "paths")
+				for _, p := range paths.([]interface{}) {
+					// service and resource are mutually exclusive backend types.
+					kind := "Service"
+					name := getField(p.(map[string]interface{}), "backend", "service", "name")
+					if name == nil {
+						name = getField(p.(map[string]interface{}), "backend", "resource", "name")
+						kind = getField(p.(map[string]interface{}), "backend", "resource", "kind").(string)
+					}
+					tid = parsed.findObjectByNameAndKind(o.ID, name.(string), kind)
+				}
 			}
-			tid = parsed.findObjectByNameAndKind(o.ID, name.(string), kind)
+
 		case "StatefulSet":
 			serviceName := getField(o.RawYAML, "spec", "serviceName").(string)
 			tid = append(tid, parsed.findObjectByNameAndKind(o.ID, serviceName, "Service")...)
@@ -187,7 +195,17 @@ func (parsed *ParsedObjs) GetSpecRel() {
 			imageSecrets := getField(o.RawYAML, "spec", "ImagePullSecrets")
 			serviceAccount := getField(o.RawYAML, "spec", "serviceaccountname")
 
-			tid = append(tid, parsed.findObjectByNameAndKind(o.ID, imageSecrets, "Secret")...)
+			if imageSecrets == nil {
+				imageSecrets = []interface{}{}
+			}
+
+			if volume == nil {
+				volume = []interface{}{}
+			}
+
+			for _, sec := range imageSecrets.([]interface{}) {
+				tid = append(tid, parsed.findObjectByNameAndKind(o.ID, sec, "Secret")...)
+			}
 			tid = append(tid, parsed.findObjectByNameAndKind(o.ID, serviceAccount, "ServiceAccount")...)
 
 			for _, v := range volume.([]interface{}) {
@@ -196,9 +214,9 @@ func (parsed *ParsedObjs) GetSpecRel() {
 				pvc := getField(vt, "persistentVolumeClaim", "claimName")
 				secret := getField(vt, "secret", "secretName")
 
-				tid = append(tid, parsed.findObjectByNameAndKind(o.ID, configMap.(string), "ConfigMap")...)
-				tid = append(tid, parsed.findObjectByNameAndKind(o.ID, pvc.(string), "PersistentVolumeClaim")...)
-				tid = append(tid, parsed.findObjectByNameAndKind(o.ID, secret.(string), "Secret")...)
+				tid = append(tid, parsed.findObjectByNameAndKind(o.ID, configMap, "ConfigMap")...)
+				tid = append(tid, parsed.findObjectByNameAndKind(o.ID, pvc, "PersistentVolumeClaim")...)
+				tid = append(tid, parsed.findObjectByNameAndKind(o.ID, secret, "Secret")...)
 			}
 		}
 

+ 16 - 20
internal/helm/grapher/relation_test.go

@@ -221,7 +221,6 @@ func TestLabelRels(t *testing.T) {
 				}
 			}
 		}
-
 	}
 }
 
@@ -229,7 +228,7 @@ func TestSpecRels(t *testing.T) {
 	ts := []test{
 		test{
 			Expected: expControlRels1,
-			FilePath: "./test_yaml/cassandra.yaml",
+			FilePath: "./test_yaml/ingress.yaml",
 		},
 	}
 
@@ -250,29 +249,26 @@ func TestSpecRels(t *testing.T) {
 		parsed.GetControlRel()
 		parsed.GetSpecRel()
 
-		t.Errorf("ok")
-
 		// for i, o := range parsed.Objects {
-		// 	e := r.Expected[i]
-		// 	if len(e.Relations.LabelRels) != len(o.Relations.LabelRels) {
-		// 		t.Errorf("Number of LabelRel differs for %s of type %s. Expected %d. Got %d",
-		// 			e.Name, e.Kind, len(e.Relations.LabelRels), len(o.Relations.LabelRels))
-		// 	}
+		// e := r.Expected[i]
+		// if len(e.Relations.SpecRels) != len(o.Relations.SpecRels) {
+		// 	t.Errorf("Number of SpecRel differs for %s of type %s. Expected %d. Got %d",
+		// 		e.Name, e.Kind, len(e.Relations.SpecRels), len(o.Relations.SpecRels))
+		// }
 
-		// 	for j, rrel := range o.Relations.LabelRels {
-		// 		expRrel := e.Relations.LabelRels[j]
+		// for j, rrel := range o.Relations.SpecRels {
+		// 	expRrel := e.Relations.SpecRels[j]
 
-		// 		if expRrel.Relation.Source != rrel.Relation.Source {
-		// 			t.Errorf("Source in ControlRel differs for %s of type %s. Expected %d. Got %d",
-		// 				o.Name, o.Kind, expRrel.Relation.Source, rrel.Relation.Source)
-		// 		}
+		// 	if expRrel.Relation.Source != rrel.Relation.Source {
+		// 		t.Errorf("Source in ControlRel differs for %s of type %s. Expected %d. Got %d",
+		// 			o.Name, o.Kind, expRrel.Relation.Source, rrel.Relation.Source)
+		// 	}
 
-		// 		if expRrel.Relation.Target != rrel.Relation.Target {
-		// 			t.Errorf("Target in ControlRel differs for %s of type %s. Expected %d. Got %d",
-		// 				o.Name, o.Kind, expRrel.Relation.Target, rrel.Relation.Target)
-		// 		}
+		// 	if expRrel.Relation.Target != rrel.Relation.Target {
+		// 		t.Errorf("Target in ControlRel differs for %s of type %s. Expected %d. Got %d",
+		// 			o.Name, o.Kind, expRrel.Relation.Target, rrel.Relation.Target)
 		// 	}
 		// }
-
+		// }
 	}
 }

+ 119 - 0
internal/helm/grapher/test_yaml/ingress.yaml

@@ -0,0 +1,119 @@
+---
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: service-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /
+spec:
+  rules:
+  - http:
+      paths:
+      - path: /testpath
+        pathType: Prefix
+        backend:
+          service:
+            name: test
+            port:
+              number: 80
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: test
+spec:
+  type: NodePort
+  selector:
+    app: foo
+  ports:
+  - protocol: TCP
+    port: 80
+    targetPort: 80
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: nginx
+spec:
+  type: NodePort
+  selector:
+    app: foo
+  ports:
+  - protocol: TCP
+    port: 80
+    targetPort: 80
+---
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: resource-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /
+spec:
+  rules:
+  - http:
+      paths:
+      - path: /testpath
+        pathType: Prefix
+        backend:
+          resource:
+            name: resource-test
+            kind: StatefulSet
+            port:
+              number: 80
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: resource-test
+spec:
+  serviceName: "nginx"
+  replicas: 2
+  selector:
+    matchLabels:
+      app: nginx
+  template:
+    metadata:
+      labels:
+        app: nginx
+    spec:
+      volumes:
+        - name: config-vol
+          configMap:
+            name: log-config
+            items:
+              - key: log_level
+                path: log_level
+      containers:
+      - name: nginx
+        image: k8s.gcr.io/nginx-slim:0.8
+        ports:
+        - containerPort: 80
+          name: web
+        volumeMounts:
+        - name: www
+          mountPath: /usr/share/nginx/html
+  volumeClaimTemplates:
+  - metadata:
+      name: www
+    spec:
+      accessModes: [ "ReadWriteOnce" ]
+      resources:
+        requests:
+          storage: 1Gi
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  creationTimestamp: 2016-02-18T18:52:05Z
+  name: log-config
+  namespace: default
+  resourceVersion: "516"
+  uid: b4952dc3-d670-11e5-8cd0-68f728db1985
+data:
+  game.properties: |
+    enemies=aliens
+    lives=3
+    secret.code.lives=30
+  ui.properties: |
+    color.good=purple

+ 35 - 0
internal/helm/grapher/test_yaml/volumes.yaml

@@ -0,0 +1,35 @@
+---
+apiVersion: v1
+kind: Pod
+metadata:
+  name: configmap-pod
+spec:
+  containers:
+    - name: test
+      image: busybox
+      volumeMounts:
+        - name: config-vol
+          mountPath: /etc/config
+  volumes:
+    - name: config-vol
+      configMap:
+        name: log-config
+        items:
+          - key: log_level
+            path: log_level
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  creationTimestamp: 2016-02-18T18:52:05Z
+  name: log-config
+  namespace: default
+  resourceVersion: "516"
+  uid: b4952dc3-d670-11e5-8cd0-68f728db1985
+data:
+  game.properties: |
+    enemies=aliens
+    lives=3
+    secret.code.lives=30
+  ui.properties: |
+    color.good=purple

+ 1 - 0
server/api/release_handler.go

@@ -143,6 +143,7 @@ func (app *App) HandleGetReleaseComponents(w http.ResponseWriter, r *http.Reques
 
 	parsed.GetControlRel()
 	parsed.GetLabelRel()
+	parsed.GetSpecRel()
 
 	if err := json.NewEncoder(w).Encode(parsed.Objects); err != nil {
 		app.handleErrorFormDecoding(err, ErrReleaseDecode, w)