From c64ba4bf91c9daac0f5095ec60abc3c42d2b6b63 Mon Sep 17 00:00:00 2001 From: EJ Etherington Date: Mon, 17 Feb 2020 17:09:33 -0800 Subject: [PATCH 01/17] updating language aroudn the webook because admission controller is what people are really searching for, not webook --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b45de3865..779718780 100644 --- a/README.md +++ b/README.md @@ -49,10 +49,10 @@ The Polaris dashboard is a way to get a simple visual overview of the current st Our default standards in Polaris are rather high, so don’t be surprised if your score is lower than you might expect. A key goal for Polaris was to set a high standard and aim for great configuration by default. If the defaults we’ve included are too strict, it’s easy to adjust the configuration as part of the deployment configuration to better suit your workloads. -## Webhook +## Admission Controller: Validating Webhook > [View installation instructions](docs/usage.md#webhook) -Polaris includes an optional validating webhook. This accepts the same configuration as the dashboard, and can run the same validations. This webhook will reject any workloads that trigger a validation error. This is indicative of the greater goal of Polaris, not just to encourage better configuration through dashboard visibility, but to actually enforce it with this webhook. +Polaris can be run as an admission controller that acts as a validating webhook. This accepts the same configuration as the dashboard, and can run the same validations. This webhook will reject any workloads that trigger a validation error. This is indicative of the greater goal of Polaris, not just to encourage better configuration through dashboard visibility, but to actually enforce it with this webhook. Polaris will not fix your workloads, only block them. Unfortunately we have not found a way to display warnings as part of `kubectl` output unless we are rejecting a workload altogether. That means that any checks with a severity of `warning` will still pass webhook validation, and the only evidence of that warning will either be in the Polaris dashboard or the Polaris webhook logs. From 0da4ea69bfb98cdc0c4658ff7fcef494ff877f9f Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 25 Feb 2020 16:25:34 +0000 Subject: [PATCH 02/17] support some old controller versions --- pkg/kube/resources.go | 153 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 136 insertions(+), 17 deletions(-) diff --git a/pkg/kube/resources.go b/pkg/kube/resources.go index 6b867517c..de27c9d9a 100644 --- a/pkg/kube/resources.go +++ b/pkg/kube/resources.go @@ -2,6 +2,7 @@ package kube import ( "bytes" + "encoding/json" "io/ioutil" "os" "path/filepath" @@ -77,7 +78,7 @@ func CreateResourceProviderFromPath(directory string) (*ResourceProvider, error) } contents, err := ioutil.ReadFile(path) if err != nil { - logrus.Errorf("Error reading file %v", path) + logrus.Errorf("Error reading file: %v", path) return err } specs := regexp.MustCompile("\n-+\n").Split(string(contents), -1) @@ -105,12 +106,12 @@ func CreateResourceProviderFromPath(directory string) (*ResourceProvider, error) func CreateResourceProviderFromCluster() (*ResourceProvider, error) { kubeConf, configError := config.GetConfig() if configError != nil { - logrus.Errorf("Error fetching KubeConfig %v", configError) + logrus.Errorf("Error fetching KubeConfig: %v", configError) return nil, configError } api, err := kubernetes.NewForConfig(kubeConf) if err != nil { - logrus.Errorf("Error creating Kubernetes client %v", err) + logrus.Errorf("Error creating Kubernetes client: %v", err) return nil, err } return CreateResourceProviderFromAPI(api, kubeConf.Host) @@ -121,52 +122,50 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string listOpts := metav1.ListOptions{} serverVersion, err := kube.Discovery().ServerVersion() if err != nil { - logrus.Errorf("Error fetching Cluster API version %v", err) + logrus.Errorf("Error fetching Cluster API version: %v", err) return nil, err } - deploys, err := kube.AppsV1().Deployments("").List(listOpts) + deploys, err := getDeployments(kube) if err != nil { - logrus.Errorf("Error fetching Deployments %v", err) return nil, err } - statefulSets, err := kube.AppsV1().StatefulSets("").List(listOpts) + statefulSets, err := getStatefulSets(kube) if err != nil { - logrus.Errorf("Error fetching StatefulSets%v", err) return nil, err } daemonSets, err := kube.AppsV1().DaemonSets("").List(listOpts) if err != nil { - logrus.Errorf("Error fetching DaemonSets %v", err) + logrus.Errorf("Error fetching DaemonSets: %v", err) return nil, err } jobs, err := kube.BatchV1().Jobs("").List(listOpts) if err != nil { - logrus.Errorf("Error fetching Jobs %v", err) + logrus.Errorf("Error fetching Jobs: %v", err) return nil, err } cronJobs, err := kube.BatchV1beta1().CronJobs("").List(listOpts) if err != nil { - logrus.Errorf("Error fetching CronJobs %v", err) + logrus.Errorf("Error fetching CronJobs: %v", err) return nil, err } replicationControllers, err := kube.CoreV1().ReplicationControllers("").List(listOpts) if err != nil { - logrus.Errorf("Error fetching ReplicationControllers %v", err) + logrus.Errorf("Error fetching ReplicationControllers: %v", err) return nil, err } nodes, err := kube.CoreV1().Nodes().List(listOpts) if err != nil { - logrus.Errorf("Error fetching Nodes %v", err) + logrus.Errorf("Error fetching Nodes: %v", err) return nil, err } namespaces, err := kube.CoreV1().Namespaces().List(listOpts) if err != nil { - logrus.Errorf("Error fetching Namespaces %v", err) + logrus.Errorf("Error fetching Namespaces: %v", err) return nil, err } pods, err := kube.CoreV1().Pods("").List(listOpts) if err != nil { - logrus.Errorf("Error fetching Pods %v", err) + logrus.Errorf("Error fetching Pods: %v", err) return nil, err } @@ -175,8 +174,8 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string SourceType: "Cluster", SourceName: clusterName, CreationTime: time.Now(), - Deployments: deploys.Items, - StatefulSets: statefulSets.Items, + Deployments: deploys, + StatefulSets: statefulSets, DaemonSets: daemonSets.Items, Jobs: jobs.Items, CronJobs: cronJobs.Items, @@ -237,3 +236,123 @@ func addResourceFromString(contents string, resources *ResourceProvider) error { } return nil } + +func getDeployments(kube kubernetes.Interface) ([]appsv1.Deployment, error) { + listOpts := metav1.ListOptions{} + deployList, err := kube.AppsV1().Deployments("").List(listOpts) + if err != nil { + logrus.Errorf("Error fetching Deployments: %v", err) + return nil, err + } + deploys := deployList.Items + + oldDeploys := make([]interface{}, 0) + deploysV1B1, err := kube.AppsV1beta1().Deployments("").List(listOpts) + if err != nil { + logrus.Errorf("Error fetching Deployments v1beta1: %v", err) + return nil, err + } + for _, oldDeploy := range deploysV1B1.Items { + oldDeploys = append(oldDeploys, oldDeploy) + } + deploysV1B2, err := kube.AppsV1beta2().Deployments("").List(listOpts) + if err != nil { + logrus.Errorf("Error fetching Deployments v1beta2: %v", err) + return nil, err + } + for _, oldDeploy := range deploysV1B2.Items { + oldDeploys = append(oldDeploys, oldDeploy) + } + + for _, oldDeploy := range oldDeploys { + str, err := json.Marshal(oldDeploy) + if err != nil { + logrus.Errorf("Error marshaling old deployment version: %v", err) + return nil, err + } + deploy := appsv1.Deployment{} + err = json.Unmarshal(str, &deploy) + if err != nil { + logrus.Errorf("Error unmarshaling old deployment version: %v", err) + return nil, err + } + deploys = append(deploys, deploy) + } + return deploys, nil +} + +func getStatefulSets(kube kubernetes.Interface) ([]appsv1.StatefulSet, error) { + listOpts := metav1.ListOptions{} + controllerList, err := kube.AppsV1().StatefulSets("").List(listOpts) + if err != nil { + logrus.Errorf("Error fetching StatefulSets: %v", err) + return nil, err + } + controllers := controllerList.Items + + oldControllers := make([]interface{}, 0) + controllersV1B1, err := kube.AppsV1beta1().StatefulSets("").List(listOpts) + if err != nil { + logrus.Errorf("Error fetching StatefulSets v1beta1: %v", err) + return nil, err + } + for _, oldController := range controllersV1B1.Items { + oldControllers = append(oldControllers, oldController) + } + controllersV1B2, err := kube.AppsV1beta2().StatefulSets("").List(listOpts) + if err != nil { + logrus.Errorf("Error fetching StatefulSets v1beta2: %v", err) + return nil, err + } + for _, oldController := range controllersV1B2.Items { + oldControllers = append(oldControllers, oldController) + } + + for _, oldController := range oldControllers { + str, err := json.Marshal(oldController) + if err != nil { + logrus.Errorf("Error marshaling old StatefulSet version: %v", err) + return nil, err + } + controller := appsv1.StatefulSet{} + err = json.Unmarshal(str, &controller) + if err != nil { + logrus.Errorf("Error unmarshaling old StatefulSet version: %v", err) + return nil, err + } + controllers = append(controllers, controller) + } + return controllers, nil +} + +func getDaemonSets(kube kubernetes.Interface) ([]appsv1.DaemonSet, error) { + listOpts := metav1.ListOptions{} + controllerList, err := kube.AppsV1().DaemonSets("").List(listOpts) + if err != nil { + logrus.Errorf("Error fetching DaemonSets: %v", err) + return nil, err + } + controllers := controllerList.Items + + controllersV1B2, err := kube.AppsV1beta2().DaemonSets("").List(listOpts) + if err != nil { + logrus.Errorf("Error fetching DaemonSets v1beta2: %v", err) + return nil, err + } + + for _, oldController := range controllersV1B2.Items { + str, err := json.Marshal(oldController) + if err != nil { + logrus.Errorf("Error marshaling old DaemonSet version: %v", err) + return nil, err + } + controller := appsv1.DaemonSet{} + err = json.Unmarshal(str, &controller) + if err != nil { + logrus.Errorf("Error unmarshaling old DaemonSet version: %v", err) + return nil, err + } + controllers = append(controllers, controller) + } + return controllers, nil +} From a0604ba3a5e9d7a82e530835d002b72f944466f9 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 25 Feb 2020 16:29:02 +0000 Subject: [PATCH 03/17] add failing v2beta2 test case --- .../failing_test.deploymentv1beta2.yaml | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 test/webhook_cases/failing_test.deploymentv1beta2.yaml diff --git a/test/webhook_cases/failing_test.deploymentv1beta2.yaml b/test/webhook_cases/failing_test.deploymentv1beta2.yaml new file mode 100644 index 000000000..8f7d6c3b6 --- /dev/null +++ b/test/webhook_cases/failing_test.deploymentv1beta2.yaml @@ -0,0 +1,29 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 + securityContext: + allowPrivilegeEscalation: true + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL From 574a1483eb2c774f4db44d3ecba23129d90254a2 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 25 Feb 2020 17:49:20 +0000 Subject: [PATCH 04/17] add to supported controllers list --- deploy/webhook.yaml | 2 ++ pkg/config/supportedcontrollers.go | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/deploy/webhook.yaml b/deploy/webhook.yaml index 5db77c985..791f22718 100644 --- a/deploy/webhook.yaml +++ b/deploy/webhook.yaml @@ -314,6 +314,8 @@ spec: - webhook - --config - /opt/app/config.yaml + - --log-level + - debug image: 'quay.io/fairwinds/polaris:0.6' imagePullPolicy: 'Always' ports: diff --git a/pkg/config/supportedcontrollers.go b/pkg/config/supportedcontrollers.go index 1bca5c86d..2d3cc8fd8 100644 --- a/pkg/config/supportedcontrollers.go +++ b/pkg/config/supportedcontrollers.go @@ -7,6 +7,8 @@ import ( "strings" appsv1 "k8s.io/api/apps/v1" + appsv1beta1 "k8s.io/api/apps/v1beta1" + appsv1beta2 "k8s.io/api/apps/v1beta2" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" corev1 "k8s.io/api/core/v1" @@ -103,14 +105,19 @@ func (s SupportedController) ListSupportedAPIVersions() []runtime.Object { case Deployments: supportedVersions = []runtime.Object{ &appsv1.Deployment{}, + &appsv1beta1.Deployment{}, + &appsv1beta2.Deployment{}, } case StatefulSets: supportedVersions = []runtime.Object{ &appsv1.StatefulSet{}, + &appsv1beta1.StatefulSet{}, + &appsv1beta2.StatefulSet{}, } case DaemonSets: supportedVersions = []runtime.Object{ &appsv1.DaemonSet{}, + &appsv1beta2.DaemonSet{}, } case Jobs: supportedVersions = []runtime.Object{ From 51f3eaa3f09dab12b7b66e593abdc66113493b58 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 25 Feb 2020 20:21:22 +0000 Subject: [PATCH 05/17] add more webhook test cases, suport for cronjobs v2alpha1 --- pkg/config/supportedcontrollers.go | 2 + pkg/kube/resources.go | 43 ++++++++++++-- .../failing_test.cronjob.v2alpha1.yaml | 24 ++++++++ .../failing_test.daemonset.v1beta2.yaml | 48 ++++++++++++++++ .../failing_test.deployment.v1beta1.yaml | 29 ++++++++++ ...l => failing_test.deployment.v1beta2.yaml} | 0 .../failing_test.statefulset.v1beta1.yaml | 56 +++++++++++++++++++ .../failing_test.statefulset.v1beta2.yaml | 56 +++++++++++++++++++ 8 files changed, 252 insertions(+), 6 deletions(-) create mode 100644 test/webhook_cases/failing_test.cronjob.v2alpha1.yaml create mode 100644 test/webhook_cases/failing_test.daemonset.v1beta2.yaml create mode 100644 test/webhook_cases/failing_test.deployment.v1beta1.yaml rename test/webhook_cases/{failing_test.deploymentv1beta2.yaml => failing_test.deployment.v1beta2.yaml} (100%) create mode 100644 test/webhook_cases/failing_test.statefulset.v1beta1.yaml create mode 100644 test/webhook_cases/failing_test.statefulset.v1beta2.yaml diff --git a/pkg/config/supportedcontrollers.go b/pkg/config/supportedcontrollers.go index 2d3cc8fd8..2562859bd 100644 --- a/pkg/config/supportedcontrollers.go +++ b/pkg/config/supportedcontrollers.go @@ -11,6 +11,7 @@ import ( appsv1beta2 "k8s.io/api/apps/v1beta2" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" + batchv2alpha1 "k8s.io/api/batch/v2alpha1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" ) @@ -126,6 +127,7 @@ func (s SupportedController) ListSupportedAPIVersions() []runtime.Object { case CronJobs: supportedVersions = []runtime.Object{ &batchv1beta1.CronJob{}, + &batchv2alpha1.CronJob{}, } case ReplicationControllers: supportedVersions = []runtime.Object{ diff --git a/pkg/kube/resources.go b/pkg/kube/resources.go index de27c9d9a..532dfcd0f 100644 --- a/pkg/kube/resources.go +++ b/pkg/kube/resources.go @@ -133,6 +133,10 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string if err != nil { return nil, err } + cronJobs, err := getCronJobs(kube) + if err != nil { + return nil, err + } daemonSets, err := kube.AppsV1().DaemonSets("").List(listOpts) if err != nil { logrus.Errorf("Error fetching DaemonSets: %v", err) @@ -143,11 +147,6 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string logrus.Errorf("Error fetching Jobs: %v", err) return nil, err } - cronJobs, err := kube.BatchV1beta1().CronJobs("").List(listOpts) - if err != nil { - logrus.Errorf("Error fetching CronJobs: %v", err) - return nil, err - } replicationControllers, err := kube.CoreV1().ReplicationControllers("").List(listOpts) if err != nil { logrus.Errorf("Error fetching ReplicationControllers: %v", err) @@ -178,7 +177,7 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string StatefulSets: statefulSets, DaemonSets: daemonSets.Items, Jobs: jobs.Items, - CronJobs: cronJobs.Items, + CronJobs: cronJobs, ReplicationControllers: replicationControllers.Items, Nodes: nodes.Items, Namespaces: namespaces.Items, @@ -356,3 +355,35 @@ func getDaemonSets(kube kubernetes.Interface) ([]appsv1.DaemonSet, error) { } return controllers, nil } + +func getCronJobs(kube kubernetes.Interface) ([]batchv1beta1.CronJob, error) { + listOpts := metav1.ListOptions{} + controllerList, err := kube.BatchV1beta1().CronJobs("").List(listOpts) + if err != nil { + logrus.Errorf("Error fetching CronJobs: %v", err) + return nil, err + } + controllers := controllerList.Items + + controllersV2A1, err := kube.BatchV2alpha1().CronJobs("").List(listOpts) + if err != nil { + logrus.Errorf("Error fetching CronJobs v2alpha1: %v", err) + return nil, err + } + + for _, oldController := range controllersV2A1.Items { + str, err := json.Marshal(oldController) + if err != nil { + logrus.Errorf("Error marshaling old CronJob version: %v", err) + return nil, err + } + controller := batchv1beta1.CronJob{} + err = json.Unmarshal(str, &controller) + if err != nil { + logrus.Errorf("Error unmarshaling old CronJob version: %v", err) + return nil, err + } + controllers = append(controllers, controller) + } + return controllers, nil +} diff --git a/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml b/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml new file mode 100644 index 000000000..e4919d22e --- /dev/null +++ b/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml @@ -0,0 +1,24 @@ +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + name: test +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: test + image: busybox:uclibc + args: + - whoami + securityContext: + allowPrivilegeEscalation: true + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + restartPolicy: OnFailure \ No newline at end of file diff --git a/test/webhook_cases/failing_test.daemonset.v1beta2.yaml b/test/webhook_cases/failing_test.daemonset.v1beta2.yaml new file mode 100644 index 000000000..83f2a997a --- /dev/null +++ b/test/webhook_cases/failing_test.daemonset.v1beta2.yaml @@ -0,0 +1,48 @@ +apiVersion: apps/v1beta2 +kind: DaemonSet +metadata: + name: fluentd-elasticsearch + namespace: kube-system + labels: + k8s-app: fluentd-logging +spec: + selector: + matchLabels: + name: fluentd-elasticsearch + template: + metadata: + labels: + name: fluentd-elasticsearch + spec: + tolerations: + - key: node-role.kubernetes.io/master + effect: + containers: + - name: fluentd-elasticsearch + image: gcr.io/fluentd-elasticsearch/fluentd:v2.5.1 + resources: + requests: + cpu: 100m + volumeMounts: + - name: varlog + mountPath: /var/log + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + securityContext: + allowPrivilegeEscalation: true + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + terminationGracePeriodSeconds: 30 + volumes: + - name: varlog + hostPath: + path: /var/log + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + diff --git a/test/webhook_cases/failing_test.deployment.v1beta1.yaml b/test/webhook_cases/failing_test.deployment.v1beta1.yaml new file mode 100644 index 000000000..0cab0a54a --- /dev/null +++ b/test/webhook_cases/failing_test.deployment.v1beta1.yaml @@ -0,0 +1,29 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 + securityContext: + allowPrivilegeEscalation: true + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL diff --git a/test/webhook_cases/failing_test.deploymentv1beta2.yaml b/test/webhook_cases/failing_test.deployment.v1beta2.yaml similarity index 100% rename from test/webhook_cases/failing_test.deploymentv1beta2.yaml rename to test/webhook_cases/failing_test.deployment.v1beta2.yaml diff --git a/test/webhook_cases/failing_test.statefulset.v1beta1.yaml b/test/webhook_cases/failing_test.statefulset.v1beta1.yaml new file mode 100644 index 000000000..6579e03fa --- /dev/null +++ b/test/webhook_cases/failing_test.statefulset.v1beta1.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + name: web + clusterIP: None + selector: + app: nginx +--- +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: web +spec: + selector: + matchLabels: + app: nginx # has to match .spec.template.metadata.labels + serviceName: "nginx" + replicas: 3 # by default is 1 + template: + metadata: + labels: + app: nginx # has to match .spec.selector.matchLabels + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: nginx + image: k8s.gcr.io/nginx-slim:0.8 + ports: + - containerPort: 80 + name: web + volumeMounts: + - name: www + mountPath: /usr/share/nginx/html + securityContext: + allowPrivilegeEscalation: true + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + volumeClaimTemplates: + - metadata: + name: www + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: "my-storage-class" + resources: + requests: + storage: 1Gi diff --git a/test/webhook_cases/failing_test.statefulset.v1beta2.yaml b/test/webhook_cases/failing_test.statefulset.v1beta2.yaml new file mode 100644 index 000000000..eb697926d --- /dev/null +++ b/test/webhook_cases/failing_test.statefulset.v1beta2.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + name: web + clusterIP: None + selector: + app: nginx +--- +apiVersion: apps/v1beta2 +kind: StatefulSet +metadata: + name: web +spec: + selector: + matchLabels: + app: nginx # has to match .spec.template.metadata.labels + serviceName: "nginx" + replicas: 3 # by default is 1 + template: + metadata: + labels: + app: nginx # has to match .spec.selector.matchLabels + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: nginx + image: k8s.gcr.io/nginx-slim:0.8 + ports: + - containerPort: 80 + name: web + volumeMounts: + - name: www + mountPath: /usr/share/nginx/html + securityContext: + allowPrivilegeEscalation: true + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + volumeClaimTemplates: + - metadata: + name: www + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: "my-storage-class" + resources: + requests: + storage: 1Gi From c591765f70f486712af3390cb4eef816346b04bf Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 25 Feb 2020 21:05:32 +0000 Subject: [PATCH 06/17] add more webhook test cases, remove cronjob case --- .../failing_test.cronjob.v2alpha1.yaml | 24 -------- .../passing_test.daemonset.v1beta2.yaml | 48 ++++++++++++++++ .../passing_test.deployment.v1beta1.yaml | 29 ++++++++++ .../passing_test.deployment.v1beta2.yaml | 29 ++++++++++ .../passing_test.statefulset.v1beta1.yaml | 56 +++++++++++++++++++ .../passing_test.statefulset.v1beta2.yaml | 56 +++++++++++++++++++ 6 files changed, 218 insertions(+), 24 deletions(-) delete mode 100644 test/webhook_cases/failing_test.cronjob.v2alpha1.yaml create mode 100644 test/webhook_cases/passing_test.daemonset.v1beta2.yaml create mode 100644 test/webhook_cases/passing_test.deployment.v1beta1.yaml create mode 100644 test/webhook_cases/passing_test.deployment.v1beta2.yaml create mode 100644 test/webhook_cases/passing_test.statefulset.v1beta1.yaml create mode 100644 test/webhook_cases/passing_test.statefulset.v1beta2.yaml diff --git a/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml b/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml deleted file mode 100644 index e4919d22e..000000000 --- a/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: batch/v1beta1 -kind: CronJob -metadata: - name: test -spec: - schedule: "*/1 * * * *" - jobTemplate: - spec: - template: - spec: - containers: - - name: test - image: busybox:uclibc - args: - - whoami - securityContext: - allowPrivilegeEscalation: true - privileged: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - restartPolicy: OnFailure \ No newline at end of file diff --git a/test/webhook_cases/passing_test.daemonset.v1beta2.yaml b/test/webhook_cases/passing_test.daemonset.v1beta2.yaml new file mode 100644 index 000000000..c6d4b3804 --- /dev/null +++ b/test/webhook_cases/passing_test.daemonset.v1beta2.yaml @@ -0,0 +1,48 @@ +apiVersion: apps/v1beta2 +kind: DaemonSet +metadata: + name: fluentd-elasticsearch + namespace: kube-system + labels: + k8s-app: fluentd-logging +spec: + selector: + matchLabels: + name: fluentd-elasticsearch + template: + metadata: + labels: + name: fluentd-elasticsearch + spec: + tolerations: + - key: node-role.kubernetes.io/master + effect: + containers: + - name: fluentd-elasticsearch + image: gcr.io/fluentd-elasticsearch/fluentd:v2.5.1 + resources: + requests: + cpu: 100m + volumeMounts: + - name: varlog + mountPath: /var/log + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + terminationGracePeriodSeconds: 30 + volumes: + - name: varlog + hostPath: + path: /var/log + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + diff --git a/test/webhook_cases/passing_test.deployment.v1beta1.yaml b/test/webhook_cases/passing_test.deployment.v1beta1.yaml new file mode 100644 index 000000000..48f1cd861 --- /dev/null +++ b/test/webhook_cases/passing_test.deployment.v1beta1.yaml @@ -0,0 +1,29 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL diff --git a/test/webhook_cases/passing_test.deployment.v1beta2.yaml b/test/webhook_cases/passing_test.deployment.v1beta2.yaml new file mode 100644 index 000000000..55cfd08f7 --- /dev/null +++ b/test/webhook_cases/passing_test.deployment.v1beta2.yaml @@ -0,0 +1,29 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL diff --git a/test/webhook_cases/passing_test.statefulset.v1beta1.yaml b/test/webhook_cases/passing_test.statefulset.v1beta1.yaml new file mode 100644 index 000000000..4ae948536 --- /dev/null +++ b/test/webhook_cases/passing_test.statefulset.v1beta1.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + name: web + clusterIP: None + selector: + app: nginx +--- +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: web +spec: + selector: + matchLabels: + app: nginx # has to match .spec.template.metadata.labels + serviceName: "nginx" + replicas: 3 # by default is 1 + template: + metadata: + labels: + app: nginx # has to match .spec.selector.matchLabels + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: nginx + image: k8s.gcr.io/nginx-slim:0.8 + ports: + - containerPort: 80 + name: web + volumeMounts: + - name: www + mountPath: /usr/share/nginx/html + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + volumeClaimTemplates: + - metadata: + name: www + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: "my-storage-class" + resources: + requests: + storage: 1Gi diff --git a/test/webhook_cases/passing_test.statefulset.v1beta2.yaml b/test/webhook_cases/passing_test.statefulset.v1beta2.yaml new file mode 100644 index 000000000..604a5dc05 --- /dev/null +++ b/test/webhook_cases/passing_test.statefulset.v1beta2.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + name: web + clusterIP: None + selector: + app: nginx +--- +apiVersion: apps/v1beta2 +kind: StatefulSet +metadata: + name: web +spec: + selector: + matchLabels: + app: nginx # has to match .spec.template.metadata.labels + serviceName: "nginx" + replicas: 3 # by default is 1 + template: + metadata: + labels: + app: nginx # has to match .spec.selector.matchLabels + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: nginx + image: k8s.gcr.io/nginx-slim:0.8 + ports: + - containerPort: 80 + name: web + volumeMounts: + - name: www + mountPath: /usr/share/nginx/html + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + volumeClaimTemplates: + - metadata: + name: www + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: "my-storage-class" + resources: + requests: + storage: 1Gi From dad526245dc2636aa5fd65ed84ac14534bea8254 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 25 Feb 2020 21:23:31 +0000 Subject: [PATCH 07/17] don't exit if webhook registration fails --- cmd/polaris/webhook.go | 4 +++- pkg/webhook/validator.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/polaris/webhook.go b/cmd/polaris/webhook.go index a7bbbb89d..be9fa5eae 100644 --- a/cmd/polaris/webhook.go +++ b/cmd/polaris/webhook.go @@ -106,7 +106,9 @@ var webhookCmd = &cobra.Command{ for innerIndex, supportedAPIType := range controllerToScan.ListSupportedAPIVersions() { webhookName := strings.ToLower(fmt.Sprintf("%s-%d-%d", controllerToScan, index, innerIndex)) hook := fwebhook.NewWebhook(webhookName, mgr, fwebhook.Validator{Config: config}, supportedAPIType) - webhooks = append(webhooks, hook) + if hook != nil { + webhooks = append(webhooks, hook) + } } } diff --git a/pkg/webhook/validator.go b/pkg/webhook/validator.go index ba65d34f9..aeba03440 100644 --- a/pkg/webhook/validator.go +++ b/pkg/webhook/validator.go @@ -80,7 +80,7 @@ func NewWebhook(name string, mgr manager.Manager, validator Validator, apiType r Build() if err != nil { logrus.Errorf("Error building webhook: %v", err) - os.Exit(1) + return nil } else { logrus.Info(name + " webhook started") } From c036c91247e5b6665ef619c45b703241929df0f5 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 25 Feb 2020 21:23:40 +0000 Subject: [PATCH 08/17] add cronjob webhook test cases --- .../failing_test.cronjob.v2alpha1.yaml | 24 +++++++++++++++++++ .../passing_test.cronjob.v2alpha1.yaml | 24 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 test/webhook_cases/failing_test.cronjob.v2alpha1.yaml create mode 100644 test/webhook_cases/passing_test.cronjob.v2alpha1.yaml diff --git a/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml b/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml new file mode 100644 index 000000000..7955eb1e1 --- /dev/null +++ b/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml @@ -0,0 +1,24 @@ +apiVersion: batch/v2alpha1 +kind: CronJob +metadata: + name: test +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: test + image: busybox:uclibc + args: + - whoami + securityContext: + allowPrivilegeEscalation: true + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + restartPolicy: OnFailure diff --git a/test/webhook_cases/passing_test.cronjob.v2alpha1.yaml b/test/webhook_cases/passing_test.cronjob.v2alpha1.yaml new file mode 100644 index 000000000..1d663c1ac --- /dev/null +++ b/test/webhook_cases/passing_test.cronjob.v2alpha1.yaml @@ -0,0 +1,24 @@ +apiVersion: batch/v2alpha1 +kind: CronJob +metadata: + name: test +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: test + image: busybox:uclibc + args: + - whoami + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + restartPolicy: OnFailure From efd0ec85b94838ed9c626731d00842190feb2582 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 25 Feb 2020 21:26:28 +0000 Subject: [PATCH 09/17] fix lint error --- pkg/webhook/validator.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkg/webhook/validator.go b/pkg/webhook/validator.go index aeba03440..f93064a38 100644 --- a/pkg/webhook/validator.go +++ b/pkg/webhook/validator.go @@ -18,7 +18,6 @@ import ( "context" "fmt" "net/http" - "os" "github.com/fairwindsops/polaris/pkg/config" validator "github.com/fairwindsops/polaris/pkg/validator" @@ -81,9 +80,8 @@ func NewWebhook(name string, mgr manager.Manager, validator Validator, apiType r if err != nil { logrus.Errorf("Error building webhook: %v", err) return nil - } else { - logrus.Info(name + " webhook started") } + logrus.Info(name + " webhook started") return webhook } From 3e9193af7f59687c108f4a6bdd83c6ec3f503c02 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 25 Feb 2020 21:39:46 +0000 Subject: [PATCH 10/17] remove cronjob cases --- .../failing_test.cronjob.v2alpha1.yaml | 24 ------------------- .../passing_test.cronjob.v2alpha1.yaml | 24 ------------------- 2 files changed, 48 deletions(-) delete mode 100644 test/webhook_cases/failing_test.cronjob.v2alpha1.yaml delete mode 100644 test/webhook_cases/passing_test.cronjob.v2alpha1.yaml diff --git a/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml b/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml deleted file mode 100644 index 7955eb1e1..000000000 --- a/test/webhook_cases/failing_test.cronjob.v2alpha1.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: batch/v2alpha1 -kind: CronJob -metadata: - name: test -spec: - schedule: "*/1 * * * *" - jobTemplate: - spec: - template: - spec: - containers: - - name: test - image: busybox:uclibc - args: - - whoami - securityContext: - allowPrivilegeEscalation: true - privileged: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - restartPolicy: OnFailure diff --git a/test/webhook_cases/passing_test.cronjob.v2alpha1.yaml b/test/webhook_cases/passing_test.cronjob.v2alpha1.yaml deleted file mode 100644 index 1d663c1ac..000000000 --- a/test/webhook_cases/passing_test.cronjob.v2alpha1.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: batch/v2alpha1 -kind: CronJob -metadata: - name: test -spec: - schedule: "*/1 * * * *" - jobTemplate: - spec: - template: - spec: - containers: - - name: test - image: busybox:uclibc - args: - - whoami - securityContext: - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - restartPolicy: OnFailure From ec4e755f2f00e001d0b6258a48484b1c0435d18b Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 25 Feb 2020 21:40:23 +0000 Subject: [PATCH 11/17] remove debug logs --- deploy/webhook.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/deploy/webhook.yaml b/deploy/webhook.yaml index 791f22718..5db77c985 100644 --- a/deploy/webhook.yaml +++ b/deploy/webhook.yaml @@ -314,8 +314,6 @@ spec: - webhook - --config - /opt/app/config.yaml - - --log-level - - debug image: 'quay.io/fairwinds/polaris:0.6' imagePullPolicy: 'Always' ports: From d2bb2f126b4a354acc60a0b46339a7db046e3f3d Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Wed, 26 Feb 2020 19:26:18 +0000 Subject: [PATCH 12/17] test extra controller versions --- pkg/kube/resources.go | 8 ++-- pkg/validator/fullaudit_test.go | 51 ++++++++++++------------- test/fixtures.go | 67 +++++++++++++++++++++++++++++---- 3 files changed, 88 insertions(+), 38 deletions(-) diff --git a/pkg/kube/resources.go b/pkg/kube/resources.go index 532dfcd0f..67a3be664 100644 --- a/pkg/kube/resources.go +++ b/pkg/kube/resources.go @@ -137,11 +137,11 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string if err != nil { return nil, err } - daemonSets, err := kube.AppsV1().DaemonSets("").List(listOpts) + daemonSets, err := getDaemonSets(kube) if err != nil { - logrus.Errorf("Error fetching DaemonSets: %v", err) return nil, err } + jobs, err := kube.BatchV1().Jobs("").List(listOpts) if err != nil { logrus.Errorf("Error fetching Jobs: %v", err) @@ -175,9 +175,9 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string CreationTime: time.Now(), Deployments: deploys, StatefulSets: statefulSets, - DaemonSets: daemonSets.Items, - Jobs: jobs.Items, + DaemonSets: daemonSets, CronJobs: cronJobs, + Jobs: jobs.Items, ReplicationControllers: replicationControllers.Items, Nodes: nodes.Items, Namespaces: namespaces.Items, diff --git a/pkg/validator/fullaudit_test.go b/pkg/validator/fullaudit_test.go index b51bf5957..c5cdd7f8d 100644 --- a/pkg/validator/fullaudit_test.go +++ b/pkg/validator/fullaudit_test.go @@ -12,6 +12,7 @@ import ( func TestGetTemplateData(t *testing.T) { k8s := test.SetupTestAPI() k8s = test.SetupAddControllers(k8s, "test") + k8s = test.SetupAddExtraControllerVersions(k8s, "test-extra") resources, err := kube.CreateResourceProviderFromAPI(k8s, "test") assert.Equal(t, err, nil, "error should be nil") @@ -32,8 +33,8 @@ func TestGetTemplateData(t *testing.T) { sum := CountSummary{ Successes: uint(0), - Warnings: uint(4), - Errors: uint(4), + Warnings: uint(9), + Errors: uint(9), } actualAudit, err := RunAudit(c, resources) @@ -43,29 +44,27 @@ func TestGetTemplateData(t *testing.T) { assert.Equal(t, actualAudit.SourceType, "Cluster", "should be from a cluster") assert.Equal(t, actualAudit.SourceName, "test", "should be from a cluster") - assert.Equal(t, 6, len(actualAudit.Results)) - - assert.Equal(t, "Deployment", actualAudit.Results[0].Kind) - assert.Equal(t, 1, len(actualAudit.Results[0].PodResult.ContainerResults)) - assert.Equal(t, 2, len(actualAudit.Results[0].PodResult.ContainerResults[0].Results)) - - assert.Equal(t, "StatefulSet", actualAudit.Results[1].Kind) - assert.Equal(t, 1, len(actualAudit.Results[1].PodResult.ContainerResults)) - assert.Equal(t, 2, len(actualAudit.Results[1].PodResult.ContainerResults[0].Results)) - - assert.Equal(t, "DaemonSet", actualAudit.Results[2].Kind) - assert.Equal(t, 1, len(actualAudit.Results[2].PodResult.ContainerResults)) - assert.Equal(t, 2, len(actualAudit.Results[2].PodResult.ContainerResults[0].Results)) - - assert.Equal(t, "Job", actualAudit.Results[3].Kind) - assert.Equal(t, 1, len(actualAudit.Results[3].PodResult.ContainerResults)) - assert.Equal(t, 0, len(actualAudit.Results[3].PodResult.ContainerResults[0].Results)) - - assert.Equal(t, "CronJob", actualAudit.Results[4].Kind) - assert.Equal(t, 1, len(actualAudit.Results[4].PodResult.ContainerResults)) - assert.Equal(t, 0, len(actualAudit.Results[4].PodResult.ContainerResults[0].Results)) + expected := []struct { + kind string + results int + }{ + {kind: "Deployment", results: 2}, + {kind: "Deployment", results: 2}, + {kind: "Deployment", results: 2}, + {kind: "StatefulSet", results: 2}, + {kind: "StatefulSet", results: 2}, + {kind: "StatefulSet", results: 2}, + {kind: "DaemonSet", results: 2}, + {kind: "DaemonSet", results: 2}, + {kind: "Job", results: 0}, + {kind: "CronJob", results: 0}, + {kind: "ReplicationController", results: 2}, + } - assert.Equal(t, "ReplicationController", actualAudit.Results[5].Kind) - assert.Equal(t, 1, len(actualAudit.Results[5].PodResult.ContainerResults)) - assert.Equal(t, 2, len(actualAudit.Results[5].PodResult.ContainerResults[0].Results)) + assert.Equal(t, len(expected), len(actualAudit.Results)) + for idx, result := range actualAudit.Results { + assert.Equal(t, expected[idx].kind, result.Kind) + assert.Equal(t, 1, len(result.PodResult.ContainerResults)) + assert.Equal(t, expected[idx].results, len(result.PodResult.ContainerResults[0].Results)) + } } diff --git a/test/fixtures.go b/test/fixtures.go index 4b25f91d9..303b0613d 100644 --- a/test/fixtures.go +++ b/test/fixtures.go @@ -1,9 +1,9 @@ package test import ( - "fmt" - appsv1 "k8s.io/api/apps/v1" + appsv1beta1 "k8s.io/api/apps/v1beta1" + appsv1beta2 "k8s.io/api/apps/v1beta2" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" corev1 "k8s.io/api/core/v1" @@ -104,33 +104,84 @@ func SetupTestAPI() kubernetes.Interface { func SetupAddControllers(k kubernetes.Interface, namespace string) kubernetes.Interface { d1 := MockDeploy() if _, err := k.AppsV1().Deployments(namespace).Create(&d1); err != nil { - fmt.Println(err) + panic(err) } s1 := MockStatefulSet() if _, err := k.AppsV1().StatefulSets(namespace).Create(&s1); err != nil { - fmt.Println(err) + panic(err) } ds1 := MockDaemonSet() if _, err := k.AppsV1().DaemonSets(namespace).Create(&ds1); err != nil { - fmt.Println(err) + panic(err) } j1 := MockJob() if _, err := k.BatchV1().Jobs(namespace).Create(&j1); err != nil { - fmt.Println(err) + panic(err) } cj1 := MockCronJob() if _, err := k.BatchV1beta1().CronJobs(namespace).Create(&cj1); err != nil { - fmt.Println(err) + panic(err) } rc1 := MockReplicationController() if _, err := k.CoreV1().ReplicationControllers(namespace).Create(&rc1); err != nil { - fmt.Println(err) + panic(err) + } + + return k +} + +// SetupAddExtraControllerVersions creates mock controllers and adds them to the test clientset. +func SetupAddExtraControllerVersions(k kubernetes.Interface, namespace string) kubernetes.Interface { + p := MockPod() + + dv1b1 := appsv1beta1.Deployment{ + Spec: appsv1beta1.DeploymentSpec{ + Template: p, + }, + } + if _, err := k.AppsV1beta1().Deployments(namespace).Create(&dv1b1); err != nil { + panic(err) + } + + dv1b2 := appsv1beta2.Deployment{ + Spec: appsv1beta2.DeploymentSpec{ + Template: p, + }, + } + if _, err := k.AppsV1beta2().Deployments(namespace).Create(&dv1b2); err != nil { + panic(err) + } + + ssv1b1 := appsv1beta1.StatefulSet{ + Spec: appsv1beta1.StatefulSetSpec{ + Template: p, + }, + } + if _, err := k.AppsV1beta1().StatefulSets(namespace).Create(&ssv1b1); err != nil { + panic(err) } + ssv1b2 := appsv1beta2.StatefulSet{ + Spec: appsv1beta2.StatefulSetSpec{ + Template: p, + }, + } + if _, err := k.AppsV1beta2().StatefulSets(namespace).Create(&ssv1b2); err != nil { + panic(err) + } + + dsv1b2 := appsv1beta2.DaemonSet{ + Spec: appsv1beta2.DaemonSetSpec{ + Template: p, + }, + } + if _, err := k.AppsV1beta2().DaemonSets(namespace).Create(&dsv1b2); err != nil { + panic(err) + } return k } From 6a1cee846a2e3b17453e34f576885ef2287e149d Mon Sep 17 00:00:00 2001 From: Bob van Bokkem Date: Fri, 6 Mar 2020 08:12:52 +0100 Subject: [PATCH 13/17] Command argument error `polaris --webhook` --- deploy/webhook.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/webhook.yaml b/deploy/webhook.yaml index 5db77c985..f288d9585 100644 --- a/deploy/webhook.yaml +++ b/deploy/webhook.yaml @@ -311,7 +311,7 @@ spec: - name: webhook command: - polaris - - webhook + - --webhook - --config - /opt/app/config.yaml image: 'quay.io/fairwinds/polaris:0.6' From 2a0ed94d0da0670cf2ca34ab845d5c450db909bb Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Fri, 6 Mar 2020 15:10:38 +0000 Subject: [PATCH 14/17] fix deploy yaml --- deploy/dashboard.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/dashboard.yaml b/deploy/dashboard.yaml index 915381e9a..ee514972f 100644 --- a/deploy/dashboard.yaml +++ b/deploy/dashboard.yaml @@ -251,7 +251,7 @@ spec: containers: - command: - polaris - - dashboard + - --dashboard - --config - /opt/app/config.yaml image: 'quay.io/fairwinds/polaris:0.6' From 33d4192871bb7e65998d016293c374e5f176d995 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Fri, 6 Mar 2020 16:46:54 +0000 Subject: [PATCH 15/17] fix test deploy files --- test/kube_dashboard_test.sh | 2 ++ test/webhook_test.sh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/kube_dashboard_test.sh b/test/kube_dashboard_test.sh index 0da43b89c..8366088b3 100755 --- a/test/kube_dashboard_test.sh +++ b/test/kube_dashboard_test.sh @@ -1,4 +1,6 @@ sed -ri "s|'(quay.io/fairwinds/polaris:).+'|'\1${CIRCLE_SHA1}'|" ./deploy/dashboard.yaml +# TODO: remove this after 1.0 is released +sed -i "s/--dashboard/dashboard/" ./deploy/dashboard.yaml function check_dashboard_is_ready() { diff --git a/test/webhook_test.sh b/test/webhook_test.sh index 9909ad32d..276c3d64e 100755 --- a/test/webhook_test.sh +++ b/test/webhook_test.sh @@ -3,6 +3,8 @@ set -e #sed is replacing the polaris version with this commit sha so we are testing exactly this verison. sed -ri "s|'(quay.io/fairwinds/polaris:).+'|'\1${CIRCLE_SHA1}'|" ./deploy/webhook.yaml +# TODO: remove this after 1.0 is released +sed -i "s/--webhook/webhook/" ./deploy/webhook.yaml # Testing to ensure that the webhook starts up, allows a correct deployment to pass, # and prevents a incorrectly formatted deployment. From 1b2a930a9c8f38654934dba99c6ef397feddef86 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Mon, 9 Mar 2020 12:25:11 -0400 Subject: [PATCH 16/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 779718780..4c7955e17 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Polaris can be run in three different modes: * As a [validating webhook](#webhook), so you can automatically reject workloads that don't adhere to your organization's policies. * As a [command-line tool](#cli), so you can test local YAML files, e.g. as part of a CI/CD process. -**Want to learn more?** Fairwinds holds [office hours on Zoom](https://zoom.us/j/242508205) the first Friday of every month, at 12pm Eastern. You can also reach out via email at `opensource@fairwinds.com` +**Want to learn more?** Reach out on [the Slack channel](https://fairwindscommunity.slack.com/messages/polaris), send an email to `opensource@fairwinds.com`, or join us for [office hours on Zoom](https://fairwindscommunity.slack.com/messages/office-hours) # Dashboard Quickstart From 3191f087bbd52cf0b0e86a12066b9fa04cc5406f Mon Sep 17 00:00:00 2001 From: Alexander Lyon Date: Sat, 14 Mar 2020 17:51:09 +0100 Subject: [PATCH 17/17] Fix chart repository name (#256) charts.fairwindsops.com doesn't resolve, fixed according to FairwindsOps/charts --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index da46f83d4..0983be818 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -95,7 +95,7 @@ kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80 ``` ### Helm ```bash -helm repo add fairwinds-stable https://charts.fairwindsops.com/stable +helm repo add fairwinds-stable https://charts.fairwinds.com/stable helm upgrade --install polaris fairwinds-stable/polaris --namespace polaris kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80 ```