Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #357 - Expose application nodes networking information #1333

Merged
merged 1 commit into from
Mar 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 57 additions & 21 deletions assets/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
"200": {
"description": "(empty)",
"schema": {
"$ref": "#/definitions/applicationResourceTreeResponse"
"$ref": "#/definitions/v1alpha1ApplicationTree"
}
}
}
Expand Down Expand Up @@ -1445,17 +1445,6 @@
"applicationOperationTerminateResponse": {
"type": "object"
},
"applicationResourceTreeResponse": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/v1alpha1ResourceNode"
}
}
}
},
"clusterClusterCreateFromKubeConfigRequest": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -1696,12 +1685,14 @@
"title": "KustomizeAppSpec contains kustomize app name and path in source repo",
"properties": {
"imageTags": {
"description": "imageTags is a list of available image tags. This is only populated for Kustomize 1.",
"type": "array",
"items": {
"$ref": "#/definitions/v1alpha1KustomizeImageTag"
}
},
"images": {
"description": "images is a list of available images. This is only populated for Kustomize 2.",
"type": "array",
"items": {
"type": "string"
Expand Down Expand Up @@ -2576,6 +2567,17 @@
}
}
},
"v1alpha1ApplicationTree": {
"type": "object",
"properties": {
"nodes": {
"type": "array",
"items": {
"$ref": "#/definitions/v1alpha1ResourceNode"
}
}
}
},
"v1alpha1ApplicationWatchEvent": {
"description": "ApplicationWatchEvent contains information about application change.",
"type": "object",
Expand Down Expand Up @@ -2947,25 +2949,62 @@
}
}
},
"v1alpha1ResourceNetworkingInfo": {
"type": "object",
"properties": {
"labels": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"targetLabels": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"targetRef": {
"type": "array",
"items": {
"$ref": "#/definitions/v1alpha1ResourceRef"
}
}
}
},
"v1alpha1ResourceNode": {
"type": "object",
"title": "ResourceNode contains information about live resource and its children",
"properties": {
"children": {
"info": {
"type": "array",
"items": {
"$ref": "#/definitions/v1alpha1ResourceNode"
"$ref": "#/definitions/v1alpha1InfoItem"
}
},
"group": {
"type": "string"
"networkingInfo": {
"$ref": "#/definitions/v1alpha1ResourceNetworkingInfo"
},
"info": {
"parentRefs": {
"type": "array",
"items": {
"$ref": "#/definitions/v1alpha1InfoItem"
"$ref": "#/definitions/v1alpha1ResourceRef"
}
},
"resourceRef": {
"$ref": "#/definitions/v1alpha1ResourceRef"
},
"resourceVersion": {
"type": "string"
}
}
},
"v1alpha1ResourceRef": {
"type": "object",
"properties": {
"group": {
"type": "string"
},
"kind": {
"type": "string"
},
Expand All @@ -2975,9 +3014,6 @@
"namespace": {
"type": "string"
},
"resourceVersion": {
"type": "string"
},
"version": {
"type": "string"
}
Expand Down
2 changes: 1 addition & 1 deletion common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,5 @@ const (
MinClientVersion = "0.12.0"
// CacheVersion is a objects version cached using util/cache/cache.go.
// Number should be bumped in case of backward incompatible change to make sure cache is invalidated after upgrade.
CacheVersion = "0.12.0"
CacheVersion = "0.13.0"
)
43 changes: 19 additions & 24 deletions controller/appcontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,9 @@ func (ctrl *ApplicationController) setAppManagedResources(a *appv1.Application,
return ctrl.cache.SetAppManagedResources(a.Name, managedResources)
}

func (ctrl *ApplicationController) resourceTree(a *appv1.Application, managedResources []*appv1.ResourceDiff) ([]*appv1.ResourceNode, error) {
items := make([]*appv1.ResourceNode, 0)
func (ctrl *ApplicationController) resourceTree(a *appv1.Application, managedResources []*appv1.ResourceDiff) (*appv1.ApplicationTree, error) {
nodes := make([]appv1.ResourceNode, 0)

for i := range managedResources {
managedResource := managedResources[i]
var live = &unstructured.Unstructured{}
Expand All @@ -155,34 +156,28 @@ func (ctrl *ApplicationController) resourceTree(a *appv1.Application, managedRes
if err != nil {
return nil, err
}
version := ""
resourceVersion := ""
if live != nil {
resourceVersion = live.GetResourceVersion()
version = live.GroupVersionKind().Version
} else if target != nil {
version = target.GroupVersionKind().Version
}

node := appv1.ResourceNode{
Version: version,
ResourceVersion: resourceVersion,
Name: managedResource.Name,
Kind: managedResource.Kind,
Group: managedResource.Group,
Namespace: managedResource.Namespace,
}

if live != nil {
children, err := ctrl.stateCache.GetChildren(a.Spec.Destination.Server, live)
if live == nil {
nodes = append(nodes, appv1.ResourceNode{
ResourceRef: appv1.ResourceRef{
Version: target.GroupVersionKind().Version,
Name: managedResource.Name,
Kind: managedResource.Kind,
Group: managedResource.Group,
Namespace: managedResource.Namespace,
},
})
} else {
err := ctrl.stateCache.IterateHierarchy(a.Spec.Destination.Server, kube.GetResourceKey(live), func(child appv1.ResourceNode) {
nodes = append(nodes, child)
})
if err != nil {
return nil, err
}
node.Children = children

}
items = append(items, &node)
}
return items, nil
return &appv1.ApplicationTree{Nodes: nodes}, nil
}

func (ctrl *ApplicationController) managedResources(a *appv1.Application, comparisonResult *comparisonResult) ([]*appv1.ResourceDiff, error) {
Expand Down
11 changes: 6 additions & 5 deletions controller/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import (

type LiveStateCache interface {
IsNamespaced(server string, obj *unstructured.Unstructured) (bool, error)
// Returns child nodes for a given k8s resource
GetChildren(server string, obj *unstructured.Unstructured) ([]appv1.ResourceNode, error)
// Executes give callback against resource specified by the key and all its children
IterateHierarchy(server string, key kube.ResourceKey, action func(child appv1.ResourceNode)) error
// Returns state of live nodes which correspond for target nodes of specified application.
GetManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error)
// Starts watching resources of each controlled cluster.
Expand Down Expand Up @@ -132,12 +132,13 @@ func (c *liveStateCache) IsNamespaced(server string, obj *unstructured.Unstructu
return clusterInfo.isNamespaced(obj), nil
}

func (c *liveStateCache) GetChildren(server string, obj *unstructured.Unstructured) ([]appv1.ResourceNode, error) {
func (c *liveStateCache) IterateHierarchy(server string, key kube.ResourceKey, action func(child appv1.ResourceNode)) error {
clusterInfo, err := c.getSyncedCluster(server)
if err != nil {
return nil, err
return err
}
return clusterInfo.getChildren(obj), nil
clusterInfo.iterateHierarchy(key, action)
return nil
}

func (c *liveStateCache) GetManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) {
Expand Down
26 changes: 14 additions & 12 deletions controller/cache/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,23 +90,25 @@ func createObjInfo(un *unstructured.Unstructured, appInstanceLabel string) *node
APIVersion: "",
})
}
info := &node{
info, networkingInfo := getNodeInfo(un)
nodeInfo := &node{
resourceVersion: un.GetResourceVersion(),
ref: v1.ObjectReference{
APIVersion: un.GetAPIVersion(),
Kind: un.GetKind(),
Name: un.GetName(),
Namespace: un.GetNamespace(),
},
ownerRefs: ownerRefs,
info: getNodeInfo(un),
ownerRefs: ownerRefs,
info: info,
networkingInfo: networkingInfo,
}
appName := kube.GetAppInstanceLabel(un, appInstanceLabel)
if len(ownerRefs) == 0 && appName != "" {
info.appName = appName
info.resource = un
nodeInfo.appName = appName
nodeInfo.resource = un
}
return info
return nodeInfo
}

func (c *clusterInfo) setNode(n *node) {
Expand Down Expand Up @@ -330,19 +332,19 @@ func (c *clusterInfo) ensureSynced() error {
return c.syncError
}

func (c *clusterInfo) getChildren(obj *unstructured.Unstructured) []appv1.ResourceNode {
func (c *clusterInfo) iterateHierarchy(key kube.ResourceKey, action func(child appv1.ResourceNode)) {
c.lock.Lock()
defer c.lock.Unlock()
children := make([]appv1.ResourceNode, 0)
if objInfo, ok := c.nodes[kube.GetResourceKey(obj)]; ok {
nsNodes := c.nsIndex[obj.GetNamespace()]
if objInfo, ok := c.nodes[key]; ok {
action(objInfo.asResourceNode())
nsNodes := c.nsIndex[key.Namespace]
for _, child := range nsNodes {
if objInfo.isParentOf(child) {
children = append(children, child.childResourceNodes(nsNodes, map[kube.ResourceKey]bool{objInfo.resourceKey(): true}))
action(child.asResourceNode())
child.iterateChildren(nsNodes, map[kube.ResourceKey]bool{objInfo.resourceKey(): true}, action)
}
}
}
return children
}

func (c *clusterInfo) isNamespaced(obj *unstructured.Unstructured) bool {
Expand Down
Loading