diff --git a/pkg/analyze/data_test.go b/pkg/analyze/data_test.go index b75dd9e79..e4710a9c5 100644 --- a/pkg/analyze/data_test.go +++ b/pkg/analyze/data_test.go @@ -7,11 +7,29 @@ import ( //go:embed files/deployments/default.json var defaultDeployments string +//go:embed files/deployments/monitoring.json +var monitoringDeployments string + +//go:embed files/deployments/kube-system.json +var kubeSystemDeployments string + //go:embed files/nodes.json var collectedNodes string //go:embed files/jobs/test.json var testJobs string +//go:embed files/jobs/projectcontour.json +var projectcontourJobs string + +//go:embed files/replicasets/default.json +var defaultReplicaSets string + //go:embed files/replicasets/rook-ceph.json var rookCephReplicaSets string + +//go:embed files/statefulsets/default.json +var defaultStatefulSets string + +//go:embed files/statefulsets/monitoring.json +var monitoringStatefulSets string diff --git a/pkg/analyze/deployment_status.go b/pkg/analyze/deployment_status.go index 1266a4986..5325d9cfe 100644 --- a/pkg/analyze/deployment_status.go +++ b/pkg/analyze/deployment_status.go @@ -59,39 +59,47 @@ func analyzeOneDeploymentStatus(analyzer *troubleshootv1beta2.DeploymentStatus, } func analyzeAllDeploymentStatuses(analyzer *troubleshootv1beta2.DeploymentStatus, getFileContents func(string) (map[string][]byte, error)) ([]*AnalyzeResult, error) { - var fileName string + fileNames := make([]string, 0) if analyzer.Namespace != "" { - fileName = filepath.Join("cluster-resources", "deployments", fmt.Sprintf("%s.json", analyzer.Namespace)) - } else { - fileName = filepath.Join("cluster-resources", "deployments", "*.json") + fileNames = append(fileNames, filepath.Join("cluster-resources", "deployments", fmt.Sprintf("%s.json", analyzer.Namespace))) + } + for _, ns := range analyzer.Namespaces { + fileNames = append(fileNames, filepath.Join("cluster-resources", "deployments", fmt.Sprintf("%s.json", ns))) } - files, err := getFileContents(fileName) - if err != nil { - return nil, errors.Wrap(err, "failed to read collected deployments from file") + // no namespace specified, so we need to analyze all deployments + if len(fileNames) == 0 { + fileNames = append(fileNames, filepath.Join("cluster-resources", "deployments", "*.json")) } results := []*AnalyzeResult{} - for _, collected := range files { - var deployments []appsv1.Deployment - if err := json.Unmarshal(collected, &deployments); err != nil { - return nil, errors.Wrap(err, "failed to unmarshal deployment list") + for _, fileName := range fileNames { + files, err := getFileContents(fileName) + if err != nil { + return nil, errors.Wrap(err, "failed to read collected deployments from file") } - for _, deployment := range deployments { - if deployment.Status.Replicas == deployment.Status.AvailableReplicas { - continue + for _, collected := range files { + var deployments []appsv1.Deployment + if err := json.Unmarshal(collected, &deployments); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal deployment list") } - result := &AnalyzeResult{ - Title: fmt.Sprintf("%s/%s Deployment Status", deployment.Namespace, deployment.Name), - IconKey: "kubernetes_deployment_status", - IconURI: "https://troubleshoot.sh/images/analyzer-icons/deployment-status.svg?w=17&h=17", - IsFail: true, - Message: fmt.Sprintf("The deployment %s/%s has %d/%d replicas", deployment.Namespace, deployment.Name, deployment.Status.ReadyReplicas, deployment.Status.Replicas), - } + for _, deployment := range deployments { + if deployment.Status.Replicas == deployment.Status.AvailableReplicas { + continue + } + + result := &AnalyzeResult{ + Title: fmt.Sprintf("%s/%s Deployment Status", deployment.Namespace, deployment.Name), + IconKey: "kubernetes_deployment_status", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/deployment-status.svg?w=17&h=17", + IsFail: true, + Message: fmt.Sprintf("The deployment %s/%s has %d/%d replicas", deployment.Namespace, deployment.Name, deployment.Status.ReadyReplicas, deployment.Status.Replicas), + } - results = append(results, result) + results = append(results, result) + } } } diff --git a/pkg/analyze/deployment_status_test.go b/pkg/analyze/deployment_status_test.go index c3a4fdfe1..09bb90f25 100644 --- a/pkg/analyze/deployment_status_test.go +++ b/pkg/analyze/deployment_status_test.go @@ -46,7 +46,9 @@ func Test_deploymentStatus(t *testing.T) { }, }, files: map[string][]byte{ - "cluster-resources/deployments/default.json": []byte(defaultDeployments), + "cluster-resources/deployments/default.json": []byte(defaultDeployments), + "cluster-resources/deployments/monitoring.json": []byte(monitoringDeployments), + "cluster-resources/deployments/kube-system.json": []byte(kubeSystemDeployments), }, }, { @@ -80,7 +82,9 @@ func Test_deploymentStatus(t *testing.T) { }, }, files: map[string][]byte{ - "cluster-resources/deployments/default.json": []byte(defaultDeployments), + "cluster-resources/deployments/default.json": []byte(defaultDeployments), + "cluster-resources/deployments/monitoring.json": []byte(monitoringDeployments), + "cluster-resources/deployments/kube-system.json": []byte(kubeSystemDeployments), }, }, { @@ -120,7 +124,40 @@ func Test_deploymentStatus(t *testing.T) { }, }, files: map[string][]byte{ - "cluster-resources/deployments/default.json": []byte(defaultDeployments), + "cluster-resources/deployments/default.json": []byte(defaultDeployments), + "cluster-resources/deployments/monitoring.json": []byte(monitoringDeployments), + "cluster-resources/deployments/kube-system.json": []byte(kubeSystemDeployments), + }, + }, + { + name: "multiple namespaces, 2/3", + analyzer: troubleshootv1beta2.DeploymentStatus{ + Namespaces: []string{"default", "monitoring"}, + }, + expectResult: []*AnalyzeResult{ + { + IsPass: false, + IsWarn: false, + IsFail: true, + Title: "default/kotsadm-web Deployment Status", + Message: "The deployment default/kotsadm-web has 1/2 replicas", + IconKey: "kubernetes_deployment_status", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/deployment-status.svg?w=17&h=17", + }, + { + IsPass: false, + IsWarn: false, + IsFail: true, + Title: "monitoring/prometheus-operator Deployment Status", + Message: "The deployment monitoring/prometheus-operator has 1/2 replicas", + IconKey: "kubernetes_deployment_status", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/deployment-status.svg?w=17&h=17", + }, + }, + files: map[string][]byte{ + "cluster-resources/deployments/default.json": []byte(defaultDeployments), + "cluster-resources/deployments/monitoring.json": []byte(monitoringDeployments), + "cluster-resources/deployments/kube-system.json": []byte(kubeSystemDeployments), }, }, } @@ -130,14 +167,19 @@ func Test_deploymentStatus(t *testing.T) { req := require.New(t) getFiles := func(n string) (map[string][]byte, error) { + if file, ok := test.files[n]; ok { + return map[string][]byte{n: file}, nil + } return test.files, nil } actual, err := analyzeDeploymentStatus(&test.analyzer, getFiles) req.NoError(err) - assert.Equal(t, test.expectResult, actual) - + req.Equal(len(test.expectResult), len(actual)) + for _, a := range actual { + assert.Contains(t, test.expectResult, a) + } }) } } diff --git a/pkg/analyze/files/deployments/default.json b/pkg/analyze/files/deployments/default.json index 0bd65a3e6..c50aad7ff 100644 --- a/pkg/analyze/files/deployments/default.json +++ b/pkg/analyze/files/deployments/default.json @@ -425,7 +425,7 @@ }, "status": { "observedGeneration": 1, - "replicas": 1, + "replicas": 2, "updatedReplicas": 1, "readyReplicas": 1, "availableReplicas": 1, diff --git a/pkg/analyze/files/deployments/kube-system.json b/pkg/analyze/files/deployments/kube-system.json new file mode 100644 index 000000000..a4a518e54 --- /dev/null +++ b/pkg/analyze/files/deployments/kube-system.json @@ -0,0 +1,661 @@ +[ + { + "metadata": { + "name": "coredns", + "namespace": "kube-system", + "selfLink": "/apis/apps/v1/namespaces/kube-system/deployments/coredns", + "uid": "4e008c0d-39fd-4c54-acb7-45ad67c91ef4", + "resourceVersion": "734", + "generation": 1, + "creationTimestamp": "2021-12-17T18:38:57Z", + "labels": { + "k8s-app": "kube-dns" + }, + "annotations": { + "deployment.kubernetes.io/revision": "1" + }, + "managedFields": [ + { + "manager": "kubeadm", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:38:57Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:k8s-app": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:k8s-app": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:k8s-app": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"coredns\"}": { + ".": {}, + "f:args": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:livenessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:initialDelaySeconds": {}, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":53,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + }, + "k:{\"containerPort\":53,\"protocol\":\"UDP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + }, + "k:{\"containerPort\":9153,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + } + }, + "f:readinessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:memory": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:securityContext": { + ".": {}, + "f:allowPrivilegeEscalation": {}, + "f:capabilities": { + ".": {}, + "f:add": {}, + "f:drop": {} + }, + "f:readOnlyRootFilesystem": {} + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/etc/coredns\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:readOnly": {} + } + } + } + }, + "f:dnsPolicy": {}, + "f:nodeSelector": { + ".": {}, + "f:kubernetes.io/os": {} + }, + "f:priorityClassName": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {}, + "f:tolerations": {}, + "f:volumes": { + ".": {}, + "k:{\"name\":\"config-volume\"}": { + ".": {}, + "f:configMap": { + ".": {}, + "f:defaultMode": {}, + "f:items": {}, + "f:name": {} + }, + "f:name": {} + } + } + } + } + } + } + }, + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:39:42Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 2, + "selector": { + "matchLabels": { + "k8s-app": "kube-dns" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "k8s-app": "kube-dns" + } + }, + "spec": { + "volumes": [ + { + "name": "config-volume", + "configMap": { + "name": "coredns", + "items": [ + { + "key": "Corefile", + "path": "Corefile" + } + ], + "defaultMode": 420 + } + } + ], + "containers": [ + { + "name": "coredns", + "image": "k8s.gcr.io/coredns:1.7.0", + "args": [ + "-conf", + "/etc/coredns/Corefile" + ], + "ports": [ + { + "name": "dns", + "containerPort": 53, + "protocol": "UDP" + }, + { + "name": "dns-tcp", + "containerPort": 53, + "protocol": "TCP" + }, + { + "name": "metrics", + "containerPort": 9153, + "protocol": "TCP" + } + ], + "resources": { + "limits": { + "memory": "170Mi" + }, + "requests": { + "cpu": "100m", + "memory": "70Mi" + } + }, + "volumeMounts": [ + { + "name": "config-volume", + "readOnly": true, + "mountPath": "/etc/coredns" + } + ], + "livenessProbe": { + "httpGet": { + "path": "/health", + "port": 8080, + "scheme": "HTTP" + }, + "initialDelaySeconds": 60, + "timeoutSeconds": 5, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 5 + }, + "readinessProbe": { + "httpGet": { + "path": "/ready", + "port": 8181, + "scheme": "HTTP" + }, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent", + "securityContext": { + "capabilities": { + "add": [ + "NET_BIND_SERVICE" + ], + "drop": [ + "all" + ] + }, + "readOnlyRootFilesystem": true, + "allowPrivilegeEscalation": false + } + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "Default", + "nodeSelector": { + "kubernetes.io/os": "linux" + }, + "serviceAccountName": "coredns", + "serviceAccount": "coredns", + "securityContext": {}, + "schedulerName": "default-scheduler", + "tolerations": [ + { + "key": "CriticalAddonsOnly", + "operator": "Exists" + }, + { + "key": "node-role.kubernetes.io/master", + "effect": "NoSchedule" + } + ], + "priorityClassName": "system-cluster-critical" + } + }, + "strategy": { + "type": "RollingUpdate", + "rollingUpdate": { + "maxUnavailable": 1, + "maxSurge": "25%" + } + }, + "revisionHistoryLimit": 10, + "progressDeadlineSeconds": 600 + }, + "status": { + "observedGeneration": 1, + "replicas": 2, + "updatedReplicas": 2, + "readyReplicas": 2, + "availableReplicas": 2, + "conditions": [ + { + "type": "Available", + "status": "True", + "lastUpdateTime": "2021-12-17T18:39:25Z", + "lastTransitionTime": "2021-12-17T18:39:25Z", + "reason": "MinimumReplicasAvailable", + "message": "Deployment has minimum availability." + }, + { + "type": "Progressing", + "status": "True", + "lastUpdateTime": "2021-12-17T18:39:42Z", + "lastTransitionTime": "2021-12-17T18:39:05Z", + "reason": "NewReplicaSetAvailable", + "message": "ReplicaSet \"coredns-f9fd979d6\" has successfully progressed." + } + ] + } + }, + { + "metadata": { + "name": "metrics-server", + "namespace": "kube-system", + "selfLink": "/apis/apps/v1/namespaces/kube-system/deployments/metrics-server", + "uid": "2247dee8-5d1d-4e05-a6e8-a50f15db140b", + "resourceVersion": "2998", + "generation": 1, + "creationTimestamp": "2021-12-17T18:42:38Z", + "labels": { + "k8s-app": "metrics-server" + }, + "annotations": { + "deployment.kubernetes.io/revision": "1", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"k8s-app\":\"metrics-server\"},\"name\":\"metrics-server\",\"namespace\":\"kube-system\"},\"spec\":{\"selector\":{\"matchLabels\":{\"k8s-app\":\"metrics-server\"}},\"template\":{\"metadata\":{\"labels\":{\"k8s-app\":\"metrics-server\"},\"name\":\"metrics-server\"},\"spec\":{\"containers\":[{\"args\":[\"--cert-dir=/tmp\",\"--secure-port=4443\",\"--kubelet-insecure-tls\"],\"image\":\"k8s.gcr.io/metrics-server/metrics-server:v0.3.7\",\"imagePullPolicy\":\"IfNotPresent\",\"name\":\"metrics-server\",\"ports\":[{\"containerPort\":4443,\"name\":\"main-port\",\"protocol\":\"TCP\"}],\"securityContext\":{\"readOnlyRootFilesystem\":true,\"runAsNonRoot\":true,\"runAsUser\":1000},\"volumeMounts\":[{\"mountPath\":\"/tmp\",\"name\":\"tmp-dir\"}]}],\"nodeSelector\":{\"kubernetes.io/os\":\"linux\"},\"serviceAccountName\":\"metrics-server\",\"volumes\":[{\"emptyDir\":{},\"name\":\"tmp-dir\"}]}}}}\n" + }, + "managedFields": [ + { + "manager": "kubectl-client-side-apply", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:42:38Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:k8s-app": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:k8s-app": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:k8s-app": {} + }, + "f:name": {} + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"metrics-server\"}": { + ".": {}, + "f:args": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":4443,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:securityContext": { + ".": {}, + "f:readOnlyRootFilesystem": {}, + "f:runAsNonRoot": {}, + "f:runAsUser": {} + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/tmp\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + } + }, + "f:dnsPolicy": {}, + "f:nodeSelector": { + ".": {}, + "f:kubernetes.io/os": {} + }, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {}, + "f:volumes": { + ".": {}, + "k:{\"name\":\"tmp-dir\"}": { + ".": {}, + "f:emptyDir": {}, + "f:name": {} + } + } + } + } + } + } + }, + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:42:47Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "k8s-app": "metrics-server" + } + }, + "template": { + "metadata": { + "name": "metrics-server", + "creationTimestamp": null, + "labels": { + "k8s-app": "metrics-server" + } + }, + "spec": { + "volumes": [ + { + "name": "tmp-dir", + "emptyDir": {} + } + ], + "containers": [ + { + "name": "metrics-server", + "image": "k8s.gcr.io/metrics-server/metrics-server:v0.3.7", + "args": [ + "--cert-dir=/tmp", + "--secure-port=4443", + "--kubelet-insecure-tls" + ], + "ports": [ + { + "name": "main-port", + "containerPort": 4443, + "protocol": "TCP" + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "tmp-dir", + "mountPath": "/tmp" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent", + "securityContext": { + "runAsUser": 1000, + "runAsNonRoot": true, + "readOnlyRootFilesystem": true + } + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "nodeSelector": { + "kubernetes.io/os": "linux" + }, + "serviceAccountName": "metrics-server", + "serviceAccount": "metrics-server", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + }, + "strategy": { + "type": "RollingUpdate", + "rollingUpdate": { + "maxUnavailable": "25%", + "maxSurge": "25%" + } + }, + "revisionHistoryLimit": 10, + "progressDeadlineSeconds": 600 + }, + "status": { + "observedGeneration": 1, + "replicas": 2, + "updatedReplicas": 1, + "readyReplicas": 1, + "availableReplicas": 1, + "conditions": [ + { + "type": "Available", + "status": "True", + "lastUpdateTime": "2021-12-17T18:42:47Z", + "lastTransitionTime": "2021-12-17T18:42:47Z", + "reason": "MinimumReplicasAvailable", + "message": "Deployment has minimum availability." + }, + { + "type": "Progressing", + "status": "True", + "lastUpdateTime": "2021-12-17T18:42:47Z", + "lastTransitionTime": "2021-12-17T18:42:38Z", + "reason": "NewReplicaSetAvailable", + "message": "ReplicaSet \"metrics-server-56df6d849\" has successfully progressed." + } + ] + } + } + ] + \ No newline at end of file diff --git a/pkg/analyze/files/deployments/monitoring.json b/pkg/analyze/files/deployments/monitoring.json new file mode 100644 index 000000000..636c16d9f --- /dev/null +++ b/pkg/analyze/files/deployments/monitoring.json @@ -0,0 +1,1644 @@ +[ + { + "metadata": { + "name": "grafana", + "namespace": "monitoring", + "selfLink": "/apis/apps/v1/namespaces/monitoring/deployments/grafana", + "uid": "00cd5f1f-2a6b-49a6-8951-2c321187b31e", + "resourceVersion": "2197", + "generation": 1, + "creationTimestamp": "2021-12-17T18:41:27Z", + "labels": { + "app.kubernetes.io/instance": "v0.49.0-17.1.3", + "app.kubernetes.io/managed-by": "Helm", + "app.kubernetes.io/name": "grafana", + "app.kubernetes.io/version": "8.0.5", + "helm.sh/chart": "grafana-6.14.1" + }, + "annotations": { + "deployment.kubernetes.io/revision": "1", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/instance\":\"v0.49.0-17.1.3\",\"app.kubernetes.io/managed-by\":\"Helm\",\"app.kubernetes.io/name\":\"grafana\",\"app.kubernetes.io/version\":\"8.0.5\",\"helm.sh/chart\":\"grafana-6.14.1\"},\"name\":\"grafana\",\"namespace\":\"monitoring\"},\"spec\":{\"replicas\":1,\"revisionHistoryLimit\":10,\"selector\":{\"matchLabels\":{\"app.kubernetes.io/instance\":\"v0.49.0-17.1.3\",\"app.kubernetes.io/name\":\"grafana\"}},\"strategy\":{\"type\":\"RollingUpdate\"},\"template\":{\"metadata\":{\"annotations\":{\"checksum/config\":\"76e4c3d8e9384607b5dafa08c9dd7eaeb44b6d5c224ca070de5b99667138dc04\",\"checksum/dashboards-json-config\":\"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b\",\"checksum/sc-dashboard-provider-config\":\"5f18351bfe1f60ece9f2e169280646d34eb18165e6884855f79bbcd6b92a07f2\"},\"labels\":{\"app.kubernetes.io/instance\":\"v0.49.0-17.1.3\",\"app.kubernetes.io/name\":\"grafana\"}},\"spec\":{\"automountServiceAccountToken\":true,\"containers\":[{\"env\":[{\"name\":\"METHOD\",\"value\":null},{\"name\":\"LABEL\",\"value\":\"grafana_dashboard\"},{\"name\":\"FOLDER\",\"value\":\"/tmp/dashboards\"},{\"name\":\"RESOURCE\",\"value\":\"both\"}],\"image\":\"quay.io/kiwigrid/k8s-sidecar:1.12.2\",\"imagePullPolicy\":\"IfNotPresent\",\"name\":\"grafana-sc-dashboard\",\"resources\":{},\"volumeMounts\":[{\"mountPath\":\"/tmp/dashboards\",\"name\":\"sc-dashboard-volume\"}]},{\"env\":[{\"name\":\"GF_SECURITY_ADMIN_USER\",\"valueFrom\":{\"secretKeyRef\":{\"key\":\"admin-user\",\"name\":\"grafana-admin\"}}},{\"name\":\"GF_SECURITY_ADMIN_PASSWORD\",\"valueFrom\":{\"secretKeyRef\":{\"key\":\"admin-password\",\"name\":\"grafana-admin\"}}},{\"name\":\"GF_PATHS_DATA\",\"value\":\"/var/lib/grafana/\"},{\"name\":\"GF_PATHS_LOGS\",\"value\":\"/var/log/grafana\"},{\"name\":\"GF_PATHS_PLUGINS\",\"value\":\"/var/lib/grafana/plugins\"},{\"name\":\"GF_PATHS_PROVISIONING\",\"value\":\"/etc/grafana/provisioning\"}],\"image\":\"grafana/grafana:8.0.5\",\"imagePullPolicy\":\"IfNotPresent\",\"livenessProbe\":{\"failureThreshold\":10,\"httpGet\":{\"path\":\"/api/health\",\"port\":3000},\"initialDelaySeconds\":60,\"timeoutSeconds\":30},\"name\":\"grafana\",\"ports\":[{\"containerPort\":80,\"name\":\"service\",\"protocol\":\"TCP\"},{\"containerPort\":3000,\"name\":\"grafana\",\"protocol\":\"TCP\"}],\"readinessProbe\":{\"httpGet\":{\"path\":\"/api/health\",\"port\":3000}},\"resources\":{\"limits\":{\"cpu\":\"100m\",\"memory\":\"128Mi\"},\"requests\":{\"cpu\":\"100m\",\"memory\":\"128Mi\"}},\"volumeMounts\":[{\"mountPath\":\"/etc/grafana/grafana.ini\",\"name\":\"config\",\"subPath\":\"grafana.ini\"},{\"mountPath\":\"/var/lib/grafana\",\"name\":\"storage\"},{\"mountPath\":\"/tmp/dashboards\",\"name\":\"sc-dashboard-volume\"},{\"mountPath\":\"/etc/grafana/provisioning/dashboards/sc-dashboardproviders.yaml\",\"name\":\"sc-dashboard-provider\",\"subPath\":\"provider.yaml\"},{\"mountPath\":\"/etc/grafana/provisioning/datasources\",\"name\":\"sc-datasources-volume\"}]}],\"enableServiceLinks\":true,\"initContainers\":[{\"env\":[{\"name\":\"METHOD\",\"value\":\"LIST\"},{\"name\":\"LABEL\",\"value\":\"grafana_datasource\"},{\"name\":\"FOLDER\",\"value\":\"/etc/grafana/provisioning/datasources\"},{\"name\":\"RESOURCE\",\"value\":\"both\"}],\"image\":\"quay.io/kiwigrid/k8s-sidecar:1.12.2\",\"imagePullPolicy\":\"IfNotPresent\",\"name\":\"grafana-sc-datasources\",\"resources\":{},\"volumeMounts\":[{\"mountPath\":\"/etc/grafana/provisioning/datasources\",\"name\":\"sc-datasources-volume\"}]}],\"securityContext\":{\"fsGroup\":472,\"runAsGroup\":472,\"runAsUser\":472},\"serviceAccountName\":\"grafana\",\"volumes\":[{\"configMap\":{\"name\":\"grafana\"},\"name\":\"config\"},{\"emptyDir\":{},\"name\":\"storage\"},{\"emptyDir\":{},\"name\":\"sc-dashboard-volume\"},{\"configMap\":{\"name\":\"grafana-config-dashboards\"},\"name\":\"sc-dashboard-provider\"},{\"emptyDir\":{},\"name\":\"sc-datasources-volume\"}]}}}}\n" + }, + "managedFields": [ + { + "manager": "kubectl-client-side-apply", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:41:27Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/managed-by": {}, + "f:app.kubernetes.io/name": {}, + "f:app.kubernetes.io/version": {}, + "f:helm.sh/chart": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/name": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:checksum/config": {}, + "f:checksum/dashboards-json-config": {}, + "f:checksum/sc-dashboard-provider-config": {} + }, + "f:labels": { + ".": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/name": {} + } + }, + "f:spec": { + "f:automountServiceAccountToken": {}, + "f:containers": { + "k:{\"name\":\"grafana\"}": { + ".": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"GF_PATHS_DATA\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"GF_PATHS_LOGS\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"GF_PATHS_PLUGINS\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"GF_PATHS_PROVISIONING\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"GF_SECURITY_ADMIN_PASSWORD\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"GF_SECURITY_ADMIN_USER\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:livenessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:initialDelaySeconds": {}, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + }, + "k:{\"containerPort\":3000,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + } + }, + "f:readinessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/etc/grafana/grafana.ini\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:subPath": {} + }, + "k:{\"mountPath\":\"/etc/grafana/provisioning/dashboards/sc-dashboardproviders.yaml\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:subPath": {} + }, + "k:{\"mountPath\":\"/etc/grafana/provisioning/datasources\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + }, + "k:{\"mountPath\":\"/tmp/dashboards\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + }, + "k:{\"mountPath\":\"/var/lib/grafana\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"grafana-sc-dashboard\"}": { + ".": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"FOLDER\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"LABEL\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"METHOD\"}": { + ".": {}, + "f:name": {} + }, + "k:{\"name\":\"RESOURCE\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/tmp/dashboards\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:initContainers": { + ".": {}, + "k:{\"name\":\"grafana-sc-datasources\"}": { + ".": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"FOLDER\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"LABEL\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"METHOD\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"RESOURCE\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/etc/grafana/provisioning/datasources\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + } + }, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": { + ".": {}, + "f:fsGroup": {}, + "f:runAsGroup": {}, + "f:runAsUser": {} + }, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {}, + "f:volumes": { + ".": {}, + "k:{\"name\":\"config\"}": { + ".": {}, + "f:configMap": { + ".": {}, + "f:defaultMode": {}, + "f:name": {} + }, + "f:name": {} + }, + "k:{\"name\":\"sc-dashboard-provider\"}": { + ".": {}, + "f:configMap": { + ".": {}, + "f:defaultMode": {}, + "f:name": {} + }, + "f:name": {} + }, + "k:{\"name\":\"sc-dashboard-volume\"}": { + ".": {}, + "f:emptyDir": {}, + "f:name": {} + }, + "k:{\"name\":\"sc-datasources-volume\"}": { + ".": {}, + "f:emptyDir": {}, + "f:name": {} + }, + "k:{\"name\":\"storage\"}": { + ".": {}, + "f:emptyDir": {}, + "f:name": {} + } + } + } + } + } + } + }, + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:41:50Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app.kubernetes.io/instance": "v0.49.0-17.1.3", + "app.kubernetes.io/name": "grafana" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app.kubernetes.io/instance": "v0.49.0-17.1.3", + "app.kubernetes.io/name": "grafana" + }, + "annotations": { + "checksum/config": "76e4c3d8e9384607b5dafa08c9dd7eaeb44b6d5c224ca070de5b99667138dc04", + "checksum/dashboards-json-config": "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b", + "checksum/sc-dashboard-provider-config": "5f18351bfe1f60ece9f2e169280646d34eb18165e6884855f79bbcd6b92a07f2" + } + }, + "spec": { + "volumes": [ + { + "name": "config", + "configMap": { + "name": "grafana", + "defaultMode": 420 + } + }, + { + "name": "storage", + "emptyDir": {} + }, + { + "name": "sc-dashboard-volume", + "emptyDir": {} + }, + { + "name": "sc-dashboard-provider", + "configMap": { + "name": "grafana-config-dashboards", + "defaultMode": 420 + } + }, + { + "name": "sc-datasources-volume", + "emptyDir": {} + } + ], + "initContainers": [ + { + "name": "grafana-sc-datasources", + "image": "quay.io/kiwigrid/k8s-sidecar:1.12.2", + "env": [ + { + "name": "METHOD", + "value": "LIST" + }, + { + "name": "LABEL", + "value": "grafana_datasource" + }, + { + "name": "FOLDER", + "value": "/etc/grafana/provisioning/datasources" + }, + { + "name": "RESOURCE", + "value": "both" + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "sc-datasources-volume", + "mountPath": "/etc/grafana/provisioning/datasources" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + } + ], + "containers": [ + { + "name": "grafana-sc-dashboard", + "image": "quay.io/kiwigrid/k8s-sidecar:1.12.2", + "env": [ + { + "name": "METHOD" + }, + { + "name": "LABEL", + "value": "grafana_dashboard" + }, + { + "name": "FOLDER", + "value": "/tmp/dashboards" + }, + { + "name": "RESOURCE", + "value": "both" + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "sc-dashboard-volume", + "mountPath": "/tmp/dashboards" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "grafana", + "image": "grafana/grafana:8.0.5", + "ports": [ + { + "name": "service", + "containerPort": 80, + "protocol": "TCP" + }, + { + "name": "grafana", + "containerPort": 3000, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "GF_SECURITY_ADMIN_USER", + "valueFrom": { + "secretKeyRef": { + "name": "grafana-admin", + "key": "admin-user" + } + } + }, + { + "name": "GF_SECURITY_ADMIN_PASSWORD", + "valueFrom": { + "secretKeyRef": { + "name": "grafana-admin", + "key": "admin-password" + } + } + }, + { + "name": "GF_PATHS_DATA", + "value": "/var/lib/grafana/" + }, + { + "name": "GF_PATHS_LOGS", + "value": "/var/log/grafana" + }, + { + "name": "GF_PATHS_PLUGINS", + "value": "/var/lib/grafana/plugins" + }, + { + "name": "GF_PATHS_PROVISIONING", + "value": "/etc/grafana/provisioning" + } + ], + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + }, + "volumeMounts": [ + { + "name": "config", + "mountPath": "/etc/grafana/grafana.ini", + "subPath": "grafana.ini" + }, + { + "name": "storage", + "mountPath": "/var/lib/grafana" + }, + { + "name": "sc-dashboard-volume", + "mountPath": "/tmp/dashboards" + }, + { + "name": "sc-dashboard-provider", + "mountPath": "/etc/grafana/provisioning/dashboards/sc-dashboardproviders.yaml", + "subPath": "provider.yaml" + }, + { + "name": "sc-datasources-volume", + "mountPath": "/etc/grafana/provisioning/datasources" + } + ], + "livenessProbe": { + "httpGet": { + "path": "/api/health", + "port": 3000, + "scheme": "HTTP" + }, + "initialDelaySeconds": 60, + "timeoutSeconds": 30, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 10 + }, + "readinessProbe": { + "httpGet": { + "path": "/api/health", + "port": 3000, + "scheme": "HTTP" + }, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "grafana", + "serviceAccount": "grafana", + "automountServiceAccountToken": true, + "securityContext": { + "runAsUser": 472, + "runAsGroup": 472, + "fsGroup": 472 + }, + "schedulerName": "default-scheduler", + "enableServiceLinks": true + } + }, + "strategy": { + "type": "RollingUpdate", + "rollingUpdate": { + "maxUnavailable": "25%", + "maxSurge": "25%" + } + }, + "revisionHistoryLimit": 10, + "progressDeadlineSeconds": 600 + }, + "status": { + "observedGeneration": 1, + "replicas": 1, + "updatedReplicas": 1, + "readyReplicas": 1, + "availableReplicas": 1, + "conditions": [ + { + "type": "Available", + "status": "True", + "lastUpdateTime": "2021-12-17T18:41:50Z", + "lastTransitionTime": "2021-12-17T18:41:50Z", + "reason": "MinimumReplicasAvailable", + "message": "Deployment has minimum availability." + }, + { + "type": "Progressing", + "status": "True", + "lastUpdateTime": "2021-12-17T18:41:50Z", + "lastTransitionTime": "2021-12-17T18:41:27Z", + "reason": "NewReplicaSetAvailable", + "message": "ReplicaSet \"grafana-5b868476b6\" has successfully progressed." + } + ] + } + }, + { + "metadata": { + "name": "kube-state-metrics", + "namespace": "monitoring", + "selfLink": "/apis/apps/v1/namespaces/monitoring/deployments/kube-state-metrics", + "uid": "41cdab80-2fa4-49fc-8ac4-b80dad242855", + "resourceVersion": "2153", + "generation": 1, + "creationTimestamp": "2021-12-17T18:41:27Z", + "labels": { + "app.kubernetes.io/instance": "v0.49.0-17.1.3", + "app.kubernetes.io/managed-by": "Helm", + "app.kubernetes.io/name": "kube-state-metrics", + "app.kubernetes.io/version": "2.1.0", + "helm.sh/chart": "kube-state-metrics-3.4.1" + }, + "annotations": { + "deployment.kubernetes.io/revision": "1", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/instance\":\"v0.49.0-17.1.3\",\"app.kubernetes.io/managed-by\":\"Helm\",\"app.kubernetes.io/name\":\"kube-state-metrics\",\"app.kubernetes.io/version\":\"2.1.0\",\"helm.sh/chart\":\"kube-state-metrics-3.4.1\"},\"name\":\"kube-state-metrics\",\"namespace\":\"monitoring\"},\"spec\":{\"replicas\":1,\"selector\":{\"matchLabels\":{\"app.kubernetes.io/name\":\"kube-state-metrics\"}},\"template\":{\"metadata\":{\"labels\":{\"app.kubernetes.io/instance\":\"v0.49.0-17.1.3\",\"app.kubernetes.io/name\":\"kube-state-metrics\"}},\"spec\":{\"containers\":[{\"args\":[\"--port=8080\",\"--resources=certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,limitranges,mutatingwebhookconfigurations,namespaces,networkpolicies,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses,validatingwebhookconfigurations,volumeattachments\",\"--telemetry-port=8081\"],\"image\":\"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.1.0\",\"imagePullPolicy\":\"IfNotPresent\",\"livenessProbe\":{\"httpGet\":{\"path\":\"/healthz\",\"port\":8080},\"initialDelaySeconds\":5,\"timeoutSeconds\":5},\"name\":\"kube-state-metrics\",\"ports\":[{\"containerPort\":8080}],\"readinessProbe\":{\"httpGet\":{\"path\":\"/\",\"port\":8080},\"initialDelaySeconds\":5,\"timeoutSeconds\":5}}],\"hostNetwork\":false,\"securityContext\":{\"fsGroup\":65534,\"runAsGroup\":65534,\"runAsUser\":65534},\"serviceAccountName\":\"kube-state-metrics\"}}}}\n" + }, + "managedFields": [ + { + "manager": "kubectl-client-side-apply", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:41:27Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/managed-by": {}, + "f:app.kubernetes.io/name": {}, + "f:app.kubernetes.io/version": {}, + "f:helm.sh/chart": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app.kubernetes.io/name": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/name": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"kube-state-metrics\"}": { + ".": {}, + "f:args": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:livenessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:initialDelaySeconds": {}, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":8080,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:readinessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:initialDelaySeconds": {}, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": { + ".": {}, + "f:fsGroup": {}, + "f:runAsGroup": {}, + "f:runAsUser": {} + }, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {} + } + } + } + } + }, + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:41:46Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app.kubernetes.io/name": "kube-state-metrics" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app.kubernetes.io/instance": "v0.49.0-17.1.3", + "app.kubernetes.io/name": "kube-state-metrics" + } + }, + "spec": { + "containers": [ + { + "name": "kube-state-metrics", + "image": "k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.1.0", + "args": [ + "--port=8080", + "--resources=certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,limitranges,mutatingwebhookconfigurations,namespaces,networkpolicies,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses,validatingwebhookconfigurations,volumeattachments", + "--telemetry-port=8081" + ], + "ports": [ + { + "containerPort": 8080, + "protocol": "TCP" + } + ], + "resources": {}, + "livenessProbe": { + "httpGet": { + "path": "/healthz", + "port": 8080, + "scheme": "HTTP" + }, + "initialDelaySeconds": 5, + "timeoutSeconds": 5, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "readinessProbe": { + "httpGet": { + "path": "/", + "port": 8080, + "scheme": "HTTP" + }, + "initialDelaySeconds": 5, + "timeoutSeconds": 5, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "kube-state-metrics", + "serviceAccount": "kube-state-metrics", + "securityContext": { + "runAsUser": 65534, + "runAsGroup": 65534, + "fsGroup": 65534 + }, + "schedulerName": "default-scheduler" + } + }, + "strategy": { + "type": "RollingUpdate", + "rollingUpdate": { + "maxUnavailable": "25%", + "maxSurge": "25%" + } + }, + "revisionHistoryLimit": 10, + "progressDeadlineSeconds": 600 + }, + "status": { + "observedGeneration": 1, + "replicas": 1, + "updatedReplicas": 1, + "readyReplicas": 1, + "availableReplicas": 1, + "conditions": [ + { + "type": "Available", + "status": "True", + "lastUpdateTime": "2021-12-17T18:41:46Z", + "lastTransitionTime": "2021-12-17T18:41:46Z", + "reason": "MinimumReplicasAvailable", + "message": "Deployment has minimum availability." + }, + { + "type": "Progressing", + "status": "True", + "lastUpdateTime": "2021-12-17T18:41:46Z", + "lastTransitionTime": "2021-12-17T18:41:27Z", + "reason": "NewReplicaSetAvailable", + "message": "ReplicaSet \"kube-state-metrics-f97897479\" has successfully progressed." + } + ] + } + }, + { + "metadata": { + "name": "prometheus-adapter", + "namespace": "monitoring", + "selfLink": "/apis/apps/v1/namespaces/monitoring/deployments/prometheus-adapter", + "uid": "4fed14e4-17a1-4389-a30e-20bd9f75a9cb", + "resourceVersion": "2290", + "generation": 1, + "creationTimestamp": "2021-12-17T18:41:27Z", + "labels": { + "app": "prometheus-adapter", + "chart": "prometheus-adapter-2.15.2", + "heritage": "Helm", + "release": "v0.49.0-17.1.3" + }, + "annotations": { + "deployment.kubernetes.io/revision": "1", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"prometheus-adapter\",\"chart\":\"prometheus-adapter-2.15.2\",\"heritage\":\"Helm\",\"release\":\"v0.49.0-17.1.3\"},\"name\":\"prometheus-adapter\",\"namespace\":\"monitoring\"},\"spec\":{\"replicas\":1,\"selector\":{\"matchLabels\":{\"app\":\"prometheus-adapter\",\"release\":\"v0.49.0-17.1.3\"}},\"strategy\":{\"rollingUpdate\":{\"maxSurge\":\"25%\",\"maxUnavailable\":\"25%\"},\"type\":\"RollingUpdate\"},\"template\":{\"metadata\":{\"annotations\":{\"checksum/config\":\"89f5608c27af8dcbe0df07191295c0195b7409f20fab98f2b6458cb8a0583581\"},\"labels\":{\"app\":\"prometheus-adapter\",\"chart\":\"prometheus-adapter-2.15.2\",\"heritage\":\"Helm\",\"release\":\"v0.49.0-17.1.3\"},\"name\":\"prometheus-adapter\"},\"spec\":{\"affinity\":{},\"containers\":[{\"args\":[\"/adapter\",\"--secure-port=6443\",\"--cert-dir=/tmp/cert\",\"--logtostderr=true\",\"--prometheus-url=http://prometheus.default.svc:9090\",\"--metrics-relist-interval=1m\",\"--v=4\",\"--config=/etc/adapter/config.yaml\"],\"image\":\"directxman12/k8s-prometheus-adapter-amd64:v0.8.4\",\"imagePullPolicy\":\"IfNotPresent\",\"livenessProbe\":{\"httpGet\":{\"path\":\"/healthz\",\"port\":\"https\",\"scheme\":\"HTTPS\"},\"initialDelaySeconds\":30,\"timeoutSeconds\":5},\"name\":\"prometheus-adapter\",\"ports\":[{\"containerPort\":6443,\"name\":\"https\"}],\"readinessProbe\":{\"httpGet\":{\"path\":\"/healthz\",\"port\":\"https\",\"scheme\":\"HTTPS\"},\"initialDelaySeconds\":30,\"timeoutSeconds\":5},\"securityContext\":{\"allowPrivilegeEscalation\":false,\"capabilities\":{\"drop\":[\"all\"]},\"readOnlyRootFilesystem\":true,\"runAsNonRoot\":true,\"runAsUser\":10001},\"volumeMounts\":[{\"mountPath\":\"/etc/adapter/\",\"name\":\"config\",\"readOnly\":true},{\"mountPath\":\"/tmp\",\"name\":\"tmp\"}]}],\"nodeSelector\":{},\"priorityClassName\":null,\"securityContext\":{\"fsGroup\":10001},\"serviceAccountName\":\"prometheus-adapter\",\"tolerations\":[],\"volumes\":[{\"configMap\":{\"name\":\"prometheus-adapter\"},\"name\":\"config\"},{\"emptyDir\":{},\"name\":\"tmp\"}]}}}}\n" + }, + "managedFields": [ + { + "manager": "kubectl-client-side-apply", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:41:27Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:chart": {}, + "f:heritage": {}, + "f:release": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:release": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:checksum/config": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:chart": {}, + "f:heritage": {}, + "f:release": {} + }, + "f:name": {} + }, + "f:spec": { + "f:affinity": {}, + "f:containers": { + "k:{\"name\":\"prometheus-adapter\"}": { + ".": {}, + "f:args": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:livenessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:initialDelaySeconds": {}, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":6443,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + } + }, + "f:readinessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:initialDelaySeconds": {}, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:resources": {}, + "f:securityContext": { + ".": {}, + "f:allowPrivilegeEscalation": {}, + "f:capabilities": { + ".": {}, + "f:drop": {} + }, + "f:readOnlyRootFilesystem": {}, + "f:runAsNonRoot": {}, + "f:runAsUser": {} + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/etc/adapter/\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:readOnly": {} + }, + "k:{\"mountPath\":\"/tmp\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": { + ".": {}, + "f:fsGroup": {} + }, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {}, + "f:volumes": { + ".": {}, + "k:{\"name\":\"config\"}": { + ".": {}, + "f:configMap": { + ".": {}, + "f:defaultMode": {}, + "f:name": {} + }, + "f:name": {} + }, + "k:{\"name\":\"tmp\"}": { + ".": {}, + "f:emptyDir": {}, + "f:name": {} + } + } + } + } + } + } + }, + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:42:07Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app": "prometheus-adapter", + "release": "v0.49.0-17.1.3" + } + }, + "template": { + "metadata": { + "name": "prometheus-adapter", + "creationTimestamp": null, + "labels": { + "app": "prometheus-adapter", + "chart": "prometheus-adapter-2.15.2", + "heritage": "Helm", + "release": "v0.49.0-17.1.3" + }, + "annotations": { + "checksum/config": "89f5608c27af8dcbe0df07191295c0195b7409f20fab98f2b6458cb8a0583581" + } + }, + "spec": { + "volumes": [ + { + "name": "config", + "configMap": { + "name": "prometheus-adapter", + "defaultMode": 420 + } + }, + { + "name": "tmp", + "emptyDir": {} + } + ], + "containers": [ + { + "name": "prometheus-adapter", + "image": "directxman12/k8s-prometheus-adapter-amd64:v0.8.4", + "args": [ + "/adapter", + "--secure-port=6443", + "--cert-dir=/tmp/cert", + "--logtostderr=true", + "--prometheus-url=http://prometheus.default.svc:9090", + "--metrics-relist-interval=1m", + "--v=4", + "--config=/etc/adapter/config.yaml" + ], + "ports": [ + { + "name": "https", + "containerPort": 6443, + "protocol": "TCP" + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "config", + "readOnly": true, + "mountPath": "/etc/adapter/" + }, + { + "name": "tmp", + "mountPath": "/tmp" + } + ], + "livenessProbe": { + "httpGet": { + "path": "/healthz", + "port": "https", + "scheme": "HTTPS" + }, + "initialDelaySeconds": 30, + "timeoutSeconds": 5, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "readinessProbe": { + "httpGet": { + "path": "/healthz", + "port": "https", + "scheme": "HTTPS" + }, + "initialDelaySeconds": 30, + "timeoutSeconds": 5, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent", + "securityContext": { + "capabilities": { + "drop": [ + "all" + ] + }, + "runAsUser": 10001, + "runAsNonRoot": true, + "readOnlyRootFilesystem": true, + "allowPrivilegeEscalation": false + } + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "prometheus-adapter", + "serviceAccount": "prometheus-adapter", + "securityContext": { + "fsGroup": 10001 + }, + "affinity": {}, + "schedulerName": "default-scheduler" + } + }, + "strategy": { + "type": "RollingUpdate", + "rollingUpdate": { + "maxUnavailable": "25%", + "maxSurge": "25%" + } + }, + "revisionHistoryLimit": 10, + "progressDeadlineSeconds": 600 + }, + "status": { + "observedGeneration": 1, + "replicas": 1, + "updatedReplicas": 1, + "readyReplicas": 1, + "availableReplicas": 1, + "conditions": [ + { + "type": "Available", + "status": "True", + "lastUpdateTime": "2021-12-17T18:42:07Z", + "lastTransitionTime": "2021-12-17T18:42:07Z", + "reason": "MinimumReplicasAvailable", + "message": "Deployment has minimum availability." + }, + { + "type": "Progressing", + "status": "True", + "lastUpdateTime": "2021-12-17T18:42:07Z", + "lastTransitionTime": "2021-12-17T18:41:27Z", + "reason": "NewReplicaSetAvailable", + "message": "ReplicaSet \"prometheus-adapter-75c7788d57\" has successfully progressed." + } + ] + } + }, + { + "metadata": { + "name": "prometheus-operator", + "namespace": "monitoring", + "selfLink": "/apis/apps/v1/namespaces/monitoring/deployments/prometheus-operator", + "uid": "e619939c-7c41-4a30-8f13-3cf1ad50b4f4", + "resourceVersion": "1813", + "generation": 1, + "creationTimestamp": "2021-12-17T18:41:27Z", + "labels": { + "app": "kube-prometheus-stack-operator", + "app.kubernetes.io/instance": "v0.49.0-17.1.3", + "app.kubernetes.io/managed-by": "Helm", + "app.kubernetes.io/part-of": "kube-prometheus-stack", + "app.kubernetes.io/version": "17.1.3", + "chart": "kube-prometheus-stack-17.1.3", + "heritage": "Helm", + "release": "v0.49.0-17.1.3" + }, + "annotations": { + "deployment.kubernetes.io/revision": "1", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"kube-prometheus-stack-operator\",\"app.kubernetes.io/instance\":\"v0.49.0-17.1.3\",\"app.kubernetes.io/managed-by\":\"Helm\",\"app.kubernetes.io/part-of\":\"kube-prometheus-stack\",\"app.kubernetes.io/version\":\"17.1.3\",\"chart\":\"kube-prometheus-stack-17.1.3\",\"heritage\":\"Helm\",\"release\":\"v0.49.0-17.1.3\"},\"name\":\"prometheus-operator\",\"namespace\":\"monitoring\"},\"spec\":{\"replicas\":1,\"selector\":{\"matchLabels\":{\"app\":\"kube-prometheus-stack-operator\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"kube-prometheus-stack-operator\",\"app.kubernetes.io/instance\":\"v0.49.0-17.1.3\",\"app.kubernetes.io/managed-by\":\"Helm\",\"app.kubernetes.io/part-of\":\"kube-prometheus-stack\",\"app.kubernetes.io/version\":\"17.1.3\",\"chart\":\"kube-prometheus-stack-17.1.3\",\"heritage\":\"Helm\",\"release\":\"v0.49.0-17.1.3\"}},\"spec\":{\"containers\":[{\"args\":[\"--kubelet-service=kube-system/prometheus-kubelet\",\"--localhost=***HIDDEN***\",\"--prometheus-config-reloader=quay.io/prometheus-operator/prometheus-config-reloader:v0.49.0\",\"--config-reloader-cpu=100m\",\"--config-reloader-memory=50Mi\",\"--thanos-default-base-image=quay.io/thanos/thanos:v0.17.2\"],\"image\":\"quay.io/prometheus-operator/prometheus-operator:v0.49.0\",\"imagePullPolicy\":\"IfNotPresent\",\"name\":\"kube-prometheus-stack\",\"ports\":[{\"containerPort\":8080,\"name\":\"http\"}],\"resources\":{\"limits\":{\"cpu\":\"200m\",\"memory\":\"200Mi\"},\"requests\":{\"cpu\":\"100m\",\"memory\":\"100Mi\"}},\"securityContext\":{\"allowPrivilegeEscalation\":false,\"readOnlyRootFilesystem\":true}}],\"securityContext\":{\"fsGroup\":65534,\"runAsGroup\":65534,\"runAsNonRoot\":true,\"runAsUser\":65534},\"serviceAccountName\":\"prometheus-operator\"}}}}\n" + }, + "managedFields": [ + { + "manager": "kubectl-client-side-apply", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:41:27Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/managed-by": {}, + "f:app.kubernetes.io/part-of": {}, + "f:app.kubernetes.io/version": {}, + "f:chart": {}, + "f:heritage": {}, + "f:release": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/managed-by": {}, + "f:app.kubernetes.io/part-of": {}, + "f:app.kubernetes.io/version": {}, + "f:chart": {}, + "f:heritage": {}, + "f:release": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"kube-prometheus-stack\"}": { + ".": {}, + "f:args": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":8080,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + } + }, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:securityContext": { + ".": {}, + "f:allowPrivilegeEscalation": {}, + "f:readOnlyRootFilesystem": {} + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": { + ".": {}, + "f:fsGroup": {}, + "f:runAsGroup": {}, + "f:runAsNonRoot": {}, + "f:runAsUser": {} + }, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {} + } + } + } + } + }, + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:41:30Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app": "kube-prometheus-stack-operator" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "kube-prometheus-stack-operator", + "app.kubernetes.io/instance": "v0.49.0-17.1.3", + "app.kubernetes.io/managed-by": "Helm", + "app.kubernetes.io/part-of": "kube-prometheus-stack", + "app.kubernetes.io/version": "17.1.3", + "chart": "kube-prometheus-stack-17.1.3", + "heritage": "Helm", + "release": "v0.49.0-17.1.3" + } + }, + "spec": { + "containers": [ + { + "name": "kube-prometheus-stack", + "image": "quay.io/prometheus-operator/prometheus-operator:v0.49.0", + "args": [ + "--kubelet-service=kube-system/prometheus-kubelet", + "--localhost=***HIDDEN***", + "--prometheus-config-reloader=quay.io/prometheus-operator/prometheus-config-reloader:v0.49.0", + "--config-reloader-cpu=100m", + "--config-reloader-memory=50Mi", + "--thanos-default-base-image=quay.io/thanos/thanos:v0.17.2" + ], + "ports": [ + { + "name": "http", + "containerPort": 8080, + "protocol": "TCP" + } + ], + "resources": { + "limits": { + "cpu": "200m", + "memory": "200Mi" + }, + "requests": { + "cpu": "100m", + "memory": "100Mi" + } + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent", + "securityContext": { + "readOnlyRootFilesystem": true, + "allowPrivilegeEscalation": false + } + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "prometheus-operator", + "serviceAccount": "prometheus-operator", + "securityContext": { + "runAsUser": 65534, + "runAsGroup": 65534, + "runAsNonRoot": true, + "fsGroup": 65534 + }, + "schedulerName": "default-scheduler" + } + }, + "strategy": { + "type": "RollingUpdate", + "rollingUpdate": { + "maxUnavailable": "25%", + "maxSurge": "25%" + } + }, + "revisionHistoryLimit": 10, + "progressDeadlineSeconds": 600 + }, + "status": { + "observedGeneration": 1, + "replicas": 2, + "updatedReplicas": 1, + "readyReplicas": 1, + "availableReplicas": 1, + "conditions": [ + { + "type": "Available", + "status": "True", + "lastUpdateTime": "2021-12-17T18:41:30Z", + "lastTransitionTime": "2021-12-17T18:41:30Z", + "reason": "MinimumReplicasAvailable", + "message": "Deployment has minimum availability." + }, + { + "type": "Progressing", + "status": "True", + "lastUpdateTime": "2021-12-17T18:41:30Z", + "lastTransitionTime": "2021-12-17T18:41:27Z", + "reason": "NewReplicaSetAvailable", + "message": "ReplicaSet \"prometheus-operator-7f6d8fdc86\" has successfully progressed." + } + ] + } + } + ] + \ No newline at end of file diff --git a/pkg/analyze/files/jobs/projectcontour.json b/pkg/analyze/files/jobs/projectcontour.json new file mode 100644 index 000000000..fc128c110 --- /dev/null +++ b/pkg/analyze/files/jobs/projectcontour.json @@ -0,0 +1,198 @@ +[ + { + "metadata": { + "name": "contour-certgen-v1.19.1", + "namespace": "projectcontour", + "selfLink": "/apis/batch/v1/namespaces/projectcontour/jobs/contour-certgen-v1.19.1", + "uid": "416a2a9d-b862-47b8-93d9-160775641fbe", + "resourceVersion": "1386", + "creationTimestamp": "2021-12-17T18:41:14Z", + "labels": { + "app": "contour-certgen", + "controller-uid": "416a2a9d-b862-47b8-93d9-160775641fbe", + "job-name": "contour-certgen-v1.19.1" + }, + "annotations": { + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"batch/v1\",\"kind\":\"Job\",\"metadata\":{\"annotations\":{},\"name\":\"contour-certgen-v1.19.1\",\"namespace\":\"projectcontour\"},\"spec\":{\"backoffLimit\":1,\"completions\":1,\"parallelism\":1,\"template\":{\"metadata\":{\"labels\":{\"app\":\"contour-certgen\"}},\"spec\":{\"containers\":[{\"command\":[\"contour\",\"certgen\",\"--kube\",\"--incluster\",\"--overwrite\",\"--secrets-format=compact\",\"--namespace=$(CONTOUR_NAMESPACE)\"],\"env\":[{\"name\":\"CONTOUR_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}}],\"image\":\"ghcr.io/projectcontour/contour:v1.19.1\",\"imagePullPolicy\":\"IfNotPresent\",\"name\":\"contour\"}],\"restartPolicy\":\"Never\",\"securityContext\":{\"runAsGroup\":65534,\"runAsNonRoot\":true,\"runAsUser\":65534},\"serviceAccountName\":\"contour-certgen\"}},\"ttlSecondsAfterFinished\":0}}\n" + }, + "managedFields": [ + { + "manager": "kubectl-client-side-apply", + "operation": "Update", + "apiVersion": "batch/v1", + "time": "2021-12-17T18:41:14Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:app": {} + } + }, + "f:spec": { + "f:backoffLimit": {}, + "f:completions": {}, + "f:parallelism": {}, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"contour\"}": { + ".": {}, + "f:command": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"CONTOUR_NAMESPACE\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:fieldRef": { + ".": {}, + "f:apiVersion": {}, + "f:fieldPath": {} + } + } + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": { + ".": {}, + "f:runAsGroup": {}, + "f:runAsNonRoot": {}, + "f:runAsUser": {} + }, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "f:ttlSecondsAfterFinished": {} + } + } + }, + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "batch/v1", + "time": "2021-12-17T18:41:17Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:completionTime": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Complete\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:startTime": {}, + "f:succeeded": {} + } + } + } + ] + }, + "spec": { + "parallelism": 1, + "completions": 1, + "backoffLimit": 1, + "selector": { + "matchLabels": { + "controller-uid": "416a2a9d-b862-47b8-93d9-160775641fbe" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "contour-certgen", + "controller-uid": "416a2a9d-b862-47b8-93d9-160775641fbe", + "job-name": "contour-certgen-v1.19.1" + } + }, + "spec": { + "containers": [ + { + "name": "contour", + "image": "ghcr.io/projectcontour/contour:v1.19.1", + "command": [ + "contour", + "certgen", + "--kube", + "--incluster", + "--overwrite", + "--secrets-format=compact", + "--namespace=$(CONTOUR_NAMESPACE)" + ], + "env": [ + { + "name": "CONTOUR_NAMESPACE", + "valueFrom": { + "fieldRef": { + "apiVersion": "v1", + "fieldPath": "metadata.namespace" + } + } + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Never", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "contour-certgen", + "serviceAccount": "contour-certgen", + "securityContext": { + "runAsUser": 65534, + "runAsGroup": 65534, + "runAsNonRoot": true + }, + "schedulerName": "default-scheduler" + } + } + }, + "status": { + "conditions": [ + { + "type": "Complete", + "status": "True", + "lastProbeTime": "2021-12-17T18:41:17Z", + "lastTransitionTime": "2021-12-17T18:41:17Z" + } + ], + "startTime": "2021-12-17T18:41:14Z", + "completionTime": "2021-12-17T18:41:17Z", + "succeeded": 0, + "failed": 1 + } + } + ] + \ No newline at end of file diff --git a/pkg/analyze/files/replicasets/default.json b/pkg/analyze/files/replicasets/default.json new file mode 100644 index 000000000..544b87a45 --- /dev/null +++ b/pkg/analyze/files/replicasets/default.json @@ -0,0 +1,1443 @@ +[ + { + "metadata": { + "name": "kotsadm-f98ff7d75", + "namespace": "default", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/kotsadm-f98ff7d75", + "uid": "40e57483-79f2-45f7-968e-3ef05d4538c0", + "resourceVersion": "2398", + "generation": 1, + "creationTimestamp": "2021-12-17T18:41:34Z", + "labels": { + "app": "kotsadm", + "kots.io/backup": "velero", + "kots.io/kotsadm": "true", + "pod-template-hash": "f98ff7d75" + }, + "annotations": { + "deployment.kubernetes.io/desired-replicas": "1", + "deployment.kubernetes.io/max-replicas": "2", + "deployment.kubernetes.io/revision": "1" + }, + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "kind": "Deployment", + "name": "kotsadm", + "uid": "8195922b-137d-4a0a-b3c4-4458e39d9e94", + "controller": true, + "blockOwnerDeletion": true + } + ], + "managedFields": [ + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:42:21Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:kots.io/backup": {}, + "f:kots.io/kotsadm": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"8195922b-137d-4a0a-b3c4-4458e39d9e94\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:backup.velero.io/backup-volumes": {}, + "f:pre.hook.backup.velero.io/command": {}, + "f:pre.hook.backup.velero.io/timeout": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:kots.io/backup": {}, + "f:kots.io/kotsadm": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"kotsadm\"}": { + ".": {}, + "f:args": {}, + "f:command": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"API_ADVERTISE_ENDPOINT\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"API_ENCRYPTION_KEY\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"API_ENDPOINT\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"AUTO_CREATE_CLUSTER\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"AUTO_CREATE_CLUSTER_NAME\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"AUTO_CREATE_CLUSTER_TOKEN\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"DEX_PGPASSWORD\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"KURL_INSTALL_ID\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"KURL_PROXY_TLS_CERT_PATH\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"POD_NAMESPACE\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:fieldRef": { + ".": {}, + "f:apiVersion": {}, + "f:fieldPath": {} + } + } + }, + "k:{\"name\":\"POD_OWNER_KIND\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"POSTGRES_PASSWORD\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"POSTGRES_URI\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"PROMETHEUS_ADDRESS\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"S3_ACCESS_KEY_ID\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"S3_BUCKET_ENDPOINT\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"S3_BUCKET_NAME\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"S3_ENDPOINT\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"S3_SECRET_ACCESS_KEY\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"SESSION_KEY\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"SHARED_PASSWORD_BCRYPT\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":3000,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + } + }, + "f:readinessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:initialDelaySeconds": {}, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/backup\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + }, + "k:{\"mountPath\":\"/etc/kubernetes/pki/kubelet\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:readOnly": {} + }, + "k:{\"mountPath\":\"/etc/kurl-proxy/ca\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:readOnly": {} + }, + "k:{\"mountPath\":\"/etc/ssl/certs/ca-certificates.crt\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + }, + "k:{\"mountPath\":\"/scripts/start-kotsadm-web.sh\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:subPath": {} + } + } + } + }, + "f:dnsPolicy": {}, + "f:initContainers": { + ".": {}, + "k:{\"name\":\"restore-db\"}": { + ".": {}, + "f:command": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"POSTGRES_PASSWORD\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/backup\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"restore-s3\"}": { + ".": {}, + "f:command": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"S3_ACCESS_KEY_ID\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"S3_BUCKET_ENDPOINT\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"S3_BUCKET_NAME\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"S3_ENDPOINT\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"S3_SECRET_ACCESS_KEY\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/backup\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"schemahero-apply\"}": { + ".": {}, + "f:args": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"SCHEMAHERO_DDL\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"SCHEMAHERO_DRIVER\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"SCHEMAHERO_URI\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/migrations\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"schemahero-plan\"}": { + ".": {}, + "f:args": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"SCHEMAHERO_DRIVER\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"SCHEMAHERO_OUT\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"SCHEMAHERO_SPEC_FILE\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"SCHEMAHERO_URI\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/migrations\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + } + }, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": { + ".": {}, + "f:runAsUser": {} + }, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {}, + "f:volumes": { + ".": {}, + "k:{\"name\":\"backup\"}": { + ".": {}, + "f:emptyDir": {}, + "f:name": {} + }, + "k:{\"name\":\"host-cacerts\"}": { + ".": {}, + "f:hostPath": { + ".": {}, + "f:path": {}, + "f:type": {} + }, + "f:name": {} + }, + "k:{\"name\":\"kotsadm-web-scripts\"}": { + ".": {}, + "f:configMap": { + ".": {}, + "f:defaultMode": {}, + "f:name": {} + }, + "f:name": {} + }, + "k:{\"name\":\"kubelet-client-cert\"}": { + ".": {}, + "f:name": {}, + "f:secret": { + ".": {}, + "f:defaultMode": {}, + "f:secretName": {} + } + }, + "k:{\"name\":\"kurl-proxy-kotsadm-tls-cert\"}": { + ".": {}, + "f:name": {}, + "f:secret": { + ".": {}, + "f:defaultMode": {}, + "f:secretName": {} + } + }, + "k:{\"name\":\"migrations\"}": { + ".": {}, + "f:emptyDir": { + ".": {}, + "f:medium": {} + }, + "f:name": {} + } + } + } + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:fullyLabeledReplicas": {}, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app": "kotsadm", + "pod-template-hash": "f98ff7d75" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "kotsadm", + "kots.io/backup": "velero", + "kots.io/kotsadm": "true", + "pod-template-hash": "f98ff7d75" + }, + "annotations": { + "backup.velero.io/backup-volumes": "backup", + "pre.hook.backup.velero.io/command": "[\"/backup.sh\"]", + "pre.hook.backup.velero.io/timeout": "10m" + } + }, + "spec": { + "volumes": [ + { + "name": "host-cacerts", + "hostPath": { + "path": "/etc/ssl/certs/ca-certificates.crt", + "type": "File" + } + }, + { + "name": "kubelet-client-cert", + "secret": { + "secretName": "kubelet-client-cert", + "defaultMode": 420 + } + }, + { + "name": "kurl-proxy-kotsadm-tls-cert", + "secret": { + "secretName": "kotsadm-tls", + "defaultMode": 420 + } + }, + { + "name": "kotsadm-web-scripts", + "configMap": { + "name": "kotsadm-web-scripts", + "defaultMode": 511 + } + }, + { + "name": "backup", + "emptyDir": {} + }, + { + "name": "migrations", + "emptyDir": { + "medium": "Memory" + } + } + ], + "initContainers": [ + { + "name": "schemahero-plan", + "image": "kotsadm/kotsadm-migrations:v1.58.2", + "args": [ + "plan" + ], + "env": [ + { + "name": "SCHEMAHERO_DRIVER", + "value": "postgres" + }, + { + "name": "SCHEMAHERO_SPEC_FILE", + "value": "/tables" + }, + { + "name": "SCHEMAHERO_URI", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-postgres", + "key": "uri" + } + } + }, + { + "name": "SCHEMAHERO_OUT", + "value": "/migrations/plan.yaml" + } + ], + "resources": { + "limits": { + "cpu": "100m", + "memory": "100Mi" + }, + "requests": { + "cpu": "50m", + "memory": "50Mi" + } + }, + "volumeMounts": [ + { + "name": "migrations", + "mountPath": "/migrations" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "schemahero-apply", + "image": "kotsadm/kotsadm-migrations:v1.58.2", + "args": [ + "apply" + ], + "env": [ + { + "name": "SCHEMAHERO_DRIVER", + "value": "postgres" + }, + { + "name": "SCHEMAHERO_DDL", + "value": "/migrations/plan.yaml" + }, + { + "name": "SCHEMAHERO_URI", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-postgres", + "key": "uri" + } + } + } + ], + "resources": { + "limits": { + "cpu": "100m", + "memory": "100Mi" + }, + "requests": { + "cpu": "50m", + "memory": "50Mi" + } + }, + "volumeMounts": [ + { + "name": "migrations", + "mountPath": "/migrations" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "restore-db", + "image": "kotsadm/kotsadm:v1.58.2", + "command": [ + "/restore-db.sh" + ], + "env": [ + { + "name": "POSTGRES_PASSWORD", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-postgres", + "key": "password" + } + } + } + ], + "resources": { + "limits": { + "cpu": "1" + }, + "requests": { + "cpu": "100m", + "memory": "100Mi" + } + }, + "volumeMounts": [ + { + "name": "backup", + "mountPath": "/backup" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "restore-s3", + "image": "kotsadm/kotsadm:v1.58.2", + "command": [ + "/restore-s3.sh" + ], + "env": [ + { + "name": "S3_ENDPOINT", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-s3", + "key": "endpoint" + } + } + }, + { + "name": "S3_BUCKET_NAME", + "value": "kotsadm" + }, + { + "name": "S3_ACCESS_KEY_ID", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-s3", + "key": "access-key-id" + } + } + }, + { + "name": "S3_SECRET_ACCESS_KEY", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-s3", + "key": "secret-access-key" + } + } + }, + { + "name": "S3_BUCKET_ENDPOINT", + "value": "true" + } + ], + "resources": { + "limits": { + "cpu": "1" + }, + "requests": { + "cpu": "100m", + "memory": "100Mi" + } + }, + "volumeMounts": [ + { + "name": "backup", + "mountPath": "/backup" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + } + ], + "containers": [ + { + "name": "kotsadm", + "image": "kotsadm/kotsadm:v1.58.2", + "command": [ + "bash" + ], + "args": [ + "/scripts/start-kotsadm-web.sh" + ], + "ports": [ + { + "name": "http", + "containerPort": 3000, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "PROMETHEUS_ADDRESS", + "value": "http://prometheus-k8s.monitoring.svc.cluster.local:9090" + }, + { + "name": "KURL_INSTALL_ID", + "value": "t3j93et9c385x51w" + }, + { + "name": "AUTO_CREATE_CLUSTER", + "value": "1" + }, + { + "name": "AUTO_CREATE_CLUSTER_NAME", + "value": "this-cluster" + }, + { + "name": "AUTO_CREATE_CLUSTER_TOKEN", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-cluster-token", + "key": "kotsadm-cluster-token" + } + } + }, + { + "name": "SHARED_PASSWORD_BCRYPT", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-password", + "key": "passwordBcrypt" + } + } + }, + { + "name": "SESSION_KEY", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-session", + "key": "key" + } + } + }, + { + "name": "POSTGRES_URI", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-postgres", + "key": "uri" + } + } + }, + { + "name": "POSTGRES_PASSWORD", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-postgres", + "key": "password" + } + } + }, + { + "name": "POD_NAMESPACE", + "valueFrom": { + "fieldRef": { + "apiVersion": "v1", + "fieldPath": "metadata.namespace" + } + } + }, + { + "name": "API_ENCRYPTION_KEY", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-encryption", + "key": "encryptionKey" + } + } + }, + { + "name": "S3_ENDPOINT", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-s3", + "key": "endpoint" + } + } + }, + { + "name": "S3_BUCKET_NAME", + "value": "kotsadm" + }, + { + "name": "S3_ACCESS_KEY_ID", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-s3", + "key": "access-key-id" + } + } + }, + { + "name": "S3_SECRET_ACCESS_KEY", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-s3", + "key": "secret-access-key" + } + } + }, + { + "name": "S3_BUCKET_ENDPOINT", + "value": "true" + }, + { + "name": "API_ADVERTISE_ENDPOINT", + "value": "http://localhost:8800" + }, + { + "name": "API_ENDPOINT", + "value": "http://kotsadm.default.svc.cluster.local:3000" + }, + { + "name": "POD_OWNER_KIND", + "value": "deployment" + }, + { + "name": "KURL_PROXY_TLS_CERT_PATH", + "value": "/etc/kurl-proxy/ca/tls.crt" + }, + { + "name": "DEX_PGPASSWORD", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-dex-postgres", + "key": "PGPASSWORD" + } + } + } + ], + "resources": { + "limits": { + "cpu": "1" + }, + "requests": { + "cpu": "100m", + "memory": "100Mi" + } + }, + "volumeMounts": [ + { + "name": "host-cacerts", + "mountPath": "/etc/ssl/certs/ca-certificates.crt" + }, + { + "name": "kotsadm-web-scripts", + "mountPath": "/scripts/start-kotsadm-web.sh", + "subPath": "start-kotsadm-web.sh" + }, + { + "name": "backup", + "mountPath": "/backup" + }, + { + "name": "kubelet-client-cert", + "readOnly": true, + "mountPath": "/etc/kubernetes/pki/kubelet" + }, + { + "name": "kurl-proxy-kotsadm-tls-cert", + "readOnly": true, + "mountPath": "/etc/kurl-proxy/ca" + } + ], + "readinessProbe": { + "httpGet": { + "path": "/healthz", + "port": 3000, + "scheme": "HTTP" + }, + "initialDelaySeconds": 10, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "kotsadm", + "serviceAccount": "kotsadm", + "securityContext": { + "runAsUser": 1001 + }, + "schedulerName": "default-scheduler" + } + } + }, + "status": { + "replicas": 1, + "fullyLabeledReplicas": 1, + "readyReplicas": 1, + "availableReplicas": 1, + "observedGeneration": 1 + } + }, + { + "metadata": { + "name": "kurl-proxy-kotsadm-cf695877c", + "namespace": "default", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/kurl-proxy-kotsadm-cf695877c", + "uid": "5187bfda-5635-4901-8cf9-77cacc652844", + "resourceVersion": "2139", + "generation": 1, + "creationTimestamp": "2021-12-17T18:41:35Z", + "labels": { + "app": "kurl-proxy-kotsadm", + "kots.io/backup": "velero", + "kots.io/kotsadm": "true", + "pod-template-hash": "cf695877c" + }, + "annotations": { + "deployment.kubernetes.io/desired-replicas": "1", + "deployment.kubernetes.io/max-replicas": "2", + "deployment.kubernetes.io/revision": "1" + }, + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "kind": "Deployment", + "name": "kurl-proxy-kotsadm", + "uid": "28ff212c-9b9a-4478-8c25-34b822562ba7", + "controller": true, + "blockOwnerDeletion": true + } + ], + "managedFields": [ + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:41:45Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:kots.io/backup": {}, + "f:kots.io/kotsadm": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"28ff212c-9b9a-4478-8c25-34b822562ba7\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:kots.io/backup": {}, + "f:kots.io/kotsadm": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"proxy\"}": { + ".": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"DEX_UPSTREAM_ORIGIN\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"NAMESPACE\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:fieldRef": { + ".": {}, + "f:apiVersion": {}, + "f:fieldPath": {} + } + } + }, + "k:{\"name\":\"NODE_PORT\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"TLS_SECRET_NAME\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"UPSTREAM_ORIGIN\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/etc/kotsadm\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {}, + "f:volumes": { + ".": {}, + "k:{\"name\":\"kotsadm-config\"}": { + ".": {}, + "f:configMap": { + ".": {}, + "f:defaultMode": {}, + "f:name": {}, + "f:optional": {} + }, + "f:name": {} + } + } + } + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:fullyLabeledReplicas": {}, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app": "kurl-proxy-kotsadm", + "pod-template-hash": "cf695877c" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "kurl-proxy-kotsadm", + "kots.io/backup": "velero", + "kots.io/kotsadm": "true", + "pod-template-hash": "cf695877c" + } + }, + "spec": { + "volumes": [ + { + "name": "kotsadm-config", + "configMap": { + "name": "kotsadm-application-metadata", + "defaultMode": 420, + "optional": true + } + } + ], + "containers": [ + { + "name": "proxy", + "image": "kotsadm/kurl-proxy:v1.58.2", + "env": [ + { + "name": "NODE_PORT", + "value": "8800" + }, + { + "name": "UPSTREAM_ORIGIN", + "value": "http://kotsadm:3000" + }, + { + "name": "DEX_UPSTREAM_ORIGIN", + "value": "http://kotsadm-dex:5556" + }, + { + "name": "TLS_SECRET_NAME", + "value": "kotsadm-tls" + }, + { + "name": "NAMESPACE", + "valueFrom": { + "fieldRef": { + "apiVersion": "v1", + "fieldPath": "metadata.namespace" + } + } + } + ], + "resources": { + "limits": { + "cpu": "200m", + "memory": "200Mi" + }, + "requests": { + "cpu": "50m", + "memory": "50Mi" + } + }, + "volumeMounts": [ + { + "name": "kotsadm-config", + "mountPath": "/etc/kotsadm" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "kurl-proxy", + "serviceAccount": "kurl-proxy", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + } + }, + "status": { + "replicas": 1, + "fullyLabeledReplicas": 1, + "readyReplicas": 1, + "observedGeneration": 1 + } + } + ] + \ No newline at end of file diff --git a/pkg/analyze/files/statefulsets/default.json b/pkg/analyze/files/statefulsets/default.json new file mode 100644 index 000000000..a9f0b0b52 --- /dev/null +++ b/pkg/analyze/files/statefulsets/default.json @@ -0,0 +1,412 @@ +[ + { + "metadata": { + "name": "kotsadm-postgres", + "namespace": "default", + "selfLink": "/apis/apps/v1/namespaces/default/statefulsets/kotsadm-postgres", + "uid": "7b8a5a95-98bf-4b37-b302-7f55e5af844b", + "resourceVersion": "2185", + "generation": 1, + "creationTimestamp": "2021-12-17T18:41:34Z", + "labels": { + "kots.io/backup": "velero", + "kots.io/kotsadm": "true" + }, + "annotations": { + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"StatefulSet\",\"metadata\":{\"annotations\":{},\"labels\":{\"kots.io/backup\":\"velero\",\"kots.io/kotsadm\":\"true\"},\"name\":\"kotsadm-postgres\",\"namespace\":\"default\"},\"spec\":{\"replicas\":1,\"selector\":{\"matchLabels\":{\"app\":\"kotsadm-postgres\"}},\"serviceName\":\"kotsadm-postgres\",\"template\":{\"metadata\":{\"labels\":{\"app\":\"kotsadm-postgres\",\"kots.io/backup\":\"velero\",\"kots.io/kotsadm\":\"true\"}},\"spec\":{\"containers\":[{\"env\":[{\"name\":\"PGDATA\",\"value\":\"/var/lib/postgresql/data/pgdata\"},{\"name\":\"POSTGRES_USER\",\"value\":\"***HIDDEN***\"},{\"name\":\"POSTGRES_PASSWORD\",\"valueFrom\":{\"secretKeyRef\":{\"key\":\"password\",\"name\":\"kotsadm-postgres\"}}},{\"name\":\"POSTGRES_DB\",\"value\":\"kotsadm\"}],\"image\":\"postgres:10.18-alpine\",\"livenessProbe\":{\"exec\":{\"command\":[\"/bin/sh\",\"-i\",\"-c\",\"pg_isready -U kotsadm -h ***HIDDEN*** -p 5432\"]},\"failureThreshold\":3,\"initialDelaySeconds\":30,\"timeoutSeconds\":5},\"name\":\"kotsadm-postgres\",\"ports\":[{\"containerPort\":5432,\"name\":\"postgres\"}],\"readinessProbe\":{\"exec\":{\"command\":[\"/bin/sh\",\"-i\",\"-c\",\"pg_isready -U kotsadm -h ***HIDDEN*** -p 5432\"]},\"initialDelaySeconds\":1,\"periodSeconds\":1,\"timeoutSeconds\":1},\"resources\":{\"limits\":{\"cpu\":\"200m\",\"memory\":\"200Mi\"},\"requests\":{\"cpu\":\"100m\",\"memory\":\"100Mi\"}},\"volumeMounts\":[{\"mountPath\":\"/var/lib/postgresql/data\",\"name\":\"kotsadm-postgres\"},{\"mountPath\":\"/etc/passwd\",\"name\":\"etc-passwd\",\"subPath\":\"passwd\"}]}],\"securityContext\":{\"fsGroup\":999,\"runAsUser\":999},\"volumes\":[{\"name\":\"kotsadm-postgres\",\"persistentVolumeClaim\":{\"claimName\":\"kotsadm-postgres\"}},{\"configMap\":{\"items\":[{\"key\":\"passwd\",\"mode\":420,\"path\":\"passwd\"}],\"name\":\"kotsadm-postgres\"},\"name\":\"etc-passwd\"}]}},\"volumeClaimTemplates\":[{\"metadata\":{\"labels\":{\"kots.io/kotsadm\":\"true\"},\"name\":\"kotsadm-postgres\"},\"spec\":{\"accessModes\":[\"ReadWriteOnce\"],\"resources\":{\"requests\":{\"storage\":\"1Gi\"}}}}]}}\n" + }, + "managedFields": [ + { + "manager": "kubectl-client-side-apply", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:41:34Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:kots.io/backup": {}, + "f:kots.io/kotsadm": {} + } + }, + "f:spec": { + "f:podManagementPolicy": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {} + } + }, + "f:serviceName": {}, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:kots.io/backup": {}, + "f:kots.io/kotsadm": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"kotsadm-postgres\"}": { + ".": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"PGDATA\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"POSTGRES_DB\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + }, + "k:{\"name\":\"POSTGRES_PASSWORD\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:secretKeyRef": { + ".": {}, + "f:key": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"POSTGRES_USER\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:livenessProbe": { + ".": {}, + "f:exec": { + ".": {}, + "f:command": {} + }, + "f:failureThreshold": {}, + "f:initialDelaySeconds": {}, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":5432,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + } + }, + "f:readinessProbe": { + ".": {}, + "f:exec": { + ".": {}, + "f:command": {} + }, + "f:failureThreshold": {}, + "f:initialDelaySeconds": {}, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/etc/passwd\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:subPath": {} + }, + "k:{\"mountPath\":\"/var/lib/postgresql/data\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": { + ".": {}, + "f:fsGroup": {}, + "f:runAsUser": {} + }, + "f:terminationGracePeriodSeconds": {}, + "f:volumes": { + ".": {}, + "k:{\"name\":\"etc-passwd\"}": { + ".": {}, + "f:configMap": { + ".": {}, + "f:defaultMode": {}, + "f:items": {}, + "f:name": {} + }, + "f:name": {} + }, + "k:{\"name\":\"kotsadm-postgres\"}": { + ".": {}, + "f:name": {}, + "f:persistentVolumeClaim": { + ".": {}, + "f:claimName": {} + } + } + } + } + }, + "f:updateStrategy": { + "f:rollingUpdate": { + ".": {}, + "f:partition": {} + }, + "f:type": {} + } + } + } + }, + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:41:48Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:spec": { + "f:volumeClaimTemplates": {} + }, + "f:status": { + "f:collisionCount": {}, + "f:currentReplicas": {}, + "f:currentRevision": {}, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updateRevision": {}, + "f:updatedReplicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app": "kotsadm-postgres" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "kotsadm-postgres", + "kots.io/backup": "velero", + "kots.io/kotsadm": "true" + } + }, + "spec": { + "volumes": [ + { + "name": "kotsadm-postgres", + "persistentVolumeClaim": { + "claimName": "kotsadm-postgres" + } + }, + { + "name": "etc-passwd", + "configMap": { + "name": "kotsadm-postgres", + "items": [ + { + "key": "passwd", + "path": "passwd", + "mode": 420 + } + ], + "defaultMode": 420 + } + } + ], + "containers": [ + { + "name": "kotsadm-postgres", + "image": "postgres:10.18-alpine", + "ports": [ + { + "name": "postgres", + "containerPort": 5432, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "PGDATA", + "value": "/var/lib/postgresql/data/pgdata" + }, + { + "name": "POSTGRES_USER", + "value": "***HIDDEN***" + }, + { + "name": "POSTGRES_PASSWORD", + "valueFrom": { + "secretKeyRef": { + "name": "kotsadm-postgres", + "key": "password" + } + } + }, + { + "name": "POSTGRES_DB", + "value": "kotsadm" + } + ], + "resources": { + "limits": { + "cpu": "200m", + "memory": "200Mi" + }, + "requests": { + "cpu": "100m", + "memory": "100Mi" + } + }, + "volumeMounts": [ + { + "name": "kotsadm-postgres", + "mountPath": "/var/lib/postgresql/data" + }, + { + "name": "etc-passwd", + "mountPath": "/etc/passwd", + "subPath": "passwd" + } + ], + "livenessProbe": { + "exec": { + "command": [ + "/bin/sh", + "-i", + "-c", + "pg_isready -U kotsadm -h ***HIDDEN*** -p 5432" + ] + }, + "initialDelaySeconds": 30, + "timeoutSeconds": 5, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "readinessProbe": { + "exec": { + "command": [ + "/bin/sh", + "-i", + "-c", + "pg_isready -U kotsadm -h ***HIDDEN*** -p 5432" + ] + }, + "initialDelaySeconds": 1, + "timeoutSeconds": 1, + "periodSeconds": 1, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": { + "runAsUser": 999, + "fsGroup": 999 + }, + "schedulerName": "default-scheduler" + } + }, + "volumeClaimTemplates": [ + { + "kind": "PersistentVolumeClaim", + "apiVersion": "v1", + "metadata": { + "name": "kotsadm-postgres", + "creationTimestamp": null, + "labels": { + "kots.io/kotsadm": "true" + } + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "1Gi" + } + }, + "volumeMode": "Filesystem" + }, + "status": { + "phase": "Pending" + } + } + ], + "serviceName": "kotsadm-postgres", + "podManagementPolicy": "OrderedReady", + "updateStrategy": { + "type": "RollingUpdate", + "rollingUpdate": { + "partition": 0 + } + }, + "revisionHistoryLimit": 10 + }, + "status": { + "observedGeneration": 1, + "replicas": 2, + "readyReplicas": 1, + "currentReplicas": 1, + "updatedReplicas": 1, + "currentRevision": "kotsadm-postgres-77c87fd9d8", + "updateRevision": "kotsadm-postgres-77c87fd9d8", + "collisionCount": 0 + } + } + ] + \ No newline at end of file diff --git a/pkg/analyze/files/statefulsets/monitoring.json b/pkg/analyze/files/statefulsets/monitoring.json new file mode 100644 index 000000000..44408fa74 --- /dev/null +++ b/pkg/analyze/files/statefulsets/monitoring.json @@ -0,0 +1,1282 @@ +[ + { + "metadata": { + "name": "alertmanager-prometheus-alertmanager", + "namespace": "monitoring", + "selfLink": "/apis/apps/v1/namespaces/monitoring/statefulsets/alertmanager-prometheus-alertmanager", + "uid": "73597dc5-f02d-4557-95ed-ce9daff3b6c9", + "resourceVersion": "3068", + "generation": 2, + "creationTimestamp": "2021-12-17T18:41:31Z", + "labels": { + "app": "kube-prometheus-stack-alertmanager", + "app.kubernetes.io/instance": "v0.49.0-17.1.3", + "app.kubernetes.io/managed-by": "Helm", + "app.kubernetes.io/part-of": "kube-prometheus-stack", + "app.kubernetes.io/version": "17.1.3", + "chart": "kube-prometheus-stack-17.1.3", + "heritage": "Helm", + "release": "v0.49.0-17.1.3" + }, + "annotations": { + "prometheus-operator-input-hash": "17184405095684028533" + }, + "ownerReferences": [ + { + "apiVersion": "monitoring.coreos.com/v1", + "kind": "Alertmanager", + "name": "prometheus-alertmanager", + "uid": "c13bc191-0eb8-4fea-95b2-d78a140a64be", + "controller": true, + "blockOwnerDeletion": true + } + ], + "managedFields": [ + { + "manager": "operator", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:42:37Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:prometheus-operator-input-hash": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/managed-by": {}, + "f:app.kubernetes.io/part-of": {}, + "f:app.kubernetes.io/version": {}, + "f:chart": {}, + "f:heritage": {}, + "f:release": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"c13bc191-0eb8-4fea-95b2-d78a140a64be\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:podManagementPolicy": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:alertmanager": {}, + "f:app": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/managed-by": {}, + "f:app.kubernetes.io/name": {} + } + }, + "f:serviceName": {}, + "f:template": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/default-container": {} + }, + "f:labels": { + ".": {}, + "f:alertmanager": {}, + "f:app": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/managed-by": {}, + "f:app.kubernetes.io/name": {}, + "f:app.kubernetes.io/version": {} + } + }, + "f:spec": { + "f:affinity": { + ".": {}, + "f:podAntiAffinity": { + ".": {}, + "f:requiredDuringSchedulingIgnoredDuringExecution": {} + } + }, + "f:containers": { + "k:{\"name\":\"alertmanager\"}": { + ".": {}, + "f:args": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"POD_IP\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:fieldRef": { + ".": {}, + "f:apiVersion": {}, + "f:fieldPath": {} + } + } + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:livenessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":9093,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + }, + "k:{\"containerPort\":9094,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + }, + "k:{\"containerPort\":9094,\"protocol\":\"UDP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + } + }, + "f:readinessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:initialDelaySeconds": {}, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:resources": { + ".": {}, + "f:requests": { + ".": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/alertmanager\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + }, + "k:{\"mountPath\":\"/etc/alertmanager/certs\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:readOnly": {} + }, + "k:{\"mountPath\":\"/etc/alertmanager/config\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"config-reloader\"}": { + ".": {}, + "f:args": {}, + "f:command": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"POD_NAME\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:fieldRef": { + ".": {}, + "f:apiVersion": {}, + "f:fieldPath": {} + } + } + }, + "k:{\"name\":\"SHARD\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/etc/alertmanager/config\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:readOnly": {} + } + } + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": { + ".": {}, + "f:fsGroup": {}, + "f:runAsGroup": {}, + "f:runAsNonRoot": {}, + "f:runAsUser": {} + }, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {}, + "f:volumes": { + ".": {}, + "k:{\"name\":\"alertmanager-prometheus-alertmanager-db\"}": { + ".": {}, + "f:emptyDir": {}, + "f:name": {} + }, + "k:{\"name\":\"config-volume\"}": { + ".": {}, + "f:name": {}, + "f:secret": { + ".": {}, + "f:defaultMode": {}, + "f:secretName": {} + } + }, + "k:{\"name\":\"tls-assets\"}": { + ".": {}, + "f:name": {}, + "f:secret": { + ".": {}, + "f:defaultMode": {}, + "f:secretName": {} + } + } + } + } + }, + "f:updateStrategy": { + "f:type": {} + } + } + } + }, + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:42:52Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:currentReplicas": {}, + "f:currentRevision": {}, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updateRevision": {}, + "f:updatedReplicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "alertmanager": "prometheus-alertmanager", + "app": "alertmanager", + "app.kubernetes.io/instance": "prometheus-alertmanager", + "app.kubernetes.io/managed-by": "prometheus-operator", + "app.kubernetes.io/name": "alertmanager" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "alertmanager": "prometheus-alertmanager", + "app": "alertmanager", + "app.kubernetes.io/instance": "prometheus-alertmanager", + "app.kubernetes.io/managed-by": "prometheus-operator", + "app.kubernetes.io/name": "alertmanager", + "app.kubernetes.io/version": "0.22.2" + }, + "annotations": { + "kubectl.kubernetes.io/default-container": "alertmanager" + } + }, + "spec": { + "volumes": [ + { + "name": "config-volume", + "secret": { + "secretName": "alertmanager-prometheus-alertmanager-generated", + "defaultMode": 420 + } + }, + { + "name": "tls-assets", + "secret": { + "secretName": "alertmanager-prometheus-alertmanager-tls-assets", + "defaultMode": 420 + } + }, + { + "name": "alertmanager-prometheus-alertmanager-db", + "emptyDir": {} + } + ], + "containers": [ + { + "name": "alertmanager", + "image": "quay.io/prometheus/alertmanager:v0.22.2", + "args": [ + "--config.file=/etc/alertmanager/config/alertmanager.yaml", + "--storage.path=/alertmanager", + "--data.retention=120h", + "--cluster.listen-address=", + "--web.listen-address=:9093", + "--web.external-url=http://prometheus-alertmanager.monitoring:9093", + "--web.route-prefix=/", + "--cluster.peer=alertmanager-prometheus-alertmanager-0.alertmanager-operated:9094", + "--cluster.reconnect-timeout=5m" + ], + "ports": [ + { + "name": "web", + "containerPort": 9093, + "protocol": "TCP" + }, + { + "name": "mesh-tcp", + "containerPort": 9094, + "protocol": "TCP" + }, + { + "name": "mesh-udp", + "containerPort": 9094, + "protocol": "UDP" + } + ], + "env": [ + { + "name": "POD_IP", + "valueFrom": { + "fieldRef": { + "apiVersion": "v1", + "fieldPath": "status.podIP" + } + } + } + ], + "resources": { + "requests": { + "memory": "200Mi" + } + }, + "volumeMounts": [ + { + "name": "config-volume", + "mountPath": "/etc/alertmanager/config" + }, + { + "name": "tls-assets", + "readOnly": true, + "mountPath": "/etc/alertmanager/certs" + }, + { + "name": "alertmanager-prometheus-alertmanager-db", + "mountPath": "/alertmanager" + } + ], + "livenessProbe": { + "httpGet": { + "path": "/-/healthy", + "port": "web", + "scheme": "HTTP" + }, + "timeoutSeconds": 3, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 10 + }, + "readinessProbe": { + "httpGet": { + "path": "/-/ready", + "port": "web", + "scheme": "HTTP" + }, + "initialDelaySeconds": 3, + "timeoutSeconds": 3, + "periodSeconds": 5, + "successThreshold": 1, + "failureThreshold": 10 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "FallbackToLogsOnError", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "config-reloader", + "image": "quay.io/prometheus-operator/prometheus-config-reloader:v0.49.0", + "command": [ + "/bin/prometheus-config-reloader" + ], + "args": [ + "--listen-address=:8080", + "--reload-url=http://***HIDDEN***:9093/-/reload", + "--watched-dir=/etc/alertmanager/config" + ], + "env": [ + { + "name": "POD_NAME", + "valueFrom": { + "fieldRef": { + "apiVersion": "v1", + "fieldPath": "metadata.name" + } + } + }, + { + "name": "SHARD", + "value": "-1" + } + ], + "resources": { + "limits": { + "cpu": "100m", + "memory": "50Mi" + }, + "requests": { + "cpu": "100m", + "memory": "50Mi" + } + }, + "volumeMounts": [ + { + "name": "config-volume", + "readOnly": true, + "mountPath": "/etc/alertmanager/config" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "FallbackToLogsOnError", + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 120, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "prometheus-alertmanager", + "serviceAccount": "prometheus-alertmanager", + "securityContext": { + "runAsUser": 1000, + "runAsGroup": 2000, + "runAsNonRoot": true, + "fsGroup": 2000 + }, + "affinity": { + "podAntiAffinity": { + "requiredDuringSchedulingIgnoredDuringExecution": [ + { + "labelSelector": { + "matchExpressions": [ + { + "key": "app", + "operator": "In", + "values": [ + "alertmanager" + ] + }, + { + "key": "alertmanager", + "operator": "In", + "values": [ + "prometheus-alertmanager" + ] + } + ] + }, + "topologyKey": "kubernetes.io/hostname" + } + ] + } + }, + "schedulerName": "default-scheduler" + } + }, + "serviceName": "alertmanager-operated", + "podManagementPolicy": "Parallel", + "updateStrategy": { + "type": "RollingUpdate" + }, + "revisionHistoryLimit": 10 + }, + "status": { + "observedGeneration": 2, + "replicas": 2, + "readyReplicas": 1, + "currentReplicas": 1, + "updatedReplicas": 1, + "currentRevision": "alertmanager-prometheus-alertmanager-575f5ccd86", + "updateRevision": "alertmanager-prometheus-alertmanager-575f5ccd86", + "collisionCount": 0 + } + }, + { + "metadata": { + "name": "prometheus-k8s", + "namespace": "monitoring", + "selfLink": "/apis/apps/v1/namespaces/monitoring/statefulsets/prometheus-k8s", + "uid": "5f50dac8-79ce-4fab-b1f3-5064aab59266", + "resourceVersion": "2791", + "generation": 2, + "creationTimestamp": "2021-12-17T18:41:31Z", + "labels": { + "app": "kube-prometheus-stack-prometheus", + "app.kubernetes.io/instance": "v0.49.0-17.1.3", + "app.kubernetes.io/managed-by": "Helm", + "app.kubernetes.io/part-of": "kube-prometheus-stack", + "app.kubernetes.io/version": "17.1.3", + "chart": "kube-prometheus-stack-17.1.3", + "heritage": "Helm", + "operator.prometheus.io/name": "k8s", + "operator.prometheus.io/shard": "0", + "release": "v0.49.0-17.1.3" + }, + "annotations": { + "prometheus-operator-input-hash": "17776800170066970690" + }, + "ownerReferences": [ + { + "apiVersion": "monitoring.coreos.com/v1", + "kind": "Prometheus", + "name": "k8s", + "uid": "e224f9c1-90b8-4454-8855-8a18ad7984e3", + "controller": true, + "blockOwnerDeletion": true + } + ], + "managedFields": [ + { + "manager": "operator", + "operation": "Update", + "apiVersion": "apps/v1", + "time": "2021-12-17T18:42:38Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:prometheus-operator-input-hash": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/managed-by": {}, + "f:app.kubernetes.io/part-of": {}, + "f:app.kubernetes.io/version": {}, + "f:chart": {}, + "f:heritage": {}, + "f:operator.prometheus.io/name": {}, + "f:operator.prometheus.io/shard": {}, + "f:release": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"e224f9c1-90b8-4454-8855-8a18ad7984e3\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:podManagementPolicy": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/managed-by": {}, + "f:app.kubernetes.io/name": {}, + "f:operator.prometheus.io/name": {}, + "f:operator.prometheus.io/shard": {}, + "f:prometheus": {} + } + }, + "f:serviceName": {}, + "f:template": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/default-container": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:app.kubernetes.io/instance": {}, + "f:app.kubernetes.io/managed-by": {}, + "f:app.kubernetes.io/name": {}, + "f:app.kubernetes.io/version": {}, + "f:operator.prometheus.io/name": {}, + "f:operator.prometheus.io/shard": {}, + "f:prometheus": {} + } + }, + "f:spec": { + "f:affinity": { + ".": {}, + "f:podAntiAffinity": { + ".": {}, + "f:requiredDuringSchedulingIgnoredDuringExecution": {} + } + }, + "f:containers": { + "k:{\"name\":\"config-reloader\"}": { + ".": {}, + "f:args": {}, + "f:command": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"POD_NAME\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:fieldRef": { + ".": {}, + "f:apiVersion": {}, + "f:fieldPath": {} + } + } + }, + "k:{\"name\":\"SHARD\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/etc/prometheus/config\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + }, + "k:{\"mountPath\":\"/etc/prometheus/config_out\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + }, + "k:{\"mountPath\":\"/etc/prometheus/rules/prometheus-k8s-rulefiles-0\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + }, + "k:{\"name\":\"prometheus\"}": { + ".": {}, + "f:args": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":9090,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:name": {}, + "f:protocol": {} + } + }, + "f:readinessProbe": { + ".": {}, + "f:failureThreshold": {}, + "f:httpGet": { + ".": {}, + "f:path": {}, + "f:port": {}, + "f:scheme": {} + }, + "f:periodSeconds": {}, + "f:successThreshold": {}, + "f:timeoutSeconds": {} + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/etc/prometheus/certs\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:readOnly": {} + }, + "k:{\"mountPath\":\"/etc/prometheus/config_out\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:readOnly": {} + }, + "k:{\"mountPath\":\"/etc/prometheus/rules/prometheus-k8s-rulefiles-0\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + }, + "k:{\"mountPath\":\"/etc/prometheus/web_config/web-config.yaml\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:readOnly": {}, + "f:subPath": {} + }, + "k:{\"mountPath\":\"/prometheus\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {}, + "f:subPath": {} + } + } + } + }, + "f:dnsPolicy": {}, + "f:initContainers": { + ".": {}, + "k:{\"name\":\"init-config-reloader\"}": { + ".": {}, + "f:args": {}, + "f:command": {}, + "f:env": { + ".": {}, + "k:{\"name\":\"POD_NAME\"}": { + ".": {}, + "f:name": {}, + "f:valueFrom": { + ".": {}, + "f:fieldRef": { + ".": {}, + "f:apiVersion": {}, + "f:fieldPath": {} + } + } + }, + "k:{\"name\":\"SHARD\"}": { + ".": {}, + "f:name": {}, + "f:value": {} + } + }, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": { + ".": {}, + "f:limits": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + }, + "f:requests": { + ".": {}, + "f:cpu": {}, + "f:memory": {} + } + }, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {}, + "f:volumeMounts": { + ".": {}, + "k:{\"mountPath\":\"/etc/prometheus/config\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + }, + "k:{\"mountPath\":\"/etc/prometheus/config_out\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + }, + "k:{\"mountPath\":\"/etc/prometheus/rules/prometheus-k8s-rulefiles-0\"}": { + ".": {}, + "f:mountPath": {}, + "f:name": {} + } + } + } + }, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": { + ".": {}, + "f:fsGroup": {}, + "f:runAsGroup": {}, + "f:runAsNonRoot": {}, + "f:runAsUser": {} + }, + "f:serviceAccount": {}, + "f:serviceAccountName": {}, + "f:terminationGracePeriodSeconds": {}, + "f:volumes": { + ".": {}, + "k:{\"name\":\"config\"}": { + ".": {}, + "f:name": {}, + "f:secret": { + ".": {}, + "f:defaultMode": {}, + "f:secretName": {} + } + }, + "k:{\"name\":\"config-out\"}": { + ".": {}, + "f:emptyDir": {}, + "f:name": {} + }, + "k:{\"name\":\"prometheus-k8s-rulefiles-0\"}": { + ".": {}, + "f:configMap": { + ".": {}, + "f:defaultMode": {}, + "f:name": {} + }, + "f:name": {} + }, + "k:{\"name\":\"tls-assets\"}": { + ".": {}, + "f:name": {}, + "f:secret": { + ".": {}, + "f:defaultMode": {}, + "f:secretName": {} + } + }, + "k:{\"name\":\"web-config\"}": { + ".": {}, + "f:name": {}, + "f:secret": { + ".": {}, + "f:defaultMode": {}, + "f:secretName": {} + } + } + } + } + }, + "f:updateStrategy": { + "f:type": {} + }, + "f:volumeClaimTemplates": {} + }, + "f:status": { + "f:replicas": {} + } + } + } + ] + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app": "prometheus", + "app.kubernetes.io/instance": "k8s", + "app.kubernetes.io/managed-by": "prometheus-operator", + "app.kubernetes.io/name": "prometheus", + "operator.prometheus.io/name": "k8s", + "operator.prometheus.io/shard": "0", + "prometheus": "k8s" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "prometheus", + "app.kubernetes.io/instance": "k8s", + "app.kubernetes.io/managed-by": "prometheus-operator", + "app.kubernetes.io/name": "prometheus", + "app.kubernetes.io/version": "2.28.1", + "operator.prometheus.io/name": "k8s", + "operator.prometheus.io/shard": "0", + "prometheus": "k8s" + }, + "annotations": { + "kubectl.kubernetes.io/default-container": "prometheus" + } + }, + "spec": { + "volumes": [ + { + "name": "config", + "secret": { + "secretName": "prometheus-k8s", + "defaultMode": 420 + } + }, + { + "name": "tls-assets", + "secret": { + "secretName": "prometheus-k8s-tls-assets", + "defaultMode": 420 + } + }, + { + "name": "config-out", + "emptyDir": {} + }, + { + "name": "prometheus-k8s-rulefiles-0", + "configMap": { + "name": "prometheus-k8s-rulefiles-0", + "defaultMode": 420 + } + }, + { + "name": "web-config", + "secret": { + "secretName": "prometheus-k8s-web-config", + "defaultMode": 420 + } + } + ], + "initContainers": [ + { + "name": "init-config-reloader", + "image": "quay.io/prometheus-operator/prometheus-config-reloader:v0.49.0", + "command": [ + "/bin/prometheus-config-reloader" + ], + "args": [ + "--watch-interval=0", + "--listen-address=:8080", + "--config-file=/etc/prometheus/config/prometheus.yaml.gz", + "--config-envsubst-file=/etc/prometheus/config_out/prometheus.env.yaml", + "--watched-dir=/etc/prometheus/rules/prometheus-k8s-rulefiles-0" + ], + "env": [ + { + "name": "POD_NAME", + "valueFrom": { + "fieldRef": { + "apiVersion": "v1", + "fieldPath": "metadata.name" + } + } + }, + { + "name": "SHARD", + "value": "0" + } + ], + "resources": { + "limits": { + "cpu": "100m", + "memory": "50Mi" + }, + "requests": { + "cpu": "100m", + "memory": "50Mi" + } + }, + "volumeMounts": [ + { + "name": "config", + "mountPath": "/etc/prometheus/config" + }, + { + "name": "config-out", + "mountPath": "/etc/prometheus/config_out" + }, + { + "name": "prometheus-k8s-rulefiles-0", + "mountPath": "/etc/prometheus/rules/prometheus-k8s-rulefiles-0" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "FallbackToLogsOnError", + "imagePullPolicy": "IfNotPresent" + } + ], + "containers": [ + { + "name": "prometheus", + "image": "quay.io/prometheus/prometheus:v2.28.1", + "args": [ + "--web.console.templates=/etc/prometheus/consoles", + "--web.console.libraries=/etc/prometheus/console_libraries", + "--storage.tsdb.retention.size=9GB", + "--config.file=/etc/prometheus/config_out/prometheus.env.yaml", + "--storage.tsdb.path=/prometheus", + "--storage.tsdb.retention.time=15d", + "--web.enable-lifecycle", + "--web.external-url=http://prometheus-k8s.monitoring:9090", + "--web.route-prefix=/", + "--web.config.file=/etc/prometheus/web_config/web-config.yaml" + ], + "ports": [ + { + "name": "web", + "containerPort": 9090, + "protocol": "TCP" + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "config-out", + "readOnly": true, + "mountPath": "/etc/prometheus/config_out" + }, + { + "name": "tls-assets", + "readOnly": true, + "mountPath": "/etc/prometheus/certs" + }, + { + "name": "prometheus-k8s-db", + "mountPath": "/prometheus", + "subPath": "prometheus-db" + }, + { + "name": "prometheus-k8s-rulefiles-0", + "mountPath": "/etc/prometheus/rules/prometheus-k8s-rulefiles-0" + }, + { + "name": "web-config", + "readOnly": true, + "mountPath": "/etc/prometheus/web_config/web-config.yaml", + "subPath": "web-config.yaml" + } + ], + "readinessProbe": { + "httpGet": { + "path": "/-/ready", + "port": "web", + "scheme": "HTTP" + }, + "timeoutSeconds": 3, + "periodSeconds": 5, + "successThreshold": 1, + "failureThreshold": 120 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "FallbackToLogsOnError", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "config-reloader", + "image": "quay.io/prometheus-operator/prometheus-config-reloader:v0.49.0", + "command": [ + "/bin/prometheus-config-reloader" + ], + "args": [ + "--listen-address=:8080", + "--reload-url=http://***HIDDEN***:9090/-/reload", + "--config-file=/etc/prometheus/config/prometheus.yaml.gz", + "--config-envsubst-file=/etc/prometheus/config_out/prometheus.env.yaml", + "--watched-dir=/etc/prometheus/rules/prometheus-k8s-rulefiles-0" + ], + "env": [ + { + "name": "POD_NAME", + "valueFrom": { + "fieldRef": { + "apiVersion": "v1", + "fieldPath": "metadata.name" + } + } + }, + { + "name": "SHARD", + "value": "0" + } + ], + "resources": { + "limits": { + "cpu": "100m", + "memory": "50Mi" + }, + "requests": { + "cpu": "100m", + "memory": "50Mi" + } + }, + "volumeMounts": [ + { + "name": "config", + "mountPath": "/etc/prometheus/config" + }, + { + "name": "config-out", + "mountPath": "/etc/prometheus/config_out" + }, + { + "name": "prometheus-k8s-rulefiles-0", + "mountPath": "/etc/prometheus/rules/prometheus-k8s-rulefiles-0" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "FallbackToLogsOnError", + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 600, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "k8s", + "serviceAccount": "k8s", + "securityContext": { + "runAsUser": 1000, + "runAsGroup": 2000, + "runAsNonRoot": true, + "fsGroup": 2000 + }, + "affinity": { + "podAntiAffinity": { + "requiredDuringSchedulingIgnoredDuringExecution": [ + { + "labelSelector": { + "matchExpressions": [ + { + "key": "app.kubernetes.io/name", + "operator": "In", + "values": [ + "prometheus" + ] + }, + { + "key": "prometheus", + "operator": "In", + "values": [ + "k8s" + ] + } + ] + }, + "topologyKey": "kubernetes.io/hostname" + } + ] + } + }, + "schedulerName": "default-scheduler" + } + }, + "volumeClaimTemplates": [ + { + "kind": "PersistentVolumeClaim", + "apiVersion": "v1", + "metadata": { + "name": "prometheus-k8s-db", + "creationTimestamp": null + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "10Gi" + } + }, + "volumeMode": "Filesystem" + }, + "status": { + "phase": "Pending" + } + } + ], + "serviceName": "prometheus-operated", + "podManagementPolicy": "Parallel", + "updateStrategy": { + "type": "RollingUpdate" + }, + "revisionHistoryLimit": 10 + }, + "status": { + "observedGeneration": 2, + "replicas": 1, + "readyReplicas": 1, + "currentReplicas": 1, + "updatedReplicas": 1, + "currentRevision": "prometheus-k8s-5d6959665b", + "updateRevision": "prometheus-k8s-5d6959665b", + "collisionCount": 0 + } + } + ] + \ No newline at end of file diff --git a/pkg/analyze/job_status.go b/pkg/analyze/job_status.go index 01b202645..0482e8d2a 100644 --- a/pkg/analyze/job_status.go +++ b/pkg/analyze/job_status.go @@ -68,29 +68,37 @@ func analyzeOneJobStatus(analyzer *troubleshootv1beta2.JobStatus, getFileContent } func analyzeAllJobStatuses(analyzer *troubleshootv1beta2.JobStatus, getFileContents func(string) (map[string][]byte, error)) ([]*AnalyzeResult, error) { - var fileName string + fileNames := make([]string, 0) if analyzer.Namespace != "" { - fileName = filepath.Join("cluster-resources", "jobs", fmt.Sprintf("%s.json", analyzer.Namespace)) - } else { - fileName = filepath.Join("cluster-resources", "jobs", "*.json") + fileNames = append(fileNames, filepath.Join("cluster-resources", "jobs", fmt.Sprintf("%s.json", analyzer.Namespace))) + } + for _, ns := range analyzer.Namespaces { + fileNames = append(fileNames, filepath.Join("cluster-resources", "jobs", fmt.Sprintf("%s.json", ns))) } - files, err := getFileContents(fileName) - if err != nil { - return nil, errors.Wrap(err, "failed to read collected jobs from file") + // no namespace specified, so we need to analyze all jobs + if len(analyzer.Namespaces) == 0 { + fileNames = append(fileNames, filepath.Join("cluster-resources", "jobs", "*.json")) } results := []*AnalyzeResult{} - for _, collected := range files { - var jobs []batchv1.Job - if err := json.Unmarshal(collected, &jobs); err != nil { - return nil, errors.Wrap(err, "failed to unmarshal job list") + for _, fileName := range fileNames { + files, err := getFileContents(fileName) + if err != nil { + return nil, errors.Wrap(err, "failed to read collected jobs from file") } - for _, job := range jobs { - result := getDefaultJobResult(&job) - if result != nil { - results = append(results, result) + for _, collected := range files { + var jobs []batchv1.Job + if err := json.Unmarshal(collected, &jobs); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal job list") + } + + for _, job := range jobs { + result := getDefaultJobResult(&job) + if result != nil { + results = append(results, result) + } } } } diff --git a/pkg/analyze/job_status_test.go b/pkg/analyze/job_status_test.go index 53f9fda76..38d32adfa 100644 --- a/pkg/analyze/job_status_test.go +++ b/pkg/analyze/job_status_test.go @@ -46,7 +46,8 @@ func Test_JobStatus(t *testing.T) { }, }, files: map[string][]byte{ - "cluster-resources/jobs/test.json": []byte(testJobs), + "cluster-resources/jobs/test.json": []byte(testJobs), + "cluster-resources/jobs/projectcontour.json": []byte(projectcontourJobs), }, }, { @@ -80,7 +81,8 @@ func Test_JobStatus(t *testing.T) { }, }, files: map[string][]byte{ - "cluster-resources/jobs/test.json": []byte(testJobs), + "cluster-resources/jobs/test.json": []byte(testJobs), + "cluster-resources/jobs/projectcontour.json": []byte(projectcontourJobs), }, }, { @@ -120,7 +122,8 @@ func Test_JobStatus(t *testing.T) { }, }, files: map[string][]byte{ - "cluster-resources/jobs/test.json": []byte(testJobs), + "cluster-resources/jobs/test.json": []byte(testJobs), + "cluster-resources/jobs/projectcontour.json": []byte(projectcontourJobs), }, }, { @@ -136,9 +139,40 @@ func Test_JobStatus(t *testing.T) { IconKey: "kubernetes_deployment_status", IconURI: "https://troubleshoot.sh/images/analyzer-icons/deployment-status.svg?w=17&h=17", }, + { + IsPass: false, + IsWarn: false, + IsFail: true, + Title: "projectcontour/contour-certgen-v1.19.1 Job Status", + Message: "The job projectcontour/contour-certgen-v1.19.1 is not complete", + IconKey: "kubernetes_deployment_status", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/deployment-status.svg?w=17&h=17", + }, + }, + files: map[string][]byte{ + "cluster-resources/jobs/test.json": []byte(testJobs), + "cluster-resources/jobs/projectcontour.json": []byte(projectcontourJobs), + }, + }, + { + name: "analyze all jobs with namespaces", + analyzer: troubleshootv1beta2.JobStatus{ + Namespaces: []string{"projectcontour"}, + }, + expectResult: []*AnalyzeResult{ + { + IsPass: false, + IsWarn: false, + IsFail: true, + Title: "projectcontour/contour-certgen-v1.19.1 Job Status", + Message: "The job projectcontour/contour-certgen-v1.19.1 is not complete", + IconKey: "kubernetes_deployment_status", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/deployment-status.svg?w=17&h=17", + }, }, files: map[string][]byte{ - "cluster-resources/jobs/test.json": []byte(testJobs), + "cluster-resources/jobs/test.json": []byte(testJobs), + "cluster-resources/jobs/projectcontour.json": []byte(projectcontourJobs), }, }, } @@ -148,14 +182,19 @@ func Test_JobStatus(t *testing.T) { req := require.New(t) getFiles := func(n string) (map[string][]byte, error) { + if file, ok := test.files[n]; ok { + return map[string][]byte{n: file}, nil + } return test.files, nil } actual, err := analyzeJobStatus(&test.analyzer, getFiles) req.NoError(err) - assert.Equal(t, test.expectResult, actual) - + req.Equal(len(test.expectResult), len(actual)) + for _, a := range actual { + assert.Contains(t, test.expectResult, a) + } }) } } diff --git a/pkg/analyze/replicaset_status.go b/pkg/analyze/replicaset_status.go index 1c366ff93..45f75ee48 100644 --- a/pkg/analyze/replicaset_status.go +++ b/pkg/analyze/replicaset_status.go @@ -65,47 +65,54 @@ func analyzeOneReplicaSetStatus(analyzer *troubleshootv1beta2.ReplicaSetStatus, } func analyzeAllReplicaSetStatuses(analyzer *troubleshootv1beta2.ReplicaSetStatus, getFileContents func(string) (map[string][]byte, error)) ([]*AnalyzeResult, error) { - var fileName string + fileNames := make([]string, 0) if analyzer.Namespace != "" { - fileName = filepath.Join("cluster-resources", "replicasets", fmt.Sprintf("%s.json", analyzer.Namespace)) - } else { - fileName = filepath.Join("cluster-resources", "replicasets", "*.json") + fileNames = append(fileNames, filepath.Join("cluster-resources", "replicasets", fmt.Sprintf("%s.json", analyzer.Namespace))) } - - files, err := getFileContents(fileName) - if err != nil { - return nil, errors.Wrap(err, "failed to read collected replicaset from file") + for _, ns := range analyzer.Namespaces { + fileNames = append(fileNames, filepath.Join("cluster-resources", "replicasets", fmt.Sprintf("%s.json", ns))) } - labelSelector, err := labels.Parse(strings.Join(analyzer.Selector, ",")) - if err != nil { - return nil, errors.Wrap(err, "failed to parse selector") + if len(fileNames) == 0 { + fileNames = append(fileNames, filepath.Join("cluster-resources", "replicasets", "*.json")) } results := []*AnalyzeResult{} - for _, collected := range files { - var replicasets []appsv1.ReplicaSet - if err := json.Unmarshal(collected, &replicasets); err != nil { - return nil, errors.Wrap(err, "failed to unmarshal replicaset list") + for _, fileName := range fileNames { + files, err := getFileContents(fileName) + if err != nil { + return nil, errors.Wrap(err, "failed to read collected replicaset from file") } - for _, replicaset := range replicasets { - if !labelSelector.Matches(labels.Set(replicaset.Labels)) { - continue + labelSelector, err := labels.Parse(strings.Join(analyzer.Selector, ",")) + if err != nil { + return nil, errors.Wrap(err, "failed to parse selector") + } + + for _, collected := range files { + var replicasets []appsv1.ReplicaSet + if err := json.Unmarshal(collected, &replicasets); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal replicaset list") } - var result *AnalyzeResult - if len(analyzer.Outcomes) > 0 { - result, err = replicasetStatus(analyzer.Outcomes, &replicaset) - if err != nil { - return nil, errors.Wrap(err, "failed to process status") + for _, replicaset := range replicasets { + if !labelSelector.Matches(labels.Set(replicaset.Labels)) { + continue } - } else { - result = getDefaultReplicaSetResult(&replicaset) - } - if result != nil { - results = append(results, result) + var result *AnalyzeResult + if len(analyzer.Outcomes) > 0 { + result, err = replicasetStatus(analyzer.Outcomes, &replicaset) + if err != nil { + return nil, errors.Wrap(err, "failed to process status") + } + } else { + result = getDefaultReplicaSetResult(&replicaset) + } + + if result != nil { + results = append(results, result) + } } } } diff --git a/pkg/analyze/replicaset_status_test.go b/pkg/analyze/replicaset_status_test.go index 493e5b049..c6e767c2c 100644 --- a/pkg/analyze/replicaset_status_test.go +++ b/pkg/analyze/replicaset_status_test.go @@ -46,7 +46,8 @@ func Test_analyzeReplicaSetStatus(t *testing.T) { }, }, files: map[string][]byte{ - "cluster-resources/replicasets/rook-ceph.json": []byte(collectedReplicaSets), + "cluster-resources/replicasets/rook-ceph.json": []byte(rookCephReplicaSets), + "cluster-resources/replicasets/default.json": []byte(defaultReplicaSets), }, }, { @@ -80,7 +81,8 @@ func Test_analyzeReplicaSetStatus(t *testing.T) { }, }, files: map[string][]byte{ - "cluster-resources/replicasets/rook-ceph.json": []byte(collectedReplicaSets), + "cluster-resources/replicasets/rook-ceph.json": []byte(rookCephReplicaSets), + "cluster-resources/replicasets/default.json": []byte(defaultReplicaSets), }, }, { @@ -96,9 +98,40 @@ func Test_analyzeReplicaSetStatus(t *testing.T) { IconKey: "kubernetes_deployment_status", IconURI: "https://troubleshoot.sh/images/analyzer-icons/deployment-status.svg?w=17&h=17", }, + { + IsPass: false, + IsWarn: false, + IsFail: true, + Title: "default/kurl-proxy-kotsadm-cf695877c ReplicaSet Status", + Message: "The replicaset default/kurl-proxy-kotsadm-cf695877c is not ready", + IconKey: "kubernetes_deployment_status", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/deployment-status.svg?w=17&h=17", + }, + }, + files: map[string][]byte{ + "cluster-resources/replicasets/rook-ceph.json": []byte(rookCephReplicaSets), + "cluster-resources/replicasets/default.json": []byte(defaultReplicaSets), + }, + }, + { + name: "analyze all replicasets with namespaces", + analyzer: troubleshootv1beta2.ReplicaSetStatus{ + Namespaces: []string{"default"}, + }, + expectResult: []*AnalyzeResult{ + { + IsPass: false, + IsWarn: false, + IsFail: true, + Title: "default/kurl-proxy-kotsadm-cf695877c ReplicaSet Status", + Message: "The replicaset default/kurl-proxy-kotsadm-cf695877c is not ready", + IconKey: "kubernetes_deployment_status", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/deployment-status.svg?w=17&h=17", + }, }, files: map[string][]byte{ - "cluster-resources/replicasets/rook-ceph.json": []byte(collectedReplicaSets), + "cluster-resources/replicasets/rook-ceph.json": []byte(rookCephReplicaSets), + "cluster-resources/replicasets/default.json": []byte(defaultReplicaSets), }, }, } @@ -108,14 +141,19 @@ func Test_analyzeReplicaSetStatus(t *testing.T) { req := require.New(t) getFiles := func(n string) (map[string][]byte, error) { + if file, ok := test.files[n]; ok { + return map[string][]byte{n: file}, nil + } return test.files, nil } actual, err := analyzeReplicaSetStatus(&test.analyzer, getFiles) req.NoError(err) - assert.Equal(t, test.expectResult, actual) - + req.Equal(len(test.expectResult), len(actual)) + for _, a := range actual { + assert.Contains(t, test.expectResult, a) + } }) } } diff --git a/pkg/analyze/statefulset_status.go b/pkg/analyze/statefulset_status.go index 3f313101f..650cbad52 100644 --- a/pkg/analyze/statefulset_status.go +++ b/pkg/analyze/statefulset_status.go @@ -65,29 +65,37 @@ func analyzeOneStatefulsetStatus(analyzer *troubleshootv1beta2.StatefulsetStatus } func analyzeAllStatefulsetStatuses(analyzer *troubleshootv1beta2.StatefulsetStatus, getFileContents func(string) (map[string][]byte, error)) ([]*AnalyzeResult, error) { - var fileName string + fileNames := make([]string, 0) if analyzer.Namespace != "" { - fileName = filepath.Join("cluster-resources", "statefulsets", fmt.Sprintf("%s.json", analyzer.Namespace)) - } else { - fileName = filepath.Join("cluster-resources", "statefulsets", "*.json") + fileNames = append(fileNames, filepath.Join("cluster-resources", "statefulsets", fmt.Sprintf("%s.json", analyzer.Namespace))) + } + for _, ns := range analyzer.Namespaces { + fileNames = append(fileNames, filepath.Join("cluster-resources", "statefulsets", fmt.Sprintf("%s.json", ns))) } - files, err := getFileContents(fileName) - if err != nil { - return nil, errors.Wrap(err, "failed to read collected statefulsets from namespace") + // no namespace specified, so we need to analyze all statefulsets + if len(fileNames) == 0 { + fileNames = append(fileNames, filepath.Join("cluster-resources", "statefulsets", "*.json")) } results := []*AnalyzeResult{} - for _, collected := range files { - var statefulsets []appsv1.StatefulSet - if err := json.Unmarshal(collected, &statefulsets); err != nil { - return nil, errors.Wrap(err, "failed to unmarshal statefulset list") + for _, fileName := range fileNames { + files, err := getFileContents(fileName) + if err != nil { + return nil, errors.Wrap(err, "failed to read collected statefulsets from namespace") } - for _, statefulset := range statefulsets { - result := getDefaultStatefulSetResult(&statefulset) - if result != nil { - results = append(results, result) + for _, collected := range files { + var statefulsets []appsv1.StatefulSet + if err := json.Unmarshal(collected, &statefulsets); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal statefulset list") + } + + for _, statefulset := range statefulsets { + result := getDefaultStatefulSetResult(&statefulset) + if result != nil { + results = append(results, result) + } } } } diff --git a/pkg/analyze/statefulset_status_test.go b/pkg/analyze/statefulset_status_test.go new file mode 100644 index 000000000..78f5a00ca --- /dev/null +++ b/pkg/analyze/statefulset_status_test.go @@ -0,0 +1,89 @@ +package analyzer + +import ( + "testing" + + troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_analyzeStatefulsetStatus(t *testing.T) { + tests := []struct { + name string + analyzer troubleshootv1beta2.StatefulsetStatus + expectResult []*AnalyzeResult + files map[string][]byte + }{ + { + name: "analyze all statefulsets", + analyzer: troubleshootv1beta2.StatefulsetStatus{}, + expectResult: []*AnalyzeResult{ + { + IsPass: false, + IsWarn: false, + IsFail: true, + Title: "monitoring/alertmanager-prometheus-alertmanager Statefulset Status", + Message: "The statefulset monitoring/alertmanager-prometheus-alertmanager has 1/2 replicas", + IconKey: "kubernetes_statefulset_status", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/statefulset-status.svg?w=23&h=14", + }, + { + IsPass: false, + IsWarn: false, + IsFail: true, + Title: "default/kotsadm-postgres Statefulset Status", + Message: "The statefulset default/kotsadm-postgres has 1/2 replicas", + IconKey: "kubernetes_statefulset_status", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/statefulset-status.svg?w=23&h=14", + }, + }, + files: map[string][]byte{ + "cluster-resources/statefulsets/monitoring.json": []byte(monitoringStatefulSets), + "cluster-resources/statefulsets/default.json": []byte(defaultStatefulSets), + }, + }, + { + name: "analyze all statefulsets with namespaces", + analyzer: troubleshootv1beta2.StatefulsetStatus{ + Namespaces: []string{"monitoring"}, + }, + expectResult: []*AnalyzeResult{ + { + IsPass: false, + IsWarn: false, + IsFail: true, + Title: "monitoring/alertmanager-prometheus-alertmanager Statefulset Status", + Message: "The statefulset monitoring/alertmanager-prometheus-alertmanager has 1/2 replicas", + IconKey: "kubernetes_statefulset_status", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/statefulset-status.svg?w=23&h=14", + }, + }, + files: map[string][]byte{ + "cluster-resources/statefulsets/monitoring.json": []byte(monitoringStatefulSets), + "cluster-resources/statefulsets/default.json": []byte(defaultStatefulSets), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + req := require.New(t) + + getFiles := func(n string) (map[string][]byte, error) { + if file, ok := test.files[n]; ok { + return map[string][]byte{n: file}, nil + } + return test.files, nil + } + + actual, err := analyzeStatefulsetStatus(&test.analyzer, getFiles) + req.NoError(err) + + req.Equal(len(test.expectResult), len(actual)) + for _, a := range actual { + assert.Contains(t, test.expectResult, a) + } + }) + } +} diff --git a/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go b/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go index 889371ffe..679b68872 100644 --- a/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go @@ -49,10 +49,12 @@ type ImagePullSecret struct { Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"` RegistryName string `json:"registryName" yaml:"registryName"` } + type DeploymentStatus struct { AnalyzeMeta `json:",inline" yaml:",inline"` Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"` Namespace string `json:"namespace" yaml:"namespace"` + Namespaces []string `json:"namespaces" yaml:"namespaces"` Name string `json:"name" yaml:"name"` } @@ -60,6 +62,7 @@ type StatefulsetStatus struct { AnalyzeMeta `json:",inline" yaml:",inline"` Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"` Namespace string `json:"namespace" yaml:"namespace"` + Namespaces []string `json:"namespaces" yaml:"namespaces"` Name string `json:"name" yaml:"name"` } @@ -67,6 +70,7 @@ type JobStatus struct { AnalyzeMeta `json:",inline" yaml:",inline"` Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"` Namespace string `json:"namespace" yaml:"namespace"` + Namespaces []string `json:"namespaces" yaml:"namespaces"` Name string `json:"name" yaml:"name"` } @@ -74,6 +78,7 @@ type ReplicaSetStatus struct { AnalyzeMeta `json:",inline" yaml:",inline"` Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"` Namespace string `json:"namespace" yaml:"namespace"` + Namespaces []string `json:"namespaces" yaml:"namespaces"` Name string `json:"name" yaml:"name"` Selector []string `json:"selector" yaml:"selector"` } diff --git a/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go b/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go index cfff118cb..708bb2b50 100644 --- a/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go +++ b/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go @@ -1083,6 +1083,11 @@ func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { } } } + if in.Namespaces != nil { + in, out := &in.Namespaces, &out.Namespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStatus. @@ -2226,6 +2231,11 @@ func (in *JobStatus) DeepCopyInto(out *JobStatus) { } } } + if in.Namespaces != nil { + in, out := &in.Namespaces, &out.Namespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobStatus. @@ -3415,6 +3425,11 @@ func (in *ReplicaSetStatus) DeepCopyInto(out *ReplicaSetStatus) { } } } + if in.Namespaces != nil { + in, out := &in.Namespaces, &out.Namespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.Selector != nil { in, out := &in.Selector, &out.Selector *out = make([]string, len(*in)) @@ -3529,6 +3544,11 @@ func (in *StatefulsetStatus) DeepCopyInto(out *StatefulsetStatus) { } } } + if in.Namespaces != nil { + in, out := &in.Namespaces, &out.Namespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulsetStatus.