mirror of
https://github.com/argoproj/argo-cd
synced 2026-04-21 17:07:16 +00:00
Adds images to resource tree (#1351)
This commit is contained in:
parent
790cdd1d45
commit
723228598e
12 changed files with 428 additions and 327 deletions
|
|
@ -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
|
||||
|
|
@ -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.:
|
||||
|
|
|
|||
1
Gopkg.lock
generated
1
Gopkg.lock
generated
|
|
@ -1552,6 +1552,7 @@
|
|||
"github.com/gogo/protobuf/proto",
|
||||
"github.com/gogo/protobuf/protoc-gen-gofast",
|
||||
"github.com/gogo/protobuf/protoc-gen-gogofast",
|
||||
"github.com/gogo/protobuf/sortkeys",
|
||||
"github.com/golang/protobuf/proto",
|
||||
"github.com/golang/protobuf/protoc-gen-go",
|
||||
"github.com/golang/protobuf/ptypes/empty",
|
||||
|
|
|
|||
4
Makefile
4
Makefile
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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": {
|
||||
|
|
@ -3035,6 +3041,7 @@
|
|||
},
|
||||
"v1alpha1ResourceOverride": {
|
||||
"type": "object",
|
||||
"title": "ResourceOverride holds configuration to customize resource diffing and health assessment",
|
||||
"properties": {
|
||||
"healthLua": {
|
||||
"type": "string"
|
||||
|
|
|
|||
6
controller/cache/cluster.go
vendored
6
controller/cache/cluster.go
vendored
|
|
@ -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{
|
||||
|
|
@ -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
|
||||
|
|
|
|||
40
controller/cache/info.go
vendored
40
controller/cache/info.go
vendored
|
|
@ -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 {
|
||||
|
|
@ -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{
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
controller/cache/info_test.go
vendored
43
controller/cache/info_test.go
vendored
|
|
@ -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{{
|
||||
|
|
@ -44,5 +63,5 @@ func TestGetIngressInfo(t *testing.T) {
|
|||
Kind: kube.ServiceKind,
|
||||
Name: "helm-guestbook",
|
||||
}},
|
||||
}, networkInfo)
|
||||
}, node.networkingInfo)
|
||||
}
|
||||
|
|
|
|||
2
controller/cache/node.go
vendored
2
controller/cache/node.go
vendored
|
|
@ -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 {
|
||||
|
|
@ -101,6 +102,7 @@ func (n *node) asResourceNode() appv1.ResourceNode {
|
|||
Info: n.info,
|
||||
ResourceVersion: n.resourceVersion,
|
||||
NetworkingInfo: n.networkingInfo,
|
||||
Images: n.images,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -522,8 +522,11 @@ message ResourceNode {
|
|||
optional ResourceNetworkingInfo networkingInfo = 4;
|
||||
|
||||
optional string resourceVersion = 5;
|
||||
|
||||
repeated string images = 6;
|
||||
}
|
||||
|
||||
// ResourceOverride holds configuration to customize resource diffing and health assessment
|
||||
message ResourceOverride {
|
||||
optional string healthLua = 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -573,6 +573,7 @@ type ResourceNode struct {
|
|||
Info []InfoItem `json:"info,omitempty" protobuf:"bytes,3,opt,name=info"`
|
||||
NetworkingInfo *ResourceNetworkingInfo `json:"networkingInfo,omitempty" protobuf:"bytes,4,opt,name=networkingInfo"`
|
||||
ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,5,opt,name=resourceVersion"`
|
||||
Images []string `json:"images,omitempty" protobuf:"bytes,6,opt,name=images"`
|
||||
}
|
||||
|
||||
func (n *ResourceNode) GroupKindVersion() schema.GroupVersionKind {
|
||||
|
|
|
|||
|
|
@ -1109,6 +1109,11 @@ func (in *ResourceNode) DeepCopyInto(out *ResourceNode) {
|
|||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
if in.Images != nil {
|
||||
in, out := &in.Images, &out.Images
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue