Skip to content

Commit

Permalink
Include dependent operators in diagnostics (#1570)
Browse files Browse the repository at this point in the history
Operators that are children of other operators through dependencies are included in diagnostics bundles of their parent operator.

Signed-off-by: Jan Schlicht <jan@d2iq.com>
  • Loading branch information
Jan Schlicht committed Jun 29, 2020
1 parent 81be705 commit 6fc3086
Show file tree
Hide file tree
Showing 24 changed files with 197 additions and 2,077 deletions.
144 changes: 84 additions & 60 deletions pkg/kudoctl/cmd/diagnostics/diagnostics_test.go
Expand Up @@ -33,64 +33,73 @@ const (
)

const (
zkOperatorFile = "diag/operator_zookeeper/zookeeper.yaml"
zkOperatorVersionFile = "diag/operator_zookeeper/operatorversion_zookeeper-0.3.0/zookeeper-0.3.0.yaml"
zkPod2File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-2/zookeeper-instance-zookeeper-2.yaml"
zkLog2Container1File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-2/kubernetes-zookeeper.log.gz"
zkServicesFile = "diag/operator_zookeeper/instance_zookeeper-instance/servicelist.yaml"
zkPod0File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-0/zookeeper-instance-zookeeper-0.yaml"
zkLog0Container1File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-0/kubernetes-zookeeper.log.gz"
zkLog0Container2File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-0/pause-debug.log.gz"
zkInstanceFile = "diag/operator_zookeeper/instance_zookeeper-instance/zookeeper-instance.yaml"
zkPod1File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-1/zookeeper-instance-zookeeper-1.yaml"
zkLog1Container1File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-1/kubernetes-zookeeper.log.gz"
zkStatefulSetsFile = "diag/operator_zookeeper/instance_zookeeper-instance/statefulsetlist.yaml"
versionFile = "diag/version.yaml"
kmServicesFile = "diag/kudo/servicelist.yaml"
kmPodFile = "diag/kudo/pod_kudo-controller-manager-0/kudo-controller-manager-0.yaml"
kmLogFile = "diag/kudo/pod_kudo-controller-manager-0/manager.log.gz"
kmServiceAccountsFile = "diag/kudo/serviceaccountlist.yaml"
kmStatefulSetsFile = "diag/kudo/statefulsetlist.yaml"
settingsFile = "diag/settings.yaml"
zkOperatorFile = "diag/operator_zookeeper/zookeeper.yaml"
zkOperatorVersionFile = "diag/operator_zookeeper/operatorversion_zookeeper-0.3.0/zookeeper-0.3.0.yaml"
zkPod2File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-2/zookeeper-instance-zookeeper-2.yaml"
zkLog2Container1File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-2/kubernetes-zookeeper.log.gz"
zkServicesFile = "diag/operator_zookeeper/instance_zookeeper-instance/servicelist.yaml"
zkPod0File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-0/zookeeper-instance-zookeeper-0.yaml"
zkLog0Container1File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-0/kubernetes-zookeeper.log.gz"
zkLog0Container2File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-0/pause-debug.log.gz"
zkInstanceFile = "diag/operator_zookeeper/instance_zookeeper-instance/zookeeper-instance.yaml"
zkPod1File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-1/zookeeper-instance-zookeeper-1.yaml"
zkLog1Container1File = "diag/operator_zookeeper/instance_zookeeper-instance/pod_zookeeper-instance-zookeeper-1/kubernetes-zookeeper.log.gz"
zkStatefulSetsFile = "diag/operator_zookeeper/instance_zookeeper-instance/statefulsetlist.yaml"
childOperatorFile = "diag/operator_zookeeper/operator_zookeeper-instance-child/zookeeper-instance-child.yaml"
childOperatorVersionFile = "diag/operator_zookeeper/operator_zookeeper-instance-child/operatorversion_zookeeper-instance-child-0.1.0/zookeeper-instance-child-0.1.0.yaml"
childInstanceFile = "diag/operator_zookeeper/operator_zookeeper-instance-child/instance_zookeeper-instance-child-instance/zookeeper-instance-child-instance.yaml"
versionFile = "diag/version.yaml"
kmServicesFile = "diag/kudo/servicelist.yaml"
kmPodFile = "diag/kudo/pod_kudo-controller-manager-0/kudo-controller-manager-0.yaml"
kmLogFile = "diag/kudo/pod_kudo-controller-manager-0/manager.log.gz"
kmServiceAccountsFile = "diag/kudo/serviceaccountlist.yaml"
kmStatefulSetsFile = "diag/kudo/statefulsetlist.yaml"
settingsFile = "diag/settings.yaml"
)

// defaultFileNames - all the files that should be created if no error happens
func defaultFileNames() map[string]struct{} {
return map[string]struct{}{
zkOperatorFile: {},
zkOperatorVersionFile: {},
zkPod2File: {},
zkLog2Container1File: {},
zkServicesFile: {},
zkPod0File: {},
zkLog0Container1File: {},
zkLog0Container2File: {},
zkInstanceFile: {},
zkPod1File: {},
zkLog1Container1File: {},
zkStatefulSetsFile: {},
versionFile: {},
kmServicesFile: {},
kmPodFile: {},
kmLogFile: {},
kmServiceAccountsFile: {},
kmStatefulSetsFile: {},
settingsFile: {},
zkOperatorFile: {},
zkOperatorVersionFile: {},
zkPod2File: {},
zkLog2Container1File: {},
zkServicesFile: {},
zkPod0File: {},
zkLog0Container1File: {},
zkLog0Container2File: {},
zkInstanceFile: {},
zkPod1File: {},
zkLog1Container1File: {},
zkStatefulSetsFile: {},
childOperatorFile: {},
childOperatorVersionFile: {},
childInstanceFile: {},
versionFile: {},
kmServicesFile: {},
kmPodFile: {},
kmLogFile: {},
kmServiceAccountsFile: {},
kmStatefulSetsFile: {},
settingsFile: {},
}
}

// resource to be loaded into fake clients
var (
// resource of the instance for which diagnostics is run
pods corev1.PodList
serviceAccounts corev1.ServiceAccountList
services corev1.ServiceList
statefulsets appsv1.StatefulSetList
pvs corev1.PersistentVolumeList
pvcs corev1.PersistentVolumeClaimList
operator v1beta1.Operator
operatorVersion v1beta1.OperatorVersion
instance v1beta1.Instance
pods corev1.PodList
serviceAccounts corev1.ServiceAccountList
services corev1.ServiceList
statefulsets appsv1.StatefulSetList
pvs corev1.PersistentVolumeList
pvcs corev1.PersistentVolumeClaimList
operator v1beta1.Operator
operatorVersion v1beta1.OperatorVersion
instance v1beta1.Instance
childOperator v1beta1.Operator
childOperatorVersion v1beta1.OperatorVersion
childInstance v1beta1.Instance

// kudo-manager resources
kmNs corev1.Namespace
Expand Down Expand Up @@ -151,6 +160,9 @@ func init() {
mustReadObjectFromYaml(osFs, "testdata/zk_operator.yaml", &operator, check)
mustReadObjectFromYaml(osFs, "testdata/zk_operatorversion.yaml", &operatorVersion, check)
mustReadObjectFromYaml(osFs, "testdata/zk_instance.yaml", &instance, check)
mustReadObjectFromYaml(osFs, "testdata/child_operator.yaml", &childOperator, check)
mustReadObjectFromYaml(osFs, "testdata/child_operatorversion.yaml", &childOperatorVersion, check)
mustReadObjectFromYaml(osFs, "testdata/child_instance.yaml", &childInstance, check)
mustReadObjectFromYaml(osFs, "testdata/kudo_ns.yaml", &kmNs, check)
mustReadObjectFromYaml(osFs, "testdata/kudo_pod.yaml", &kmPod, check)
mustReadObjectFromYaml(osFs, "testdata/kudo_services.yaml", &kmServices, check)
Expand Down Expand Up @@ -181,7 +193,10 @@ func init() {
kudoObjects = objectList{}.
append(&operator).
append(&operatorVersion).
append(&instance)
append(&instance).
append(&childOperator).
append(&childOperatorVersion).
append(&childInstance)
}

func TestCollect_OK(t *testing.T) {
Expand Down Expand Up @@ -210,18 +225,21 @@ func TestCollect_OK(t *testing.T) {
})

var (
collectedPod0 corev1.Pod
collectedPod1 corev1.Pod
collectedPod2 corev1.Pod
collectedKmPod corev1.Pod
collectedServices corev1.ServiceList
collectedStatefulsets appsv1.StatefulSetList
collectedOperator v1beta1.Operator
collectedOperatorVersion v1beta1.OperatorVersion
collectedInstance v1beta1.Instance
collectedKmServices corev1.ServiceList
collectedKmServiceAccounts corev1.ServiceAccountList
collectedKmStatefulsets appsv1.StatefulSetList
collectedPod0 corev1.Pod
collectedPod1 corev1.Pod
collectedPod2 corev1.Pod
collectedKmPod corev1.Pod
collectedServices corev1.ServiceList
collectedStatefulsets appsv1.StatefulSetList
collectedOperator v1beta1.Operator
collectedOperatorVersion v1beta1.OperatorVersion
collectedInstance v1beta1.Instance
collectedChildOperator v1beta1.Operator
collectedChildOperatorVersion v1beta1.OperatorVersion
collectedChildInstance v1beta1.Instance
collectedKmServices corev1.ServiceList
collectedKmServiceAccounts corev1.ServiceAccountList
collectedKmStatefulsets appsv1.StatefulSetList
)

// read the created files and assert no error
Expand All @@ -233,6 +251,9 @@ func TestCollect_OK(t *testing.T) {
mustReadObjectFromYaml(fs, zkInstanceFile, &collectedInstance, assertNilError(t))
mustReadObjectFromYaml(fs, zkPod1File, &collectedPod1, assertNilError(t))
mustReadObjectFromYaml(fs, zkStatefulSetsFile, &collectedStatefulsets, assertNilError(t))
mustReadObjectFromYaml(fs, childOperatorFile, &collectedChildOperator, assertNilError(t))
mustReadObjectFromYaml(fs, childOperatorVersionFile, &collectedChildOperatorVersion, assertNilError(t))
mustReadObjectFromYaml(fs, childInstanceFile, &collectedChildInstance, assertNilError(t))
mustReadObjectFromYaml(fs, kmServicesFile, &collectedKmServices, assertNilError(t))
mustReadObjectFromYaml(fs, kmPodFile, &collectedKmPod, assertNilError(t))
mustReadObjectFromYaml(fs, kmServiceAccountsFile, &collectedKmServiceAccounts, assertNilError(t))
Expand All @@ -247,6 +268,9 @@ func TestCollect_OK(t *testing.T) {
assert.Equal(t, instance, collectedInstance)
assert.Equal(t, pods.Items[1], collectedPod1)
assert.Equal(t, statefulsets, collectedStatefulsets)
assert.Equal(t, childOperator, collectedChildOperator)
assert.Equal(t, childOperatorVersion, collectedChildOperatorVersion)
assert.Equal(t, childInstance, collectedChildInstance)
assert.Equal(t, kmServices, collectedKmServices)
assert.Equal(t, kmPod, collectedKmPod)
assert.Equal(t, kmServiceAccounts, collectedKmServiceAccounts)
Expand Down
31 changes: 31 additions & 0 deletions pkg/kudoctl/cmd/diagnostics/resource_funcs.go
Expand Up @@ -66,6 +66,37 @@ func newKudoResources(options *Options, c *kudo.Client) (*resourceFuncsConfig, e
}, nil
}

func newDependenciesResources(instanceName string, options *Options, c *kudo.Client, s *env.Settings) ([]*resourceFuncsConfig, error) {
instance, err := c.GetInstance(instanceName, s.Namespace)
if err != nil {
return nil, fmt.Errorf("failed to get instance %s/%s: %v", s.Namespace, instanceName, err)
}
if instance == nil {
return nil, fmt.Errorf("instance %s/%s not found", s.Namespace, instanceName)
}

children, err := c.GetChildInstances(instance)
if err != nil {
return nil, fmt.Errorf("failed to get children of instance %s/%s: %v", s.Namespace, instanceName, err)
}

configs := make([]*resourceFuncsConfig, 0, len(children))

for _, child := range children {
child := child

configs = append(configs, &resourceFuncsConfig{
c: c,
ns: s.Namespace,
instanceObj: &child,
opts: metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", kudoutil.OperatorLabel, child.Labels[kudoutil.OperatorLabel])},
logOpts: corev1.PodLogOptions{SinceSeconds: options.LogSince},
})
}

return configs, nil
}

type stringGetter func() string

func (r *resourceFuncsConfig) instance() (runtime.Object, error) {
Expand Down
18 changes: 18 additions & 0 deletions pkg/kudoctl/cmd/diagnostics/runner_helper.go
Expand Up @@ -23,6 +23,24 @@ func diagForInstance(instance string, options *Options, c *kudo.Client, info ver
return err
}

deps, err := newDependenciesResources(instance, options, c, s)
if err != nil {
p.printError(err, DiagDir, "instance")
return err
}

for _, dep := range deps {
// Nest the dependencies in the parents operator directory
root := ctx.operatorDirectory()

depCtx := &processingContext{root: root, instanceName: dep.instanceObj.Name}

runner := runnerForInstance(dep, depCtx)
if err := runner.run(p); err != nil {
return err
}
}

return nil
}

Expand Down
12 changes: 12 additions & 0 deletions pkg/kudoctl/cmd/diagnostics/testdata/child_instance.yaml
@@ -0,0 +1,12 @@
apiVersion: kudo.dev/v1beta1
kind: Instance
metadata:
labels:
kudo.dev/operator: zookeeper-instance-child
name: zookeeper-instance-child-instance
namespace: my-namespace
ownerReferences:
- uid: 4c46f7a2-3571-4047-9a15-be5043c6b357
spec:
operatorVersion:
name: zookeeper-instance-child-0.1.0
5 changes: 5 additions & 0 deletions pkg/kudoctl/cmd/diagnostics/testdata/child_operator.yaml
@@ -0,0 +1,5 @@
apiVersion: kudo.dev/v1beta1
kind: Operator
metadata:
name: zookeeper-instance-child
namespace: my-namespace
@@ -0,0 +1,9 @@
apiVersion: kudo.dev/v1beta1
kind: OperatorVersion
metadata:
name: zookeeper-instance-child-0.1.0
namespace: my-namespace
spec:
operator:
kind: Operator
name: zookeeper-instance-child
19 changes: 0 additions & 19 deletions pkg/kudoctl/cmd/diagnostics/testdata/cluster_role.yaml
@@ -1,23 +1,4 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2020-04-17T13:11:57Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
resourceVersion: "44"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/cluster-admin
uid: 00d4e229-e4ce-43f4-94e9-1c2930af13e3
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
- nonResourceURLs:
- '*'
verbs:
- '*'

0 comments on commit 6fc3086

Please sign in to comment.