Skip to content

Commit

Permalink
Adds images to resource tree (argoproj#1351)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexec authored Apr 3, 2019
1 parent 790cdd1 commit 7232285
Show file tree
Hide file tree
Showing 12 changed files with 428 additions and 327 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ make test-e2e

It is much easier to run and debug if you run ArgoCD on your local machine than in the Kubernetes cluster.

You should scale the deployemnts to zero:
You should scale the deployments to zero:

```
kubectl -n argocd scale deployment.extensions/argocd-application-controller --replicas 0
Expand All @@ -106,7 +106,7 @@ Then start the services:

```
cd ~/go/src/github.com/argoproj/argo-cd
goreman start
make start
```

You can now execute `argocd` command against your locally running ArgoCD by appending `--server localhost:8080 --plaintext --insecure`, e.g.:
Expand Down
1 change: 1 addition & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ clean-debug:
clean: clean-debug
-rm -rf ${CURRENT_DIR}/dist

.PHONY: start
start:
goreman start

.PHONY: pre-commit
pre-commit: dep-ensure codegen build lint test

Expand Down
7 changes: 7 additions & 0 deletions assets/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -3010,6 +3010,12 @@
"type": "object",
"title": "ResourceNode contains information about live resource and its children",
"properties": {
"images": {
"type": "array",
"items": {
"type": "string"
}
},
"info": {
"type": "array",
"items": {
Expand All @@ -3035,6 +3041,7 @@
},
"v1alpha1ResourceOverride": {
"type": "object",
"title": "ResourceOverride holds configuration to customize resource diffing and health assessment",
"properties": {
"healthLua": {
"type": "string"
Expand Down
6 changes: 2 additions & 4 deletions controller/cache/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ func createObjInfo(un *unstructured.Unstructured, appInstanceLabel string) *node
APIVersion: "",
})
}
info, networkingInfo := getNodeInfo(un)
nodeInfo := &node{
resourceVersion: un.GetResourceVersion(),
ref: v1.ObjectReference{
Expand All @@ -99,10 +98,9 @@ func createObjInfo(un *unstructured.Unstructured, appInstanceLabel string) *node
Name: un.GetName(),
Namespace: un.GetNamespace(),
},
ownerRefs: ownerRefs,
info: info,
networkingInfo: networkingInfo,
ownerRefs: ownerRefs,
}
populateNodeInfo(un, nodeInfo)
appName := kube.GetAppInstanceLabel(un, appInstanceLabel)
if len(ownerRefs) == 0 && appName != "" {
nodeInfo.appName = appName
Expand Down
40 changes: 25 additions & 15 deletions controller/cache/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,27 @@ import (
"github.com/argoproj/argo-cd/util/kube"
)

func getNodeInfo(un *unstructured.Unstructured) ([]v1alpha1.InfoItem, *v1alpha1.ResourceNetworkingInfo) {
func populateNodeInfo(un *unstructured.Unstructured, node *node) {
gvk := un.GroupVersionKind()

switch gvk.Group {
case "":
switch gvk.Kind {
case kube.PodKind:
return getPodInfo(un)
populatePodInfo(un, node)
return
case kube.ServiceKind:
return getServiceInfo(un)
populateServiceInfo(un, node)
return
}
case "extensions":
switch gvk.Kind {
case kube.IngressKind:
return getIngressInfo(un)
populateIngressInfo(un, node)
return
}
}
return []v1alpha1.InfoItem{}, nil
node.info = []v1alpha1.InfoItem{}
}

func getIngress(un *unstructured.Unstructured) []v1.LoadBalancerIngress {
Expand All @@ -50,16 +53,16 @@ func getIngress(un *unstructured.Unstructured) []v1.LoadBalancerIngress {
return res
}

func getServiceInfo(un *unstructured.Unstructured) ([]v1alpha1.InfoItem, *v1alpha1.ResourceNetworkingInfo) {
func populateServiceInfo(un *unstructured.Unstructured, node *node) {
targetLabels, _, _ := unstructured.NestedStringMap(un.Object, "spec", "selector")
ingress := make([]v1.LoadBalancerIngress, 0)
if serviceType, ok, err := unstructured.NestedString(un.Object, "spec", "type"); ok && err == nil && serviceType == string(v1.ServiceTypeLoadBalancer) {
ingress = getIngress(un)
}
return nil, &v1alpha1.ResourceNetworkingInfo{TargetLabels: targetLabels, Ingress: ingress}
node.networkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetLabels: targetLabels, Ingress: ingress}
}

func getIngressInfo(un *unstructured.Unstructured) ([]v1alpha1.InfoItem, *v1alpha1.ResourceNetworkingInfo) {
func populateIngressInfo(un *unstructured.Unstructured, node *node) {
targets := make([]v1alpha1.ResourceRef, 0)
if backend, ok, err := unstructured.NestedMap(un.Object, "spec", "backend"); ok && err == nil {
targets = append(targets, v1alpha1.ResourceRef{
Expand Down Expand Up @@ -95,14 +98,15 @@ func getIngressInfo(un *unstructured.Unstructured) ([]v1alpha1.InfoItem, *v1alph
}
}
}
return nil, &v1alpha1.ResourceNetworkingInfo{TargetRefs: targets, Ingress: getIngress(un)}
node.networkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetRefs: targets, Ingress: getIngress(un)}
}

func getPodInfo(un *unstructured.Unstructured) ([]v1alpha1.InfoItem, *v1alpha1.ResourceNetworkingInfo) {
func populatePodInfo(un *unstructured.Unstructured, node *node) {
pod := v1.Pod{}
err := runtime.DefaultUnstructuredConverter.FromUnstructured(un.Object, &pod)
if err != nil {
return []v1alpha1.InfoItem{}, nil
node.info = []v1alpha1.InfoItem{}
return
}
restarts := 0
totalContainers := len(pod.Spec.Containers)
Expand All @@ -114,6 +118,12 @@ func getPodInfo(un *unstructured.Unstructured) ([]v1alpha1.InfoItem, *v1alpha1.R
}

initializing := false

// note that I ignore initContainers
for _, container := range pod.Spec.Containers {
node.images = append(node.images, container.Image)
}

for i := range pod.Status.InitContainerStatuses {
container := pod.Status.InitContainerStatuses[i]
restarts += int(container.RestartCount)
Expand Down Expand Up @@ -176,10 +186,10 @@ func getPodInfo(un *unstructured.Unstructured) ([]v1alpha1.InfoItem, *v1alpha1.R
reason = "Terminating"
}

info := make([]v1alpha1.InfoItem, 0)
node.info = make([]v1alpha1.InfoItem, 0)
if reason != "" {
info = append(info, v1alpha1.InfoItem{Name: "Status Reason", Value: reason})
node.info = append(node.info, v1alpha1.InfoItem{Name: "Status Reason", Value: reason})
}
info = append(info, v1alpha1.InfoItem{Name: "Containers", Value: fmt.Sprintf("%d/%d", readyContainers, totalContainers)})
return info, &v1alpha1.ResourceNetworkingInfo{Labels: un.GetLabels()}
node.info = append(node.info, v1alpha1.InfoItem{Name: "Containers", Value: fmt.Sprintf("%d/%d", readyContainers, totalContainers)})
node.networkingInfo = &v1alpha1.ResourceNetworkingInfo{Labels: un.GetLabels()}
}
43 changes: 31 additions & 12 deletions controller/cache/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,53 @@ package cache
import (
"testing"

v1 "k8s.io/api/core/v1"

"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/util/kube"
v1 "k8s.io/api/core/v1"

"github.com/stretchr/testify/assert"
)

func TestGetPodInfo(t *testing.T) {
pod := testPod.DeepCopy()
pod.SetLabels(map[string]string{"app": "guestbook"})
pod := strToUnstructured(`
apiVersion: v1
kind: Pod
metadata:
name: helm-guestbook-pod
namespace: default
ownerReferences:
- apiVersion: extensions/v1beta1
kind: ReplicaSet
name: helm-guestbook-rs
resourceVersion: "123"
labels:
app: guestbook
spec:
containers:
- image: bar`)

info, networkInfo := getNodeInfo(pod)
assert.Equal(t, []v1alpha1.InfoItem{{Name: "Containers", Value: "0/0"}}, info)
assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{Labels: map[string]string{"app": "guestbook"}}, networkInfo)
node := &node{}
populateNodeInfo(pod, node)
assert.Equal(t, []v1alpha1.InfoItem{{Name: "Containers", Value: "0/1"}}, node.info)
assert.Equal(t, []string{"bar"}, node.images)
assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{Labels: map[string]string{"app": "guestbook"}}, node.networkingInfo)
}

func TestGetServiceInfo(t *testing.T) {
info, networkInfo := getNodeInfo(testService)
assert.Equal(t, 0, len(info))
node := &node{}
populateNodeInfo(testService, node)
assert.Equal(t, 0, len(node.info))
assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
TargetLabels: map[string]string{"app": "guestbook"},
Ingress: []v1.LoadBalancerIngress{{Hostname: "localhost"}},
}, networkInfo)
}, node.networkingInfo)
}

func TestGetIngressInfo(t *testing.T) {
info, networkInfo := getNodeInfo(testIngress)
assert.Equal(t, 0, len(info))
node := &node{}
populateNodeInfo(testIngress, node)
assert.Equal(t, 0, len(node.info))
assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}},
TargetRefs: []v1alpha1.ResourceRef{{
Expand All @@ -44,5 +63,5 @@ func TestGetIngressInfo(t *testing.T) {
Kind: kube.ServiceKind,
Name: "helm-guestbook",
}},
}, networkInfo)
}, node.networkingInfo)
}
2 changes: 2 additions & 0 deletions controller/cache/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type node struct {
resource *unstructured.Unstructured
// networkingInfo are available only for known types involved into networking: Ingress, Service, Pod
networkingInfo *appv1.ResourceNetworkingInfo
images []string
}

func (n *node) isRootAppNode() bool {
Expand Down Expand Up @@ -101,6 +102,7 @@ func (n *node) asResourceNode() appv1.ResourceNode {
Info: n.info,
ResourceVersion: n.resourceVersion,
NetworkingInfo: n.networkingInfo,
Images: n.images,
}
}

Expand Down
Loading

0 comments on commit 7232285

Please sign in to comment.