Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b72508e0b | ||
|
|
5c5d3d4e5d | ||
|
|
52df126b93 | ||
|
|
6ae13d8603 | ||
|
|
6aff3c8ee0 | ||
|
|
714add15e2 | ||
|
|
05da87eadf | ||
|
|
908a3a9c72 | ||
|
|
3e8a3c92e6 | ||
|
|
bddfece857 |
@@ -1,25 +1,10 @@
|
||||
version: 2.1
|
||||
|
||||
orbs:
|
||||
rok8s: fairwinds/rok8s-scripts@12
|
||||
oss-docs: fairwinds/oss-docs@0
|
||||
|
||||
executors:
|
||||
vm:
|
||||
machine:
|
||||
enabled: true
|
||||
|
||||
commands:
|
||||
install_goreleaser_dependencies:
|
||||
description: Installs dependencies for CI scripts
|
||||
steps:
|
||||
- run: apk update
|
||||
# gettext provides envsubst
|
||||
- run: apk add gettext
|
||||
# Register other docker platforms, to build arm64.
|
||||
# This shouldn't be needed, why TBD.
|
||||
- run: docker run --privileged --rm tonistiigi/binfmt --install all
|
||||
|
||||
references:
|
||||
set_environment_variables: &set_environment_variables
|
||||
run:
|
||||
@@ -33,7 +18,6 @@ references:
|
||||
echo 'export GOPROXY=https://proxy.golang.org' >> ${BASH_ENV}
|
||||
echo 'export GO111MODULE=on' >> ${BASH_ENV}
|
||||
echo 'export GOFLAGS=-mod=mod' >> ${BASH_ENV}
|
||||
echo 'export GORELEASER_CURRENT_TAG="${CIRCLE_TAG}"' >> $BASH_ENV
|
||||
|
||||
install_k8s: &install_k8s
|
||||
run:
|
||||
@@ -44,20 +28,20 @@ references:
|
||||
sudo apt-get install -yqq jq git
|
||||
|
||||
echo "Installing KIND"
|
||||
curl -sLO https://github.com/kubernetes-sigs/kind/releases/download/v0.19.0/kind-linux-amd64
|
||||
curl -sLO https://github.com/kubernetes-sigs/kind/releases/download/v0.8.1/kind-linux-amd64
|
||||
chmod 0755 kind-linux-amd64
|
||||
sudo mv kind-linux-amd64 /usr/local/bin/kind
|
||||
kind version
|
||||
|
||||
echo "Installing Kubectl"
|
||||
curl -sLO https://storage.googleapis.com/kubernetes-release/release/v1.25.10/bin/linux/amd64/kubectl
|
||||
curl -sLO https://storage.googleapis.com/kubernetes-release/release/v1.18.6/bin/linux/amd64/kubectl
|
||||
chmod 0755 kubectl
|
||||
sudo mv kubectl /usr/local/bin/
|
||||
kubectl version --client
|
||||
|
||||
|
||||
echo "Creating Kubernetes Cluster with Kind"
|
||||
kind create cluster --wait=90s --image kindest/node:v1.25.9@sha256:c08d6c52820aa42e533b70bce0c2901183326d86dcdcbedecc9343681db45161
|
||||
kind create cluster --wait=90s --image kindest/node:v1.15.11
|
||||
docker ps -a
|
||||
|
||||
kubectl version
|
||||
@@ -68,17 +52,18 @@ references:
|
||||
./get_helm.sh
|
||||
|
||||
echo "Installing cert-manager"
|
||||
kubectl create namespace cert-manager
|
||||
helm repo add jetstack https://charts.jetstack.io
|
||||
helm repo update
|
||||
echo "Helm install"
|
||||
helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.12.1 --set "installCRDs=true" --wait --create-namespace
|
||||
helm install cert-manager jetstack/cert-manager --namespace cert-manager --version 0.16.1 --set "installCRDs=true" --wait
|
||||
echo "Install cert-manager successful"
|
||||
|
||||
test_binary_dashboard: &test_binary_dashboard
|
||||
run:
|
||||
name: Test Dashboard
|
||||
command: |
|
||||
go run main.go dashboard --port 3000 --audit-path ./pkg/config/examples &
|
||||
go run main.go dashboard --port 3000 --audit-path ./examples &
|
||||
sleep 30
|
||||
curl -f http://localhost:3000 > /dev/null
|
||||
curl -f http://localhost:3000/health > /dev/null
|
||||
@@ -97,85 +82,196 @@ references:
|
||||
echo "Skipping Kubernetes tests for forked PR"
|
||||
fi
|
||||
|
||||
install_vault_alpine: &install_vault_alpine
|
||||
# Release scripts
|
||||
install_goreleaser: &install_goreleaser
|
||||
run:
|
||||
name: install hashicorp vault
|
||||
name: Install GoReleaser
|
||||
command: |
|
||||
apk --update add curl yq
|
||||
cd /tmp
|
||||
curl -LO https://releases.hashicorp.com/vault/1.13.2/vault_1.13.2_linux_amd64.zip
|
||||
sha256sum vault_1.13.2_linux_amd64.zip | grep f7930279de8381de7c532164b4a4408895d9606c0d24e2e9d2f9acb5dfe99b3c
|
||||
unzip vault_1.13.2_linux_amd64.zip
|
||||
mv vault /usr/bin/vault
|
||||
curl -fsSLo goreleaser.deb https://github.com/goreleaser/goreleaser/releases/download/v0.174.2/goreleaser_amd64.deb
|
||||
echo "bad33997ea9977a84196bdca1d5993fada909cd81c3e88d52bd297666bea61a4 goreleaser.deb" | sha256sum -c -
|
||||
sudo dpkg -i goreleaser.deb
|
||||
rm goreleaser.deb
|
||||
|
||||
docker_build: &docker_build
|
||||
run:
|
||||
name: Docker login and build
|
||||
command: |
|
||||
docker-pull -f .circleci/build.config
|
||||
docker-build -f .circleci/build.config
|
||||
|
||||
docker_build_and_push: &docker_build_and_push
|
||||
run:
|
||||
name: Docker login, build, and push
|
||||
command: |
|
||||
docker-pull -f .circleci/build.config
|
||||
docker-build -f .circleci/build.config
|
||||
docker login quay.io -u="${fairwinds_quay_user}" -p="${fairwinds_quay_token}"
|
||||
docker-push -f .circleci/build.config
|
||||
|
||||
release_deploy_configs: &release_deploy_configs
|
||||
run:
|
||||
name: Release deploy configs
|
||||
command: |
|
||||
upload_url=$(curl --silent https://api.github.com/repos/FairwindsOps/polaris/releases/latest | grep upload_url)
|
||||
upload_url=$(echo $upload_url | sed -e 's/.*\(https.*\){.*$/\1/')
|
||||
curl -X POST "$upload_url?name=dashboard.yaml" --data-binary "@./deploy/dashboard.yaml" -H "Authorization: Bearer $GITHUB_TOKEN" -H "Content-Type: application/x-yaml"
|
||||
curl -X POST "$upload_url?name=webhook.yaml" --data-binary "@./deploy/webhook.yaml" -H "Authorization: Bearer $GITHUB_TOKEN" -H "Content-Type: application/x-yaml"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: quay.io/reactiveops/ci-images:v11.0-stretch
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- *set_environment_variables
|
||||
- *docker_build
|
||||
|
||||
push:
|
||||
docker:
|
||||
- image: quay.io/reactiveops/ci-images:v11.0-stretch
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- *set_environment_variables
|
||||
- *docker_build_and_push
|
||||
|
||||
test_k8s:
|
||||
working_directory: ~/polaris
|
||||
resource_class: medium
|
||||
executor: vm
|
||||
steps:
|
||||
- checkout
|
||||
- *set_environment_variables
|
||||
- *install_k8s
|
||||
- *test_k8s
|
||||
|
||||
test:
|
||||
working_directory: /go/src/github.com/fairwindsops/polaris/
|
||||
docker:
|
||||
- image: cimg/go:1.22
|
||||
- image: circleci/golang:1.16
|
||||
steps:
|
||||
- checkout
|
||||
- *set_environment_variables
|
||||
- run: go vet ./...
|
||||
- run: go get -u golang.org/x/lint/golint
|
||||
- run: go list ./... | grep -v vendor | xargs golint -set_exit_status
|
||||
- run: go list ./... | grep -v vendor | xargs go vet
|
||||
- run: go test ./... -coverprofile=coverage.txt -covermode=count
|
||||
- run: go run main.go audit --audit-path ./deploy --set-exit-code-below-score 100 --set-exit-code-on-danger
|
||||
- *test_binary_dashboard
|
||||
|
||||
build_and_push:
|
||||
working_directory: /go/src/github.com/fairwindsops/polaris/
|
||||
resource_class: large
|
||||
shell: /bin/bash
|
||||
insights:
|
||||
docker:
|
||||
# The goreleaser image tag determins the version of Go.
|
||||
# Manually check goreleaser images for their version of Go.
|
||||
# Ref: https://hub.docker.com/r/goreleaser/goreleaser/tags
|
||||
- image: goreleaser/goreleaser:v2.3.2
|
||||
- image: quay.io/reactiveops/ci-images:v11.0-stretch
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- run:
|
||||
name: Adjust configs for latest image
|
||||
command: |
|
||||
sed -r "s|'(quay.io/fairwinds/polaris:).+'|'\1${CIRCLE_SHA1}'|" ./deploy/webhook.yaml > ./deploy/dashboard.yaml
|
||||
sed -r "s|'(quay.io/fairwinds/polaris:).+'|'\1${CIRCLE_SHA1}'|" ./deploy/dashboard.yaml > ./deploy/webhook.yaml
|
||||
- run:
|
||||
name: Insights CI
|
||||
command: curl -L https://insights.fairwinds.com/v0/insights-ci.sh | bash
|
||||
|
||||
release_binary:
|
||||
working_directory: /go/src/github.com/fairwindsops/polaris/
|
||||
docker:
|
||||
- image: circleci/golang:1.16
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- *install_vault_alpine
|
||||
- rok8s/get_vault_env:
|
||||
vault_path: repo/global/env
|
||||
- rok8s/get_vault_env:
|
||||
vault_path: repo/polaris/env
|
||||
- *set_environment_variables
|
||||
- run: docker login quay.io -u="${FAIRWINDS_QUAY_USER}" -p="${FAIRWINDS_QUAY_TOKEN}"
|
||||
- install_goreleaser_dependencies
|
||||
- run: scripts/goreleaser.sh
|
||||
- *install_goreleaser
|
||||
- run: go get -u github.com/gobuffalo/packr/v2/packr2
|
||||
- run: git checkout -- . # FIXME: the go get makes the directory dirty
|
||||
- run: packr2
|
||||
- run: goreleaser
|
||||
- *release_deploy_configs
|
||||
|
||||
release_images:
|
||||
working_directory: /go/src/github.com/fairwindsops/polaris/
|
||||
docker:
|
||||
- image: quay.io/reactiveops/ci-images:v11.0-stretch
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- *set_environment_variables
|
||||
- *docker_build_and_push
|
||||
|
||||
publish_docs:
|
||||
docker:
|
||||
- image: cimg/node:15.5.1
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Build Docs Site
|
||||
command: |
|
||||
set -e
|
||||
cd ./docs
|
||||
npm install
|
||||
npm run check-links
|
||||
npm run build
|
||||
- run:
|
||||
name: Install AWS CLI
|
||||
command: |
|
||||
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
||||
unzip awscliv2.zip
|
||||
sudo ./aws/install
|
||||
- run:
|
||||
name: Publish Docs Site to S3
|
||||
command: |
|
||||
cd ./dist
|
||||
aws s3 sync ./ s3://polaris.docs.fairwinds.com --delete
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
|
||||
release:
|
||||
build:
|
||||
jobs:
|
||||
- test:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
- build_and_push:
|
||||
- test
|
||||
- build:
|
||||
requires:
|
||||
- test
|
||||
- push:
|
||||
context: org-global
|
||||
requires:
|
||||
- build
|
||||
filters:
|
||||
branches:
|
||||
ignore: /pull\/[0-9]+/
|
||||
- insights:
|
||||
requires:
|
||||
- push
|
||||
filters:
|
||||
branches:
|
||||
ignore: /pull\/[0-9]+/
|
||||
tags:
|
||||
ignore: /^testing-.*/
|
||||
- test_k8s:
|
||||
requires:
|
||||
- build_and_push
|
||||
- push
|
||||
filters:
|
||||
branches:
|
||||
ignore: /pull\/[0-9]+/
|
||||
|
||||
release:
|
||||
jobs:
|
||||
- release_binary:
|
||||
context: org-global
|
||||
filters:
|
||||
branches:
|
||||
ignore: /.*/
|
||||
tags:
|
||||
ignore: /^testing-.*/
|
||||
- oss-docs/publish-docs:
|
||||
repository: polaris
|
||||
- release_images:
|
||||
requires:
|
||||
- release_binary
|
||||
context: org-global
|
||||
filters:
|
||||
branches:
|
||||
ignore: /.*/
|
||||
tags:
|
||||
ignore: /^testing-.*/
|
||||
- publish_docs:
|
||||
filters:
|
||||
branches:
|
||||
ignore: /.*/
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
name: Bug Report
|
||||
description: File a bug report
|
||||
labels: [bug, triage]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report! Please fill the form below.
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: What happened?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: What did you expect to happen?
|
||||
description: What is the expected or desired behavior?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproducible
|
||||
attributes:
|
||||
label: How can we reproduce this?
|
||||
description: Please share the steps that we can take to reproduce this. Also include any relevant configuration.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: The version of the tool that you are using. If a helm chart, please share the name of the chart.
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: search
|
||||
attributes:
|
||||
label: Search
|
||||
options:
|
||||
- label: I did search for other open and closed issues before opening this.
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow the CODE_OF_CONDUCT in this repository.
|
||||
options:
|
||||
- label: I agree to follow this project's Code of Conduct
|
||||
required: true
|
||||
- type: textarea
|
||||
id: ctx
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Anything else you would like to add
|
||||
validations:
|
||||
required: false
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
name: Bug report
|
||||
about: Let us know about an unexpected error, a crash, or an incorrect behavior.
|
||||
|
||||
---
|
||||
### Installation Process
|
||||
<!---
|
||||
Did you install polaris on your local machine, or in a kubernetes cluster? Did you use kubectl, helm, brew, a GitHub release, or the source code? Let us know below.
|
||||
-->
|
||||
|
||||
### Polaris Version
|
||||
<!---
|
||||
If you are using polaris locally, run `polaris --version` to show the version, and paste the result between the ``` marks below.
|
||||
|
||||
If you are not running the latest version of Polaris, please try upgrading because your issue may have already been fixed.
|
||||
-->
|
||||
|
||||
```
|
||||
...
|
||||
```
|
||||
|
||||
### Expected Behavior
|
||||
<!--
|
||||
What should have happened?
|
||||
-->
|
||||
|
||||
### Actual Behavior
|
||||
<!--
|
||||
What actually happened?
|
||||
-->
|
||||
|
||||
### Steps to Reproduce
|
||||
<!--
|
||||
Please list the full steps required to reproduce the issue, for example:
|
||||
1. `polaris --audit --output-format score`
|
||||
-->
|
||||
|
||||
### Additional Context
|
||||
<!--
|
||||
Are there anything atypical about your situation that we should know?
|
||||
-->
|
||||
|
||||
### References
|
||||
<!--
|
||||
Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here? For example:
|
||||
|
||||
- #6017
|
||||
|
||||
-->
|
||||
@@ -2,7 +2,7 @@
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: [triage, enhancement]
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
name: Other
|
||||
about: For misc. tasks like research or continued conversation
|
||||
title: ''
|
||||
labels: [triage]
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# The action uses an own Dockerfile on purpose because the root Dockerfile takes way too long to build for an action
|
||||
|
||||
FROM alpine:3.17
|
||||
FROM alpine:3.10
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
|
||||
@@ -17,4 +17,4 @@ mkdir polaris
|
||||
tar -xzf $TARGET_FILE -C polaris
|
||||
rm $TARGET_FILE
|
||||
echo "polaris" >> $GITHUB_PATH
|
||||
echo "version=$INPUT_VERSION" >> $GITHUB_OUTPUT
|
||||
echo "::set-output name=version::$INPUT_VERSION"
|
||||
@@ -1,20 +1,44 @@
|
||||
## DO NOT EDIT - Managed by Terraform
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/docs"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 0
|
||||
ignore:
|
||||
- dependency-name: "*"
|
||||
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: gomod
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
time: "11:00"
|
||||
ignore:
|
||||
- dependency-name: cloud.google.com/go
|
||||
versions:
|
||||
- ">= 0.57.a, < 0.58"
|
||||
- dependency-name: github.com/go-logr/logr
|
||||
versions:
|
||||
- ">= 0.2.a, < 0.3"
|
||||
- dependency-name: github.com/go-logr/zapr
|
||||
versions:
|
||||
- ">= 0.2.a, < 0.3"
|
||||
- dependency-name: github.com/googleapis/gnostic
|
||||
versions:
|
||||
- ">= 0.4.a, < 0.5"
|
||||
- dependency-name: github.com/googleapis/gnostic
|
||||
versions:
|
||||
- ">= 0.5.a, < 0.6"
|
||||
- dependency-name: github.com/qri-io/jsonschema
|
||||
versions:
|
||||
- ">= 0.2.a, < 0.3"
|
||||
- dependency-name: k8s.io/api
|
||||
versions:
|
||||
- ">= 0.19.a, < 0.20"
|
||||
- dependency-name: k8s.io/apimachinery
|
||||
versions:
|
||||
- ">= 0.19.a, < 0.20"
|
||||
- dependency-name: k8s.io/client-go
|
||||
versions:
|
||||
- ">= 0.19.a, < 0.20"
|
||||
- dependency-name: sigs.k8s.io/controller-runtime
|
||||
versions:
|
||||
- ">= 0.5.a, < 0.6"
|
||||
- dependency-name: sigs.k8s.io/controller-runtime
|
||||
versions:
|
||||
- ">= 0.8.a, < 0.9"
|
||||
- dependency-name: k8s.io/apimachinery
|
||||
versions:
|
||||
- 0.20.4
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
This PR fixes #
|
||||
|
||||
## Checklist
|
||||
* [ ] I have signed the CLA
|
||||
* [ ] I have updated/added any relevant documentation
|
||||
|
||||
## Description
|
||||
### What's the goal of this PR?
|
||||
|
||||
### What changes did you make?
|
||||
|
||||
### What alternative solution should we consider, if any?
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
daysUntilStale: 30
|
||||
daysUntilClose: 7
|
||||
onlyLabels: []
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
|
||||
exemptProjects: false
|
||||
exemptMilestones: true
|
||||
exemptAssignees: false
|
||||
staleLabel: stale
|
||||
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
||||
limitPerRun: 30
|
||||
@@ -1,18 +0,0 @@
|
||||
name: 'Close stale issues and PRs'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '32 1 * * *'
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v4
|
||||
with:
|
||||
exempt-issue-labels: pinned
|
||||
stale-pr-label: stale
|
||||
stale-issue-label: stale
|
||||
@@ -7,7 +7,7 @@ jobs:
|
||||
build-int:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup polaris
|
||||
uses: ./.github/actions/setup-polaris
|
||||
with:
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
build-ext:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup polaris
|
||||
uses: fairwindsops/polaris/.github/actions/setup-polaris@master
|
||||
with:
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
# goreleaser is run via a wrapper that creates .goreleaser.yml from .goreleaser.yml.envsubst
|
||||
.goreleaser.yml
|
||||
# dist
|
||||
# # Binaries for programs and plugins
|
||||
.go-version
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
@@ -23,6 +19,7 @@ Tiltfile
|
||||
main
|
||||
.DS_Store
|
||||
|
||||
*-packr.go
|
||||
dist
|
||||
.vscode
|
||||
|
||||
@@ -30,4 +27,3 @@ dist
|
||||
|
||||
node_modules
|
||||
/dist
|
||||
docs/README.md
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
builds:
|
||||
- id: polaris
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
- GO111MODULE=on
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
goarm:
|
||||
- 6
|
||||
- 7
|
||||
archives:
|
||||
- id: polaris
|
||||
builds: ["polaris"]
|
||||
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}"
|
||||
brews:
|
||||
- name: polaris
|
||||
tap:
|
||||
owner: FairwindsOps
|
||||
name: homebrew-tap
|
||||
folder: Formula
|
||||
description: Open Source Best Practices for Kubernetes
|
||||
test: |
|
||||
system "#{bin}/polaris version"
|
||||
@@ -1,114 +0,0 @@
|
||||
version: 2
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
env:
|
||||
- GOBIN={{ .Env.TMPDIR }}/go-bin
|
||||
before:
|
||||
hooks:
|
||||
- go mod download
|
||||
builds:
|
||||
- id: polaris
|
||||
ldflags:
|
||||
- -X main.Version={{.Version}} -X main.Commit={{.Commit}} -s -w
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
- GO111MODULE=on
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
goarm:
|
||||
- 6
|
||||
- 7
|
||||
archives:
|
||||
- id: polaris
|
||||
builds: ["polaris"]
|
||||
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}"
|
||||
signs:
|
||||
- cmd: cosign
|
||||
args: ["sign-blob", "--key=hashivault://cosign", "-output-signature=${signature}", "${artifact}"]
|
||||
artifacts: checksum
|
||||
release:
|
||||
# This is replaced using `envsubst`, depending on the git branch.
|
||||
disable: ${skip_release}
|
||||
prerelease: auto
|
||||
footer: |
|
||||
You can verify the signature of the checksums.txt file using [cosign](https://github.com/sigstore/cosign).
|
||||
|
||||
```
|
||||
cosign verify-blob checksums.txt --signature=checksums.txt.sig --key https://artifacts.fairwinds.com/cosign.pub
|
||||
```
|
||||
brews:
|
||||
- name: polaris
|
||||
# This is replaced using `envsubst`, depending on the git branch.
|
||||
skip_upload: ${skip_release}
|
||||
repository:
|
||||
owner: FairwindsOps
|
||||
name: homebrew-tap
|
||||
directory: Formula
|
||||
description: Open Source Best Practices for Kubernetes
|
||||
url_template: "https://github.com/FairwindsOps/polaris/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
|
||||
test: |
|
||||
system "#{bin}/polaris version"
|
||||
dockers:
|
||||
# There are multiple images to match the `--platform` docker build flag with
|
||||
# combinations of `GOOS`, `GOARCH`, and `GOARM`
|
||||
- image_templates:
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-amd64"
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--platform=linux/amd64"
|
||||
- image_templates:
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-arm64"
|
||||
use: buildx
|
||||
goarch: arm64
|
||||
goos: linux
|
||||
build_flag_templates:
|
||||
- "--platform=linux/arm64"
|
||||
docker_manifests:
|
||||
# Create DOcker manifests that make multiple architectures available within a tag,
|
||||
# and provide partial-version tags like 2, and 2.2.
|
||||
- name_template: quay.io/fairwinds/polaris:{{ .FullCommit }}
|
||||
image_templates:
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-amd64"
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-arm64"
|
||||
- name_template: quay.io/fairwinds/polaris:{{ .Env.feature_docker_tag }}
|
||||
# This is replaced using `envsubst`, depending on the git branch.
|
||||
skip_push: ${skip_feature_docker_tags}
|
||||
image_templates:
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-amd64"
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-arm64"
|
||||
- name_template: quay.io/fairwinds/polaris:latest
|
||||
# This is replaced using `envsubst`, depending on the git branch.
|
||||
skip_push: ${skip_release}
|
||||
image_templates:
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-amd64"
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-arm64"
|
||||
- name_template: quay.io/fairwinds/polaris:{{ .Tag }}
|
||||
# This is replaced using `envsubst`, depending on the git branch.
|
||||
skip_push: ${skip_release}
|
||||
image_templates:
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-amd64"
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-arm64"
|
||||
- name_template: quay.io/fairwinds/polaris:{{ .Major }}
|
||||
# This is replaced using `envsubst`, depending on the git branch.
|
||||
skip_push: ${skip_release}
|
||||
image_templates:
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-amd64"
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-arm64"
|
||||
- name_template: quay.io/fairwinds/polaris:{{ .Major }}.{{ .Minor }}
|
||||
# This is replaced using `envsubst`, depending on the git branch.
|
||||
skip_push: ${skip_release}
|
||||
image_templates:
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-amd64"
|
||||
- "quay.io/fairwinds/polaris:{{ .FullCommit }}-arm64"
|
||||
@@ -1,24 +0,0 @@
|
||||
header:
|
||||
license:
|
||||
spdx-id: Apache-2.0
|
||||
copyright-owner: 'FairwindsOps, Inc.'
|
||||
content: |
|
||||
// Copyright 2019 FairwindsOps Inc
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
paths:
|
||||
- '**/*.go'
|
||||
comment: on-failure
|
||||
dependency:
|
||||
files:
|
||||
- go.mod
|
||||
@@ -1,2 +1 @@
|
||||
## DO NOT EDIT - Managed by Terraform
|
||||
* @sudermanjr @jdesouza @vitorvezani
|
||||
* @rbren @makoscafee
|
||||
@@ -1,21 +1,27 @@
|
||||
FROM alpine:3.21
|
||||
FROM golang:1.16 AS build-env
|
||||
WORKDIR /go/src/github.com/fairwindsops/polaris/
|
||||
|
||||
LABEL org.opencontainers.image.authors="FairwindsOps, Inc." \
|
||||
org.opencontainers.image.vendor="FairwindsOps, Inc." \
|
||||
org.opencontainers.image.title="polaris" \
|
||||
org.opencontainers.image.description="Polaris is a cli tool to help discover deprecated apiVersions in Kubernetes" \
|
||||
org.opencontainers.image.documentation="https://polaris.docs.fairwinds.com/" \
|
||||
org.opencontainers.image.source="https://github.com/FairwindsOps/polaris" \
|
||||
org.opencontainers.image.url="https://github.com/FairwindsOps/polaris" \
|
||||
org.opencontainers.image.licenses="Apache License 2.0"
|
||||
ENV GO111MODULE=on
|
||||
ENV GOPROXY=https://proxy.golang.org
|
||||
ENV CGO_ENABLED=0
|
||||
ENV GOOS=linux
|
||||
ENV GOARCH=amd64
|
||||
|
||||
COPY go.mod .
|
||||
COPY go.sum .
|
||||
RUN go mod download
|
||||
RUN go get -u github.com/gobuffalo/packr/v2/packr2
|
||||
|
||||
COPY . .
|
||||
RUN packr2 build -a -o polaris *.go
|
||||
|
||||
FROM alpine:3.14
|
||||
WORKDIR /usr/local/bin
|
||||
RUN apk -U upgrade
|
||||
RUN apk --no-cache add ca-certificates
|
||||
|
||||
RUN addgroup -S polaris && adduser -u 1200 -S polaris -G polaris
|
||||
USER 1200
|
||||
COPY polaris .
|
||||
COPY --from=build-env /go/src/github.com/fairwindsops/polaris/polaris .
|
||||
|
||||
WORKDIR /opt/app
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<div align="center" class="no-border">
|
||||
<img src="https://polaris.docs.fairwinds.com/img/polaris-logo.png" alt="Polaris Logo">
|
||||
<br>
|
||||
<h3>Polaris is an open source policy engine for Kubernetes</h3>
|
||||
<a href="https://github.com/FairwindsOps/polaris/releases">
|
||||
<img src="https://img.shields.io/github/v/release/FairwindsOps/polaris">
|
||||
<h3>Best Practices for Kubernetes Workload Configuration</h3>
|
||||
<a href="https://github.com/FairwindsOps/polaris">
|
||||
<img src="https://img.shields.io/static/v1.svg?label=Version&message=4.2.0&color=239922">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/FairwindsOps/polaris">
|
||||
<img src="https://goreportcard.com/badge/github.com/FairwindsOps/polaris">
|
||||
@@ -16,12 +16,15 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
Polaris is an open source policy engine for Kubernetes that validates and remediates resource configuration. It includes 30+ built in configuration policies, as well as the ability to build custom policies with JSON Schema. When run on the command line or as a mutating webhook, Polaris can automatically remediate issues based on policy criteria.
|
||||
Fairwinds' Polaris keeps your clusters sailing smoothly. It runs a variety of checks to ensure that
|
||||
Kubernetes pods and controllers are configured using best practices, helping you avoid
|
||||
problems in the future.
|
||||
|
||||
Polaris can be run in three different modes:
|
||||
* As a [dashboard](https://polaris.docs.fairwinds.com/dashboard) - Validate Kubernetes resources against policy-as-code.
|
||||
* As an [admission controller](https://polaris.docs.fairwinds.com/admission-controller) - Automatically reject or modify workloads that don't adhere to your organization's policies.
|
||||
* As a [command-line tool](https://polaris.docs.fairwinds.com/infrastructure-as-code) - Incorporate policy-as-code into the CI/CD process to test local YAML files.
|
||||
* As a [dashboard](https://polaris.docs.fairwinds.com/dashboard), so you can audit what's running inside your cluster.
|
||||
* As an [admission controller](https://polaris.docs.fairwinds.com/admission-controller), so you can automatically reject workloads that don't adhere to your organization's policies.
|
||||
* As a [command-line tool](https://polaris.docs.fairwinds.com/infrastructure-as-code), so you can test local YAML files, e.g. as part of a CI/CD process.
|
||||
|
||||
<p align="center">
|
||||
<img src="https://polaris.docs.fairwinds.com/img/architecture.svg" alt="Polaris Architecture" width="550"/>
|
||||
</p>
|
||||
@@ -34,13 +37,12 @@ Check out the [documentation at docs.fairwinds.com](https://polaris.docs.fairwin
|
||||
|
||||
The goal of the Fairwinds Community is to exchange ideas, influence the open source roadmap,
|
||||
and network with fellow Kubernetes users.
|
||||
[Chat with us on Slack](https://join.slack.com/t/fairwindscommunity/shared_invite/zt-2na8gtwb4-DGQ4qgmQbczQyB2NlFlYQQ)
|
||||
[Chat with us on Slack](https://join.slack.com/t/fairwindscommunity/shared_invite/zt-e3c6vj4l-3lIH6dvKqzWII5fSSFDi1g)
|
||||
or
|
||||
[join the user group](https://www.fairwinds.com/open-source-software-user-group) to get involved!
|
||||
|
||||
<a href="https://insights.fairwinds.com/auth/register/">
|
||||
<img src="https://www.fairwinds.com/hubfs/Doc_Banners/Fairwinds_OSS_User_Group_740x125_v6.png"
|
||||
alt="Love Fairwinds Open Source? Automate Fairwinds Open Source for free with Fairwinds Insights. Click to learn more" />
|
||||
<a href="https://www.fairwinds.com/t-shirt-offer?utm_source=polaris&utm_medium=polaris&utm_campaign=polaris-tshirt">
|
||||
<img src="https://www.fairwinds.com/hubfs/Doc_Banners/Fairwinds_OSS_User_Group_740x125_v6.png" alt="Love Fairwinds Open Source? Share your business email and job title and we'll send you a free Fairwinds t-shirt!" />
|
||||
</a>
|
||||
|
||||
## Other Projects from Fairwinds
|
||||
@@ -56,9 +58,9 @@ Or [check out the full list](https://www.fairwinds.com/open-source-software?utm_
|
||||
If you're interested in running Polaris in multiple clusters,
|
||||
tracking the results over time, integrating with Slack, Datadog, and Jira,
|
||||
or unlocking other functionality, check out
|
||||
[Fairwinds Insights](https://fairwinds.com/pricing),
|
||||
[Fairwinds Insights](https://www.fairwinds.com/polaris-user-insights-demo?utm_source=polaris&utm_medium=polaris&utm_campaign=polaris),
|
||||
a platform for auditing and enforcing policy in Kubernetes clusters.
|
||||
|
||||
<a href="https://fairwinds.com/pricing">
|
||||
<a href="https://www.fairwinds.com/polaris-user-insights-demo?utm_source=polaris&utm_medium=ad&utm_campaign=polarisad">
|
||||
<img src="https://www.fairwinds.com/hubfs/Doc_Banners/Fairwinds_Polaris_Ad.png" alt="Fairwinds Insights" />
|
||||
</a>
|
||||
|
||||
@@ -25,8 +25,3 @@ schema:
|
||||
type: string
|
||||
not:
|
||||
const: ''
|
||||
mutations:
|
||||
- op: add
|
||||
path: /resources/limits/cpu
|
||||
value: 100m
|
||||
comment: "TODO: Set this to the maximum amount of CPU you want your workload to use"
|
||||
@@ -25,8 +25,3 @@ schema:
|
||||
type: string
|
||||
not:
|
||||
const: ''
|
||||
mutations:
|
||||
- op: add
|
||||
path: /resources/requests/cpu
|
||||
value: 100m
|
||||
comment: "TODO: Set this to the amount of CPU you want to reserve for your workload"
|
||||
@@ -24,8 +24,3 @@ schema:
|
||||
- not:
|
||||
contains:
|
||||
pattern: '^(?i)NET_ADMIN$'
|
||||
|
||||
|
||||
mutations:
|
||||
- op: remove
|
||||
path: /securityContext/capabilities/add
|
||||
@@ -1,7 +1,7 @@
|
||||
successMessage: Host IPC is not configured
|
||||
failureMessage: Host IPC should not be configured
|
||||
category: Security
|
||||
target: PodSpec
|
||||
target: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
@@ -9,6 +9,3 @@ schema:
|
||||
hostIPC:
|
||||
not:
|
||||
const: true
|
||||
mutations:
|
||||
- op: remove
|
||||
path: /hostIPC
|
||||
@@ -1,7 +1,7 @@
|
||||
successMessage: Host network is not configured
|
||||
failureMessage: Host network should not be configured
|
||||
category: Security
|
||||
target: PodSpec
|
||||
target: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
@@ -9,6 +9,3 @@ schema:
|
||||
hostNetwork:
|
||||
not:
|
||||
const: true
|
||||
mutations:
|
||||
- op: remove
|
||||
path: /hostNetwork
|
||||
@@ -1,7 +1,7 @@
|
||||
successMessage: Host PID is not configured
|
||||
failureMessage: Host PID should not be configured
|
||||
category: Security
|
||||
target: PodSpec
|
||||
target: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
@@ -9,6 +9,3 @@ schema:
|
||||
hostPID:
|
||||
not:
|
||||
const: true
|
||||
mutations:
|
||||
- op: remove
|
||||
path: /hostPID
|
||||
@@ -13,6 +13,3 @@ schema:
|
||||
properties:
|
||||
hostPort:
|
||||
const: 0
|
||||
mutations:
|
||||
- op: remove
|
||||
path: /ports/*/hostPort
|
||||
@@ -54,7 +54,3 @@ schema:
|
||||
pattern: '^(?i)KILL$'
|
||||
- contains:
|
||||
pattern: '^(?i)AUDIT_WRITE$'
|
||||
mutations:
|
||||
- op: replace
|
||||
path: /securityContext/capabilities
|
||||
value: {"drop": ["ALL"]}
|
||||
@@ -19,8 +19,3 @@ schema:
|
||||
type: object
|
||||
not:
|
||||
const: null
|
||||
mutations:
|
||||
- op: add
|
||||
path: /livenessProbe
|
||||
value: {"exec": { "command": [ "cat", "/tmp/healthy" ] }, "initialDelaySeconds": 5, "periodSeconds": 5 }
|
||||
comment: "TODO: Change the livenessProbe setting to reflect your application's health"
|
||||
@@ -25,8 +25,3 @@ schema:
|
||||
type: string
|
||||
not:
|
||||
const: ''
|
||||
mutations:
|
||||
- op: add
|
||||
path: /resources/limits/memory
|
||||
value: "512Mi"
|
||||
comment: "TODO: Set this to the maximum amount of memory you want your workload to use"
|
||||
@@ -25,8 +25,3 @@ schema:
|
||||
type: string
|
||||
not:
|
||||
const: ''
|
||||
mutations:
|
||||
- op: add
|
||||
path: /resources/requests/memory
|
||||
value: "512Mi"
|
||||
comment: "TODO: Set this to the amount of Memory you want to reserve for your workload"
|
||||
@@ -1,6 +1,6 @@
|
||||
successMessage: example FP success
|
||||
failureMessage: example FP fail
|
||||
target: Pod
|
||||
successMessage: Label app.kubernetes.io/name matches metadata.name
|
||||
failureMessage: Label app.kubernetes.io/name must match metadata.name
|
||||
target: Controller
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
@@ -4,27 +4,17 @@ category: Reliability
|
||||
target: Controller
|
||||
controllers:
|
||||
include:
|
||||
- Deployment
|
||||
- Deployment
|
||||
schema:
|
||||
"$schema": http://json-schema.org/draft-07/schema#
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required: [spec]
|
||||
properties:
|
||||
spec:
|
||||
metadata:
|
||||
type: object
|
||||
required: [template]
|
||||
properties:
|
||||
template:
|
||||
labels:
|
||||
type: object
|
||||
required: [metadata]
|
||||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
required: [labels]
|
||||
properties:
|
||||
labels:
|
||||
type: object
|
||||
minProperties: 1
|
||||
minProperties: 1
|
||||
additionalSchemaStrings:
|
||||
policy/PodDisruptionBudget: |
|
||||
type: object
|
||||
@@ -40,7 +30,7 @@ additionalSchemaStrings:
|
||||
matchLabels:
|
||||
type: object
|
||||
anyOf:
|
||||
{{ range $key, $value := .spec.template.metadata.labels }}
|
||||
{{ range $key, $value := .metadata.labels }}
|
||||
- properties:
|
||||
"{{ $key }}":
|
||||
type: string
|
||||
@@ -19,7 +19,3 @@ schema:
|
||||
replicas:
|
||||
type: integer
|
||||
minimum: 2
|
||||
mutations:
|
||||
- op: add
|
||||
path: /spec/replicas
|
||||
value: 3
|
||||
@@ -2,7 +2,7 @@ successMessage: Filesystem is read only
|
||||
failureMessage: Filesystem should be read only
|
||||
category: Security
|
||||
target: Container
|
||||
schemaTarget: PodSpec
|
||||
schemaTarget: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
definitions:
|
||||
@@ -40,9 +40,4 @@ schema:
|
||||
- securityContext
|
||||
properties:
|
||||
securityContext:
|
||||
$ref: "#/definitions/goodSecurityContext"
|
||||
mutations:
|
||||
- op: add
|
||||
path: /securityContext/readOnlyRootFilesystem
|
||||
value: true
|
||||
|
||||
$ref: "#/definitions/goodSecurityContext"
|
||||
@@ -1,13 +1,9 @@
|
||||
successMessage: Priority class has been set
|
||||
failureMessage: Priority class should be set
|
||||
category: Reliability
|
||||
target: PodSpec
|
||||
category: Security
|
||||
target: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
- priorityClassName
|
||||
mutations:
|
||||
- op: add
|
||||
path: /priorityClassName
|
||||
value: high-priority
|
||||
@@ -2,7 +2,7 @@ successMessage: Privilege escalation not allowed
|
||||
failureMessage: Privilege escalation should not be allowed
|
||||
category: Security
|
||||
target: Container
|
||||
schemaTarget: PodSpec
|
||||
schemaTarget: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
definitions:
|
||||
@@ -40,9 +40,4 @@ schema:
|
||||
- securityContext
|
||||
properties:
|
||||
securityContext:
|
||||
$ref: "#/definitions/goodSecurityContext"
|
||||
|
||||
mutations:
|
||||
- op: add
|
||||
path: /securityContext/allowPrivilegeEscalation
|
||||
value: false
|
||||
$ref: "#/definitions/goodSecurityContext"
|
||||
@@ -9,7 +9,3 @@ schema:
|
||||
properties:
|
||||
imagePullPolicy:
|
||||
const: Always
|
||||
mutations:
|
||||
- op: add
|
||||
path: /imagePullPolicy
|
||||
value: Always
|
||||
@@ -19,8 +19,3 @@ schema:
|
||||
type: object
|
||||
not:
|
||||
const: null
|
||||
mutations:
|
||||
- op: add
|
||||
path: /readinessProbe
|
||||
value: {"exec": { "command": [ "cat", "/tmp/healthy" ] }, "initialDelaySeconds": 5, "periodSeconds": 5 }
|
||||
comment: "TODO: Change the readinessProbe setting to reflect your application's readiness to serve traffic"
|
||||
@@ -2,7 +2,7 @@ successMessage: Not running as privileged
|
||||
failureMessage: Should not be running as privileged
|
||||
category: Security
|
||||
target: Container
|
||||
schemaTarget: PodSpec
|
||||
schemaTarget: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
definitions:
|
||||
@@ -21,8 +21,4 @@ schema:
|
||||
items:
|
||||
properties:
|
||||
securityContext:
|
||||
$ref: "#/definitions/notBadSecurityContext"
|
||||
mutations:
|
||||
- op: add
|
||||
path: /securityContext/privileged
|
||||
value: false
|
||||
$ref: "#/definitions/notBadSecurityContext"
|
||||
@@ -2,7 +2,7 @@ successMessage: Is not allowed to run as root
|
||||
failureMessage: Should not be allowed to run as root
|
||||
category: Security
|
||||
target: Container
|
||||
schemaTarget: PodSpec
|
||||
schemaTarget: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
definitions:
|
||||
@@ -50,7 +50,3 @@ schema:
|
||||
properties:
|
||||
securityContext:
|
||||
$ref: "#/definitions/goodSecurityContext"
|
||||
mutations:
|
||||
- op: add
|
||||
path: /securityContext/runAsNonRoot
|
||||
value: true
|
||||
@@ -17,21 +17,13 @@ package cmd
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
workloads "github.com/fairwindsops/insights-plugins/plugins/workloads"
|
||||
workloadsPkg "github.com/fairwindsops/insights-plugins/plugins/workloads/pkg"
|
||||
|
||||
"github.com/fairwindsops/polaris/pkg/auth"
|
||||
cfg "github.com/fairwindsops/polaris/pkg/config"
|
||||
"github.com/fairwindsops/polaris/pkg/insights"
|
||||
"github.com/fairwindsops/polaris/pkg/kube"
|
||||
"github.com/fairwindsops/polaris/pkg/validator"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -39,26 +31,16 @@ import (
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var (
|
||||
setExitCode bool
|
||||
onlyShowFailedTests bool
|
||||
minScore int
|
||||
auditOutputURL string
|
||||
auditOutputFile string
|
||||
auditOutputFormat string
|
||||
resourceToAudit string
|
||||
useColor bool
|
||||
helmChart string
|
||||
helmValues []string
|
||||
helmSkipTests bool
|
||||
checks []string
|
||||
auditNamespace string
|
||||
severityLevel string
|
||||
skipSslValidation bool
|
||||
uploadInsights bool
|
||||
clusterName string
|
||||
quiet bool
|
||||
)
|
||||
var setExitCode bool
|
||||
var onlyShowFailedTests bool
|
||||
var minScore int
|
||||
var auditOutputURL string
|
||||
var auditOutputFile string
|
||||
var auditOutputFormat string
|
||||
var resourceToAudit string
|
||||
var useColor bool
|
||||
var helmChart string
|
||||
var helmValues string
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(auditCmd)
|
||||
@@ -73,15 +55,7 @@ func init() {
|
||||
auditCmd.PersistentFlags().StringVar(&displayName, "display-name", "", "An optional identifier for the audit.")
|
||||
auditCmd.PersistentFlags().StringVar(&resourceToAudit, "resource", "", "Audit a specific resource, in the format namespace/kind/version/name, e.g. nginx-ingress/Deployment.apps/v1/default-backend.")
|
||||
auditCmd.PersistentFlags().StringVar(&helmChart, "helm-chart", "", "Will fill out Helm template")
|
||||
auditCmd.PersistentFlags().StringSliceVar(&helmValues, "helm-values", []string{}, "Optional flag to add helm values")
|
||||
auditCmd.PersistentFlags().BoolVar(&helmSkipTests, "helm-skip-tests", false, "Corresponds to --skip-tests of helm template")
|
||||
auditCmd.PersistentFlags().StringSliceVar(&checks, "checks", []string{}, "Optional flag to specify specific checks to check")
|
||||
auditCmd.PersistentFlags().StringVar(&auditNamespace, "namespace", "", "Namespace to audit. Only applies to in-cluster audits")
|
||||
auditCmd.PersistentFlags().StringVar(&severityLevel, "severity", "", "Severity level used to filter results. Behaves like log levels. 'danger' is the least verbose (warning, danger)")
|
||||
auditCmd.PersistentFlags().BoolVar(&skipSslValidation, "skip-ssl-validation", false, "Skip https certificate verification")
|
||||
auditCmd.PersistentFlags().BoolVar(&uploadInsights, "upload-insights", false, "Upload scan results to Fairwinds Insights")
|
||||
auditCmd.PersistentFlags().StringVar(&clusterName, "cluster-name", "", "Set --cluster-name to a descriptive name for the cluster you're auditing")
|
||||
auditCmd.PersistentFlags().BoolVar(&quiet, "quiet", false, "Suppress the 'upload to Insights' prompt.")
|
||||
auditCmd.PersistentFlags().StringVar(&helmValues, "helm-values", "", "Optional flag to add helm values")
|
||||
}
|
||||
|
||||
var auditCmd = &cobra.Command{
|
||||
@@ -92,54 +66,16 @@ var auditCmd = &cobra.Command{
|
||||
if displayName != "" {
|
||||
config.DisplayName = displayName
|
||||
}
|
||||
if len(checks) > 0 {
|
||||
targetChecks := make(map[string]bool)
|
||||
for _, check := range checks {
|
||||
targetChecks[check] = true
|
||||
}
|
||||
for key := range config.Checks {
|
||||
if isTarget := targetChecks[key]; !isTarget {
|
||||
config.Checks[key] = cfg.SeverityIgnore
|
||||
}
|
||||
}
|
||||
}
|
||||
if auditNamespace != "" {
|
||||
if helmChart != "" {
|
||||
logrus.Warn("--namespace and --helm-chart are mutually exclusive. --namespace will be ignored.")
|
||||
}
|
||||
if auditPath != "" {
|
||||
logrus.Warn("--namespace and --audit-path are mutually exclusive. --namespace will be ignored.")
|
||||
}
|
||||
config.Namespace = auditNamespace
|
||||
}
|
||||
if helmChart != "" {
|
||||
var err error
|
||||
auditPath, err = ProcessHelmTemplates(helmChart, helmValues, helmSkipTests)
|
||||
auditPath, err = ProcessHelmTemplates(helmChart, helmValues)
|
||||
if err != nil {
|
||||
logrus.Errorf("Couldn't process helm chart: %v", err)
|
||||
logrus.Infof("Couldn't process helm chart: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if uploadInsights && len(clusterName) == 0 {
|
||||
logrus.Error("cluster-name is required when using --upload-insights")
|
||||
os.Exit(1)
|
||||
}
|
||||
if uploadInsights {
|
||||
if auditPath != "" {
|
||||
logrus.Errorf("upload-insights and audit-path are not supported when used simultaneously")
|
||||
os.Exit(1)
|
||||
}
|
||||
if !auth.IsLoggedIn() {
|
||||
err := auth.HandleLogin(insightsHost)
|
||||
if err != nil {
|
||||
logrus.Errorf("error handling logging: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
k, err := kube.CreateResourceProvider(ctx, auditPath, resourceToAudit, config)
|
||||
k, err := kube.CreateResourceProvider(context.TODO(), auditPath, resourceToAudit, config)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error fetching Kubernetes resources %v", err)
|
||||
os.Exit(1)
|
||||
@@ -151,43 +87,7 @@ var auditCmd = &cobra.Command{
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if uploadInsights {
|
||||
auth, err := auth.GetAuth(insightsHost)
|
||||
if err != nil {
|
||||
logrus.Errorf("getting auth: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// fetch workloads using workload plugin... or should we adapt the workloads from above?
|
||||
dynamicClient, restMapper, clientSet, host, err := kube.GetKubeClient(ctx, "")
|
||||
if err != nil {
|
||||
logrus.Errorf("getting the kubernetes client: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
k8sResources, err := workloadsPkg.CreateResourceProviderFromAPI(ctx, dynamicClient, restMapper, clientSet, host)
|
||||
if err != nil {
|
||||
logrus.Errorf("creating resource provider: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
insightsClient := insights.NewHTTPClient(insightsHost, auth.Organization, auth.Token)
|
||||
insightsReporter := insights.NewInsightsReporter(insightsClient)
|
||||
wr := insights.WorkloadsReport{Version: workloads.Version, Payload: *k8sResources}
|
||||
pr := insights.PolarisReport{Version: version, Payload: auditData}
|
||||
logrus.Infof("Uploading to Fairwinds Insights organization '%s/%s'...", auth.Organization, clusterName)
|
||||
err = insightsReporter.ReportAuditToFairwindsInsights(clusterName, wr, pr)
|
||||
if err != nil {
|
||||
logrus.Errorf("reporting audit file to insights: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Stderr.WriteString("\n\nSuccess! You can see your results at:")
|
||||
os.Stderr.WriteString(fmt.Sprintf("\n\n%s/orgs/%s/clusters/%s/action-items\n\n", insightsHost, auth.Organization, clusterName))
|
||||
} else {
|
||||
outputAudit(auditData, auditOutputFile, auditOutputURL, auditOutputFormat, useColor, onlyShowFailedTests, severityLevel)
|
||||
if !quiet {
|
||||
os.Stderr.WriteString("\n\n🚀 Upload your Polaris findings to Fairwinds Insights to see remediation advice, add teammates, integrate with Slack or Jira, and more:")
|
||||
os.Stderr.WriteString("\n\n❯ polaris " + strings.Join(os.Args[1:], " ") + " --upload-insights --cluster-name=my-cluster\n\n")
|
||||
}
|
||||
}
|
||||
outputAudit(auditData, auditOutputFile, auditOutputURL, auditOutputFormat, useColor, onlyShowFailedTests)
|
||||
|
||||
summary := auditData.GetSummary()
|
||||
score := summary.GetScore()
|
||||
@@ -202,7 +102,7 @@ var auditCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
// ProcessHelmTemplates turns helm into yaml to be processed by Polaris or the other tools.
|
||||
func ProcessHelmTemplates(helmChart string, helmValues []string, helmSkipTests bool) (string, error) {
|
||||
func ProcessHelmTemplates(helmChart, helmValues string) (string, error) {
|
||||
cmd := exec.Command("helm", "dependency", "update", helmChart)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
@@ -210,22 +110,18 @@ func ProcessHelmTemplates(helmChart string, helmValues []string, helmSkipTests b
|
||||
return "", err
|
||||
}
|
||||
|
||||
dir, err := os.MkdirTemp("", "*")
|
||||
dir, err := ioutil.TempDir("", "*")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
params := []string{
|
||||
"template", helmChart,
|
||||
"--generate-name",
|
||||
helmChart,
|
||||
"--output-dir",
|
||||
dir,
|
||||
}
|
||||
for _, v := range helmValues {
|
||||
params = append(params, "--values", v)
|
||||
}
|
||||
|
||||
if helmSkipTests {
|
||||
params = append(params, "--skip-tests")
|
||||
if helmValues != "" {
|
||||
params = append(params, "--values", helmValues)
|
||||
}
|
||||
|
||||
cmd = exec.Command("helm", params...)
|
||||
@@ -238,20 +134,10 @@ func ProcessHelmTemplates(helmChart string, helmValues []string, helmSkipTests b
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
func outputAudit(auditData validator.AuditData, outputFile, outputURL, outputFormat string, useColor bool, onlyShowFailedTests bool, severityLevel string) {
|
||||
func outputAudit(auditData validator.AuditData, outputFile, outputURL, outputFormat string, useColor bool, onlyShowFailedTests bool) {
|
||||
if onlyShowFailedTests {
|
||||
auditData = auditData.RemoveSuccessfulResults()
|
||||
}
|
||||
|
||||
if severityLevel != "" {
|
||||
switch severityLevel {
|
||||
case "danger":
|
||||
auditData = auditData.FilterResultsBySeverityLevel(cfg.SeverityDanger)
|
||||
case "warning":
|
||||
auditData = auditData.FilterResultsBySeverityLevel(cfg.SeverityWarning)
|
||||
}
|
||||
}
|
||||
|
||||
var outputBytes []byte
|
||||
var err error
|
||||
if outputFormat == "score" {
|
||||
@@ -289,13 +175,9 @@ func outputAudit(auditData validator.AuditData, outputFile, outputURL, outputFor
|
||||
} else {
|
||||
req.Header.Set("Content-Type", "text/plain")
|
||||
}
|
||||
|
||||
client := &http.Client{}
|
||||
if skipSslValidation {
|
||||
transport := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
|
||||
client = &http.Client{Transport: transport}
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
|
||||
if err != nil {
|
||||
logrus.Errorf("Error making request for output: %v", err)
|
||||
os.Exit(1)
|
||||
@@ -303,7 +185,7 @@ func outputAudit(auditData validator.AuditData, outputFile, outputURL, outputFor
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
logrus.Errorf("Error reading response: %v", err)
|
||||
@@ -314,7 +196,7 @@ func outputAudit(auditData validator.AuditData, outputFile, outputURL, outputFor
|
||||
}
|
||||
|
||||
if outputFile != "" {
|
||||
err := os.WriteFile(outputFile, outputBytes, 0644)
|
||||
err := ioutil.WriteFile(outputFile, []byte(outputBytes), 0644)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error writing output to file: %v", err)
|
||||
os.Exit(1)
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/fairwindsops/polaris/pkg/auth"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(authCmd)
|
||||
authCmd.AddCommand(loginCmd)
|
||||
authCmd.AddCommand(logoutCmd)
|
||||
authCmd.AddCommand(statusCmd)
|
||||
authCmd.AddCommand(tokenCmd)
|
||||
}
|
||||
|
||||
var authCmd = &cobra.Command{
|
||||
Use: "auth",
|
||||
Short: "Authenticate polaris with Fairwinds Insights",
|
||||
Long: `Authenticate polaris with Fairwinds Insights so better experience`,
|
||||
}
|
||||
|
||||
var loginCmd = &cobra.Command{
|
||||
Use: "login",
|
||||
Short: "Authenticate polaris with Fairwinds Insights.",
|
||||
Long: `Authenticate polaris with Fairwinds Insights.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := auth.HandleLogin(insightsHost)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
},
|
||||
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var logoutCmd = &cobra.Command{
|
||||
Use: "logout",
|
||||
Short: "Log out of a Fairwinds Insights.",
|
||||
Long: `Log out of a Fairwinds Insights.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := auth.HandleLogout()
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
},
|
||||
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var statusCmd = &cobra.Command{
|
||||
Use: "status",
|
||||
Short: "View authentication status.",
|
||||
Long: `View authentication status.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := auth.PrintStatus(insightsHost)
|
||||
if err != nil {
|
||||
logrus.Fatalf("printing status: %v", err)
|
||||
}
|
||||
},
|
||||
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var tokenCmd = &cobra.Command{
|
||||
Use: "token",
|
||||
Short: "Print the auth token gh is configured to use.",
|
||||
Long: `Print the auth token gh is configured to use.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := auth.PrintToken()
|
||||
if err != nil {
|
||||
logrus.Fatalf("printing token: %v", err)
|
||||
}
|
||||
},
|
||||
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -54,11 +54,7 @@ var dashboardCmd = &cobra.Command{
|
||||
auditData := validator.ReadAuditFromFile(loadAuditFile)
|
||||
auditDataPtr = &auditData
|
||||
}
|
||||
router, err := dashboard.GetRouter(config, auditPath, serverPort, basePath, auditDataPtr)
|
||||
if err != nil {
|
||||
logrus.Fatalf("error creating router: %v", err)
|
||||
}
|
||||
|
||||
router := dashboard.GetRouter(config, auditPath, serverPort, basePath, auditDataPtr)
|
||||
router.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("OK"))
|
||||
})
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright 2020 FairwindsOps Inc
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"github.com/fairwindsops/polaris/pkg/fix"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
filesPath string
|
||||
checksToFix []string
|
||||
isTemplate bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(fixCommand)
|
||||
fixCommand.PersistentFlags().StringVar(&filesPath, "files-path", "", "mutate and fix one or more YAML files in a specified folder")
|
||||
fixCommand.PersistentFlags().BoolVar(&isTemplate, "template", false, "set to true when modifyng a YAML template, like a Helm chart (experimental)")
|
||||
fixCommand.PersistentFlags().StringSliceVar(&checksToFix, "checks", []string{}, "Optional flag to specify specific checks to fix eg. checks=hostIPCSet,hostPIDSet and checks=all applies fix to all defined checks mutations")
|
||||
}
|
||||
|
||||
var fixCommand = &cobra.Command{
|
||||
Use: "fix",
|
||||
Short: "Fix Infrastructure as code files.",
|
||||
Long: `Fix Infrastructure as code files.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
logrus.Debug("Setting up controller manager")
|
||||
|
||||
err := fix.Execute(config, filesPath, isTemplate, checksToFix...)
|
||||
if err != nil {
|
||||
if errors.Is(err, fix.ErrFilesPathRequired) {
|
||||
logrus.Error("Please specify a files-path flag")
|
||||
cmd.Help()
|
||||
os.Exit(1)
|
||||
}
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -15,27 +15,20 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
conf "github.com/fairwindsops/polaris/pkg/config"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var (
|
||||
mergeConfig bool
|
||||
configPath string
|
||||
disallowExemptions bool
|
||||
disallowConfigExemptions bool
|
||||
disallowAnnotationExemptions bool
|
||||
fixChecks bool
|
||||
logLevel string
|
||||
auditPath string
|
||||
displayName string
|
||||
kubeContext string
|
||||
insightsHost string
|
||||
)
|
||||
var configPath string
|
||||
var disallowExemptions, disallowConfigExemptions, disallowAnnotationExemptions bool
|
||||
var logLevel string
|
||||
var auditPath string
|
||||
var displayName string
|
||||
|
||||
var (
|
||||
version string
|
||||
@@ -43,14 +36,13 @@ var (
|
||||
|
||||
func init() {
|
||||
// Flags
|
||||
rootCmd.PersistentFlags().BoolVarP(&mergeConfig, "merge-config", "m", false, "If true, custom configuration will be merged with default configuration instead of replacing it.")
|
||||
rootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "Location of Polaris configuration file.")
|
||||
rootCmd.PersistentFlags().StringVarP(&kubeContext, "context", "x", "", "Set the kube context.")
|
||||
rootCmd.PersistentFlags().BoolVarP(&disallowExemptions, "disallow-exemptions", "", false, "Disallow any configured exemption.")
|
||||
rootCmd.PersistentFlags().BoolVarP(&disallowConfigExemptions, "disallow-config-exemptions", "", false, "Disallow exemptions set within the configuration file.")
|
||||
rootCmd.PersistentFlags().BoolVarP(&disallowAnnotationExemptions, "disallow-annotation-exemptions", "", false, "Disallow any exemption defined as a controller annotation.")
|
||||
rootCmd.PersistentFlags().StringVarP(&logLevel, "log-level", "", logrus.InfoLevel.String(), "Logrus log level to be output (trace, debug, info, warning, error, fatal, panic).")
|
||||
rootCmd.PersistentFlags().StringVar(&insightsHost, "insights-host", "https://insights.fairwinds.com", "Fairwinds Insights host URL")
|
||||
rootCmd.PersistentFlags().StringVarP(&logLevel, "log-level", "", logrus.InfoLevel.String(), "Logrus log level.")
|
||||
flag.Parse()
|
||||
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
|
||||
}
|
||||
|
||||
var config conf.Configuration
|
||||
@@ -67,7 +59,7 @@ var rootCmd = &cobra.Command{
|
||||
logrus.SetLevel(parsedLevel)
|
||||
}
|
||||
|
||||
config, err = conf.MergeConfigAndParseFile(configPath, mergeConfig)
|
||||
config, err = conf.ParseFile(configPath)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error parsing config at %s: %v", configPath, err)
|
||||
os.Exit(1)
|
||||
@@ -76,7 +68,6 @@ var rootCmd = &cobra.Command{
|
||||
config.DisallowExemptions = disallowExemptions
|
||||
config.DisallowConfigExemptions = disallowConfigExemptions
|
||||
config.DisallowAnnotationExemptions = disallowAnnotationExemptions
|
||||
config.KubeContext = kubeContext
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
logrus.Error("You must specify a sub-command.")
|
||||
@@ -86,11 +77,6 @@ var rootCmd = &cobra.Command{
|
||||
}
|
||||
os.Exit(1)
|
||||
},
|
||||
PersistentPostRun: func(cmd *cobra.Command, args []string) {
|
||||
if !strings.HasPrefix(cmd.Use, "audit") {
|
||||
os.Stderr.WriteString("\n\nWant more? Automate Polaris for free with Fairwinds Insights!\n🚀 https://fairwinds.com/insights-signup/polaris 🚀 \n")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Execute the stuff
|
||||
|
||||
@@ -31,7 +31,4 @@ var versionCmd = &cobra.Command{
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("Polaris version:" + version)
|
||||
},
|
||||
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -24,22 +25,15 @@ import (
|
||||
k8sConfig "sigs.k8s.io/controller-runtime/pkg/client/config"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
var webhookPort int
|
||||
var disableWebhookConfigInstaller bool
|
||||
var enableMutations bool
|
||||
var enableValidations bool
|
||||
var certDir string
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(webhookCmd)
|
||||
webhookCmd.PersistentFlags().IntVarP(&webhookPort, "port", "p", 9876, "Port for the dashboard webserver.")
|
||||
webhookCmd.PersistentFlags().BoolVar(&disableWebhookConfigInstaller, "disable-webhook-config-installer", false, "Disable the installer in the webhook server, so it won't install webhook configuration resources during bootstrapping.")
|
||||
webhookCmd.PersistentFlags().BoolVar(&enableValidations, "validate", true, "Enable the validating webhook to reject workloads with issues")
|
||||
webhookCmd.PersistentFlags().BoolVar(&enableMutations, "mutate", false, "Enable the mutating webhook to modify workloads with issues")
|
||||
webhookCmd.PersistentFlags().StringVar(&certDir, "cert-dir", "/opt/cert", "Directory in which tls certificate is located")
|
||||
webhookCmd.PersistentFlags().BoolVar(&disableWebhookConfigInstaller, "disable-webhook-config-installer", false, "disable the installer in the webhook server, so it won't install webhook configuration resources during bootstrapping.")
|
||||
}
|
||||
|
||||
var webhookCmd = &cobra.Command{
|
||||
@@ -50,34 +44,27 @@ var webhookCmd = &cobra.Command{
|
||||
logrus.Debug("Setting up controller manager")
|
||||
|
||||
mgr, err := manager.New(k8sConfig.GetConfigOrDie(), manager.Options{
|
||||
WebhookServer: webhook.NewServer(webhook.Options{
|
||||
CertDir: certDir,
|
||||
Port: webhookPort,
|
||||
CertName: "tls.crt",
|
||||
KeyName: "tls.key",
|
||||
}),
|
||||
CertDir: "/opt/cert",
|
||||
Port: webhookPort,
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Errorf("Unable to set up overall controller manager: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
_, err = os.Stat(certDir + "/tls.crt")
|
||||
_, err = os.Stat("/opt/cert/tls.crt")
|
||||
if os.IsNotExist(err) {
|
||||
time.Sleep(time.Second * 10)
|
||||
panic("Cert does not exist")
|
||||
}
|
||||
server := mgr.GetWebhookServer()
|
||||
server.CertName = "tls.crt"
|
||||
server.KeyName = "tls.key"
|
||||
|
||||
if !enableMutations && !enableValidations {
|
||||
logrus.Errorf("One of --mutate or --validate must be set to true")
|
||||
os.Exit(1)
|
||||
}
|
||||
// Iterate all the configurations supported controllers to scan and register them for webhooks
|
||||
// Should only register controllers that are configured to be scanned
|
||||
fwebhook.NewWebhook(mgr, fwebhook.Validator{Config: config, Client: mgr.GetClient()})
|
||||
|
||||
if enableValidations {
|
||||
fwebhook.NewValidateWebhook(mgr, config)
|
||||
}
|
||||
if enableMutations {
|
||||
fwebhook.NewMutateWebhook(mgr, config)
|
||||
}
|
||||
logrus.Infof("Polaris webhook server listening on port %d", webhookPort)
|
||||
if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
|
||||
logrus.Errorf("Error starting manager: %v", err)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -0,0 +1,6 @@
|
||||
trailingComma: "es5"
|
||||
tabWidth: 2
|
||||
semi: true
|
||||
singleQuote: true
|
||||
jsxSingleQuote: false
|
||||
parser: typescript
|
||||
@@ -0,0 +1,46 @@
|
||||
# Getting Started with Create React App
|
||||
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.\
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
|
||||
The page will reload if you make edits.\
|
||||
You will also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.\
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.\
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.\
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
|
||||
|
||||
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
|
||||
|
||||
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "dashboard",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^5.15.0",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/node": "^12.20.36",
|
||||
"@types/react": "^17.0.34",
|
||||
"@types/react-bootstrap": "^0.32.28",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"bootstrap": "^5.1.3",
|
||||
"node-sass": "^6.0.1",
|
||||
"react": "^17.0.2",
|
||||
"react-bootstrap": "^2.0.1",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "4.0.3",
|
||||
"typescript": "^4.4.4",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@axe-core/react": "^4.3.1",
|
||||
"prettier": "^2.4.1"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 342 B |
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Validation of best practices in your Kubernetes clusters"
|
||||
/>
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>Fairwinds Polaris</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
@@ -0,0 +1,18 @@
|
||||
@import "~bootstrap/scss/bootstrap.scss";
|
||||
|
||||
.App {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
.app-content {
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#mainContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import LeftNavBar from './components/Navigation/LeftBar/LeftNavBar';
|
||||
import TopNavBar from './components/Navigation/TopBar/TopNavBar';
|
||||
|
||||
import './App.scss';
|
||||
import data from './data.json';
|
||||
|
||||
function App() {
|
||||
const [pageDisplay, setPageDisplay] = useState<string>('dashboard');
|
||||
const [namespaces, setNamespaces] = useState<string[]>([]);
|
||||
const [selectedNamespace, setSelectedNamespace] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
const allNamespaces: Set<string> = new Set();
|
||||
data.Results.forEach((result) => {
|
||||
allNamespaces.add(result.Namespace);
|
||||
});
|
||||
setNamespaces(Array.from(allNamespaces));
|
||||
setSelectedNamespace('');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<LeftNavBar />
|
||||
<div id="mainContainer">
|
||||
<TopNavBar
|
||||
pageDisplay={pageDisplay}
|
||||
setPageDisplay={setPageDisplay}
|
||||
namespaces={namespaces}
|
||||
setSelected={setSelectedNamespace}
|
||||
/>
|
||||
<main className="app-content">
|
||||
{pageDisplay === 'dashboard' && <h1>Polaris Dashboard</h1>}
|
||||
{pageDisplay === 'namespaces' && (
|
||||
<h1>{selectedNamespace} Namespace</h1>
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.83333 4C4.61232 4 4.40036 4.08231 4.24408 4.22882C4.0878 4.37534 4 4.57405 4 4.78125C4 4.98845 4.0878 5.18716 4.24408 5.33368C4.40036 5.48019 4.61232 5.5625 4.83333 5.5625H14.8333C15.0543 5.5625 15.2663 5.48019 15.4226 5.33368C15.5789 5.18716 15.6667 4.98845 15.6667 4.78125C15.6667 4.57405 15.5789 4.37534 15.4226 4.22882C15.2663 4.08231 15.0543 4 14.8333 4H4.83333ZM4 7.90625C4 7.69905 4.0878 7.50034 4.24408 7.35382C4.40036 7.20731 4.61232 7.125 4.83333 7.125H14.8333C15.0543 7.125 15.2663 7.20731 15.4226 7.35382C15.5789 7.50034 15.6667 7.69905 15.6667 7.90625C15.6667 8.11345 15.5789 8.31216 15.4226 8.45868C15.2663 8.60519 15.0543 8.6875 14.8333 8.6875H4.83333C4.61232 8.6875 4.40036 8.60519 4.24408 8.45868C4.0878 8.31216 4 8.11345 4 7.90625ZM4.83333 10.25C4.61232 10.25 4.40036 10.3323 4.24408 10.4788C4.0878 10.6253 4 10.824 4 11.0312C4 11.2385 4.0878 11.4372 4.24408 11.5837C4.40036 11.7302 4.61232 11.8125 4.83333 11.8125H14.8333C15.0543 11.8125 15.2663 11.7302 15.4226 11.5837C15.5789 11.4372 15.6667 11.2385 15.6667 11.0312C15.6667 10.824 15.5789 10.6253 15.4226 10.4788C15.2663 10.3323 15.0543 10.25 14.8333 10.25H4.83333ZM4.83333 13.375C4.61232 13.375 4.40036 13.4573 4.24408 13.6038C4.0878 13.7503 4 13.949 4 14.1562C4 14.3635 4.0878 14.5622 4.24408 14.7087C4.40036 14.8552 4.61232 14.9375 4.83333 14.9375H9.83333C10.0543 14.9375 10.2663 14.8552 10.4226 14.7087C10.5789 14.5622 10.6667 14.3635 10.6667 14.1562C10.6667 13.949 10.5789 13.7503 10.4226 13.6038C10.2663 13.4573 10.0543 13.375 9.83333 13.375H4.83333Z" fill="white"/>
|
||||
<path d="M0 2.5C0 1.83696 0.351189 1.20107 0.976311 0.732233C1.60143 0.263392 2.44928 0 3.33333 0L16.6667 0C17.5507 0 18.3986 0.263392 19.0237 0.732233C19.6488 1.20107 20 1.83696 20 2.5V17.5C20 18.163 19.6488 18.7989 19.0237 19.2678C18.3986 19.7366 17.5507 20 16.6667 20H3.33333C2.44928 20 1.60143 19.7366 0.976311 19.2678C0.351189 18.7989 0 18.163 0 17.5V2.5ZM16.6667 1.25H3.33333C2.89131 1.25 2.46738 1.3817 2.15482 1.61612C1.84226 1.85054 1.66667 2.16848 1.66667 2.5V17.5C1.66667 17.8315 1.84226 18.1495 2.15482 18.3839C2.46738 18.6183 2.89131 18.75 3.33333 18.75H16.6667C17.1087 18.75 17.5326 18.6183 17.8452 18.3839C18.1577 18.1495 18.3333 17.8315 18.3333 17.5V2.5C18.3333 2.16848 18.1577 1.85054 17.8452 1.61612C17.5326 1.3817 17.1087 1.25 16.6667 1.25Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="25" height="19" viewBox="0 0 25 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M25 3.125C25 2.2962 24.6708 1.50134 24.0847 0.915291C23.4987 0.32924 22.7038 0 21.875 0H3.125C2.2962 0 1.50134 0.32924 0.915293 0.915291C0.329241 1.50134 0 2.2962 0 3.125V15.625C0 16.4538 0.329241 17.2487 0.915293 17.8347C1.50134 18.4208 2.2962 18.75 3.125 18.75H21.875C22.7038 18.75 23.4987 18.4208 24.0847 17.8347C24.6708 17.2487 25 16.4538 25 15.625V3.125ZM21.875 1.5625C22.2894 1.5625 22.6868 1.72712 22.9799 2.02015C23.2729 2.31317 23.4375 2.7106 23.4375 3.125V3.46406L12.5 10.0266L1.5625 3.46406V3.125C1.5625 2.7106 1.72712 2.31317 2.02015 2.02015C2.31317 1.72712 2.7106 1.5625 3.125 1.5625H21.875ZM1.5625 5.28594L8.99688 9.74687L1.5625 14.2406V5.2875V5.28594ZM1.61563 16.0328L10.5141 10.6562L12.5 11.8484L14.4875 10.6562L23.3844 16.0312C23.295 16.3632 23.0987 16.6563 22.8258 16.8654C22.5529 17.0744 22.2187 17.1876 21.875 17.1875H3.125C2.78147 17.1877 2.44744 17.0747 2.17459 16.866C1.90174 16.6573 1.70529 16.3644 1.61563 16.0328ZM23.4375 14.2406L16.0031 9.74687L23.4375 5.28594V14.2391V14.2406Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.5 0C5.59375 0 0 5.50583 0 12.3035C0 17.7478 3.57812 22.3463 8.54688 23.9765C9.17188 24.0842 9.40625 23.715 9.40625 23.3921C9.40625 23.0999 9.39062 22.131 9.39062 21.1005C6.25 21.6696 5.4375 20.347 5.1875 19.6549C5.04688 19.3012 4.4375 18.2092 3.90625 17.917C3.46875 17.6863 2.84375 17.1173 3.89062 17.1019C4.875 17.0865 5.57812 17.9939 5.8125 18.363C6.9375 20.2239 8.73438 19.701 9.45312 19.3781C9.5625 18.5783 9.89062 18.04 10.25 17.7325C7.46875 17.4249 4.5625 16.3637 4.5625 11.6576C4.5625 10.3196 5.04688 9.21227 5.84375 8.35102C5.71875 8.04343 5.28125 6.78232 5.96875 5.09058C5.96875 5.09058 7.01562 4.76762 9.40625 6.3517C10.4062 6.07487 11.4688 5.93645 12.5313 5.93645C13.5938 5.93645 14.6563 6.07487 15.6563 6.3517C18.0469 4.75224 19.0938 5.09058 19.0938 5.09058C19.7812 6.78232 19.3438 8.04343 19.2188 8.35102C20.0156 9.21227 20.5 10.3042 20.5 11.6576C20.5 16.3791 17.5781 17.4249 14.7969 17.7325C15.25 18.1169 15.6406 18.8552 15.6406 20.0086C15.6406 21.6542 15.625 22.9768 15.625 23.3921C15.625 23.715 15.8594 24.0995 16.4844 23.9765C18.966 23.1521 21.1224 21.5824 22.65 19.4884C24.1777 17.3944 24.9996 14.8815 25 12.3035C25 5.50583 19.4062 0 12.5 0Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="9" height="14" viewBox="0 0 9 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.755859 1.59702L7.77688 7.00555L0.755859 12.4141V1.59702ZM0.353294 12.7242C0.353419 12.7241 0.353541 12.724 0.353666 12.7239L0.353294 12.7242ZM8.03353 7.20326L8.03397 7.2036L8.18654 7.00555L8.03397 7.2036C8.03382 7.20349 8.03367 7.20337 8.03353 7.20326Z" stroke="white" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 403 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.66849 0L7.39526 2.46812C6.35771 2.81801 5.41199 3.37161 4.60838 4.08015L2.33151 3.07832L0 7.12204L1.99452 8.58833C1.89056 9.10843 1.83971 9.64966 1.83971 10.2004C1.83971 10.751 1.89059 11.2923 1.99452 11.8124L0 13.2787L2.33151 17.3224L4.60838 16.3206C5.41199 17.0291 6.35771 17.5827 7.39526 17.9326L7.66849 20.4007H12.3315L12.6047 17.9326C13.6423 17.5827 14.588 17.0291 15.3916 16.3206L17.6685 17.3224L20 13.2787L18.0055 11.8124C18.1094 11.2923 18.1603 10.751 18.1603 10.2004C18.1603 9.64966 18.1094 9.10843 18.0055 8.58833L20 7.12204L17.6685 3.07832L15.3916 4.08015C14.588 3.37161 13.6423 2.81801 12.6047 2.46812L12.3315 0H7.66849ZM10 5.2459C12.7363 5.2459 14.9545 7.46404 14.9545 10.2004C14.9545 12.9366 12.7363 15.1548 10 15.1548C7.26374 15.1548 5.04554 12.9366 5.04554 10.2004C5.04554 7.46404 7.26374 5.2459 10 5.2459Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 954 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.25313 15.7969C5.25313 17.2437 4.07188 18.4234 2.62656 18.4234C1.18125 18.4234 0 17.2437 0 15.7984C0 14.3531 1.18125 13.1719 2.625 13.1719H5.25313V15.7969ZM6.575 15.7969C6.575 14.3531 7.75625 13.1719 9.20156 13.1719C10.6469 13.1719 11.8281 14.3531 11.8281 15.7969V22.375C11.8281 23.8188 10.6469 25 9.20312 25C8.50702 24.9988 7.83974 24.7219 7.34723 24.23C6.85472 23.7381 6.57706 23.0711 6.575 22.375V15.7969ZM9.20312 5.25313C7.75625 5.25313 6.575 4.07188 6.575 2.62656C6.575 1.18125 7.75625 0 9.20312 0C10.65 0 11.8281 1.18125 11.8281 2.625V5.25313H9.20312ZM9.20312 6.575C10.6469 6.575 11.8281 7.75625 11.8281 9.20156C11.8281 10.6469 10.6469 11.8281 9.20312 11.8281H2.625C1.18281 11.8281 0 10.6469 0 9.20312C0 7.75625 1.18125 6.575 2.625 6.575H9.20312ZM19.7484 9.20312C19.7484 7.75625 20.9281 6.575 22.3734 6.575C23.8188 6.575 25 7.75625 25 9.20156C25 10.6469 23.8188 11.8281 22.375 11.8281H19.7484V9.20312ZM18.4234 9.20312C18.4234 10.6469 17.2437 11.8281 15.7984 11.8281C15.1026 11.8265 14.4357 11.5494 13.9436 11.0576C13.4514 10.5657 13.1739 9.89895 13.1719 9.20312V2.625C13.1719 1.18281 14.3531 0 15.7969 0C17.2437 0 18.4234 1.18125 18.4234 2.625V9.20312ZM15.7969 19.7469C17.2437 19.7469 18.425 20.9281 18.425 22.3734C18.425 23.8188 17.2437 25 15.7969 25C14.35 25 13.1703 23.8188 13.1703 22.375V19.7469H15.7953H15.7969ZM15.7969 18.4234C14.3531 18.4234 13.1719 17.2437 13.1719 15.7984C13.1719 14.3531 14.3531 13.1719 15.7969 13.1719H22.375C23.8188 13.1719 25 14.3531 25 15.7969C25 17.2437 23.8188 18.4234 22.375 18.4234H15.7969Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="25" height="21" viewBox="0 0 25 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.85313 21C17.2875 21 22.4484 12.9187 22.4484 5.9228C22.4484 5.69666 22.4484 5.46729 22.4391 5.24115C23.4438 4.4892 24.311 3.55825 25 2.49191C24.0614 2.91972 23.0668 3.20168 22.0484 3.32863C23.1211 2.66578 23.9246 1.62283 24.3094 0.393637C23.3015 1.01088 22.1985 1.44418 21.0484 1.67457C20.2753 0.823345 19.2522 0.259434 18.1376 0.0701857C17.0231 -0.119063 15.8793 0.0769118 14.8833 0.627754C13.8874 1.1786 13.095 2.05356 12.6288 3.11713C12.1626 4.18069 12.0487 5.37349 12.3047 6.51077C10.2652 6.40505 8.27003 5.85733 6.4485 4.90314C4.62698 3.94894 3.01982 2.60957 1.73125 0.971914C1.07709 2.13991 0.877459 3.5215 1.17288 4.83614C1.46831 6.15077 2.23665 7.29989 3.32187 8.05015C2.50866 8.02159 1.71331 7.79584 1 7.39111V7.4638C1.0014 8.68736 1.41142 9.87289 2.16074 10.82C2.91006 11.7671 3.95273 12.4177 5.1125 12.6618C4.67229 12.7872 4.21755 12.8497 3.76094 12.8476C3.43904 12.8486 3.11778 12.8178 2.80156 12.7555C3.12935 13.8088 3.76761 14.7297 4.62695 15.3892C5.48628 16.0488 6.52365 16.4139 7.59375 16.4336C5.77587 17.9096 3.53031 18.7102 1.21875 18.7063C0.811439 18.7081 0.404411 18.6838 0 18.6336C2.34612 20.1799 5.07078 21.0009 7.85313 21Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,63 @@
|
||||
.left-nav-bar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
background-color: #23103a;
|
||||
color: white;
|
||||
height: 100vh;
|
||||
padding: 1rem;
|
||||
width: 250px;
|
||||
min-width: 250px;
|
||||
|
||||
.top-div {
|
||||
img {
|
||||
width: 220px;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
|
||||
.links-title {
|
||||
color: #eceeef;
|
||||
font-size: 1rem;
|
||||
font-weight: 300;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.nav-link-section {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
text-decoration: none;
|
||||
|
||||
.link-name {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 300;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.docs {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.external-links {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.feedback {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
font-size: 1rem;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import React from 'react';
|
||||
// import Settings from '../../assets/icons/settings.svg';
|
||||
import Docs from '../../../assets/icons/docs.svg';
|
||||
import RightArrow from '../../../assets/icons/rightArrow.svg';
|
||||
import Github from '../../../assets/icons/github.svg';
|
||||
import Twitter from '../../../assets/icons/twitter.svg';
|
||||
import Slack from '../../../assets/icons/slack.svg';
|
||||
import Email from '../../../assets/icons/email.svg';
|
||||
import PolarisLogo from '../../../assets/images/polaris-logo.png';
|
||||
|
||||
import './LeftNavBar.scss';
|
||||
|
||||
const LeftNavBar = (): JSX.Element => {
|
||||
return (
|
||||
<section className="left-nav-bar">
|
||||
<div className="top-div">
|
||||
<img src={PolarisLogo} alt="Polaris icon" />
|
||||
</div>
|
||||
<div className="bottom-div">
|
||||
<h2 className="links-title">Application</h2>
|
||||
{/* TODO: no settings in Polaris? */}
|
||||
{/* <div className="nav-link-section">
|
||||
<img src={Settings} alt='gear icon' />
|
||||
<h3 className="link-name">Settings</h3>
|
||||
</div> */}
|
||||
<a
|
||||
className="nav-link-section"
|
||||
href="https://polaris.docs.fairwinds.com/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={Docs} alt="doc icon" />
|
||||
<h3 className="link-name docs">Docs</h3>
|
||||
<img src={RightArrow} alt="arrow pointing right" />
|
||||
</a>
|
||||
<div className="external-links">
|
||||
<a
|
||||
href="https://github.com/FairwindsOps/polaris"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={Github} alt="github logo" />
|
||||
</a>
|
||||
<a
|
||||
href="https://twitter.com/fairwindsops"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={Twitter} alt="twitter logo" />
|
||||
</a>
|
||||
<a
|
||||
href="https://join.slack.com/t/fairwindscommunity/shared_invite/zt-e3c6vj4l-3lIH6dvKqzWII5fSSFDi1g"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={Slack} alt="slack logo" />
|
||||
</a>
|
||||
<a
|
||||
href="https://www.fairwinds.com/fairwinds-newsletter"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={Email} alt="envelope for newsletter" />
|
||||
</a>
|
||||
</div>
|
||||
<a
|
||||
href="https://github.com/fairwindsops/polaris/issues"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="feedback"
|
||||
>
|
||||
Feedback
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default LeftNavBar;
|
||||
@@ -0,0 +1,40 @@
|
||||
.top-nav-bar {
|
||||
z-index: 3;
|
||||
background-color: white;
|
||||
height: 3rem;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
padding-bottom: 0 !important;
|
||||
|
||||
.top-nav {
|
||||
padding: 0 24px;
|
||||
height: inherit;
|
||||
align-content: end;
|
||||
width: 100%;
|
||||
|
||||
.nav-item > .dropdown-menu {
|
||||
max-height: 15rem;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.nav-item > .nav-link {
|
||||
color: #495057;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
border-color: transparent;
|
||||
}
|
||||
&.active {
|
||||
border-color: #fff #fff;
|
||||
margin-bottom: -2px;
|
||||
border-bottom: 2px solid #445688;
|
||||
color: #445688;
|
||||
padding-bottom: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
#nav-dropdown {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import React, { SyntheticEvent, useState } from 'react';
|
||||
import { Nav, Navbar, NavDropdown } from 'react-bootstrap';
|
||||
import './TopNavBar.scss';
|
||||
|
||||
type NavProps = {
|
||||
pageDisplay: string;
|
||||
setPageDisplay: React.Dispatch<React.SetStateAction<string>>;
|
||||
namespaces: string[];
|
||||
setSelected: React.Dispatch<React.SetStateAction<string>>;
|
||||
};
|
||||
|
||||
const TopNavBar = ({
|
||||
pageDisplay,
|
||||
setPageDisplay,
|
||||
namespaces,
|
||||
setSelected,
|
||||
}: NavProps): JSX.Element => {
|
||||
const [selectedNamespace, setSelectedNamespace] =
|
||||
useState<string>('All Namespaces');
|
||||
|
||||
const handleNamespaceSelection = (
|
||||
namespace: SyntheticEvent<HTMLDivElement, Event>
|
||||
): void => {
|
||||
if (namespace.toString() === 'All Namespaces') {
|
||||
setSelectedNamespace('All Namespace');
|
||||
} else if (namespace) {
|
||||
setSelectedNamespace(namespace.toString());
|
||||
}
|
||||
setPageDisplay('namespaces');
|
||||
setSelected(namespace.toString());
|
||||
};
|
||||
|
||||
const NavItems = (): JSX.Element => (
|
||||
<>
|
||||
{namespaces.map((item) => {
|
||||
return (
|
||||
<NavDropdown.Item key={item} eventKey={item}>
|
||||
{item}
|
||||
</NavDropdown.Item>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<header>
|
||||
<Navbar className="top-nav-bar" expand={true}>
|
||||
<Nav variant="tabs" className="top-nav">
|
||||
<NavDropdown
|
||||
title={selectedNamespace}
|
||||
id="nav-dropdown"
|
||||
active={pageDisplay === 'namespaces'}
|
||||
onSelect={handleNamespaceSelection}
|
||||
>
|
||||
<NavDropdown.Item
|
||||
key={'all-namespaces'}
|
||||
eventKey={'all-namespaces'}
|
||||
>
|
||||
All Namespaces
|
||||
</NavDropdown.Item>
|
||||
<NavItems />
|
||||
</NavDropdown>
|
||||
<Nav.Item onClick={() => setPageDisplay('dashboard')}>
|
||||
<Nav.Link active={pageDisplay === 'dashboard'}>Dashboard</Nav.Link>
|
||||
</Nav.Item>
|
||||
</Nav>
|
||||
</Navbar>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
export default TopNavBar;
|
||||
@@ -0,0 +1,13 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './index.scss';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const axe = require('@axe-core/react');
|
||||
axe(React, ReactDOM, 1000);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
||||
@@ -0,0 +1 @@
|
||||
/// <reference types="react-scripts" />
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ReportHandler } from 'web-vitals';
|
||||
|
||||
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
||||
@@ -0,0 +1,5 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
---
|
||||
# Source: polaris/templates/0-namespace.yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: polaris
|
||||
---
|
||||
# Source: polaris/templates/serviceaccount.yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: polaris
|
||||
namespace: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
---
|
||||
# Source: polaris/templates/rbac.yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
rules:
|
||||
# required by controller-runtime code doing a cluster wide lookup
|
||||
# when it seems namespace would suffice
|
||||
- apiGroups:
|
||||
- ''
|
||||
resources:
|
||||
- 'nodes'
|
||||
verbs:
|
||||
- 'get'
|
||||
- 'list'
|
||||
- apiGroups:
|
||||
- 'monitoring.coreos.com'
|
||||
resources:
|
||||
- 'prometheuses'
|
||||
- 'alertmanagers'
|
||||
verbs:
|
||||
- 'get'
|
||||
- 'list'
|
||||
---
|
||||
# Source: polaris/templates/rbac.yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: polaris-view
|
||||
labels:
|
||||
app: polaris
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: view
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: polaris
|
||||
namespace: polaris
|
||||
---
|
||||
# Source: polaris/templates/rbac.yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: polaris
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: polaris
|
||||
namespace: polaris
|
||||
---
|
||||
# Source: polaris/templates/dashboard.service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: polaris-dashboard
|
||||
namespace: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
annotations:
|
||||
spec:
|
||||
ports:
|
||||
- name: http-dashboard
|
||||
port: 80
|
||||
protocol: TCP
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: polaris
|
||||
component: dashboard
|
||||
type: ClusterIP
|
||||
---
|
||||
# Source: polaris/templates/dashboard.deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: polaris-dashboard
|
||||
namespace: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
component: dashboard
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: polaris
|
||||
component: dashboard
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: polaris
|
||||
component: dashboard
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- polaris
|
||||
- dashboard
|
||||
- --port
|
||||
- "8080"
|
||||
image: 'quay.io/fairwinds/polaris:4.2'
|
||||
imagePullPolicy: 'Always'
|
||||
name: dashboard
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 20
|
||||
resources:
|
||||
limits:
|
||||
cpu: 150m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
serviceAccountName: polaris
|
||||
nodeSelector:
|
||||
tolerations:
|
||||
@@ -0,0 +1,270 @@
|
||||
---
|
||||
# Source: polaris/templates/0-namespace.yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: polaris
|
||||
---
|
||||
# Source: polaris/templates/serviceaccount.yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: polaris
|
||||
namespace: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
---
|
||||
# Source: polaris/templates/rbac.yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
rules:
|
||||
# required by controller-runtime code doing a cluster wide lookup
|
||||
# when it seems namespace would suffice
|
||||
- apiGroups:
|
||||
- ''
|
||||
resources:
|
||||
- 'nodes'
|
||||
verbs:
|
||||
- 'get'
|
||||
- 'list'
|
||||
- apiGroups:
|
||||
- 'monitoring.coreos.com'
|
||||
resources:
|
||||
- 'prometheuses'
|
||||
- 'alertmanagers'
|
||||
verbs:
|
||||
- 'get'
|
||||
- 'list'
|
||||
---
|
||||
# Source: polaris/templates/rbac.yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: polaris-view
|
||||
labels:
|
||||
app: polaris
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: view
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: polaris
|
||||
namespace: polaris
|
||||
---
|
||||
# Source: polaris/templates/rbac.yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: polaris
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: polaris
|
||||
namespace: polaris
|
||||
---
|
||||
# Source: polaris/templates/webhook.service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: polaris-webhook
|
||||
namespace: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
spec:
|
||||
ports:
|
||||
- name: webhook
|
||||
port: 443
|
||||
protocol: TCP
|
||||
targetPort: 9876
|
||||
selector:
|
||||
app: polaris
|
||||
component: webhook
|
||||
type: ClusterIP
|
||||
---
|
||||
# Source: polaris/templates/webhook.deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: polaris-webhook
|
||||
namespace: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
component: webhook
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: polaris
|
||||
component: webhook
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: polaris
|
||||
component: webhook
|
||||
spec:
|
||||
containers:
|
||||
- name: webhook
|
||||
command:
|
||||
- polaris
|
||||
- webhook
|
||||
image: 'quay.io/fairwinds/polaris:4.2'
|
||||
imagePullPolicy: 'Always'
|
||||
ports:
|
||||
- containerPort: 9876
|
||||
# These are fairly useless readiness/liveness probes for now
|
||||
# Follow this issue for potential improvements:
|
||||
# https://github.com/kubernetes-sigs/controller-runtime/issues/356
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- ps -ef | grep polaris
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- ps -ef | grep polaris
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
volumeMounts:
|
||||
- name: secret
|
||||
mountPath: /opt/cert/
|
||||
readOnly: true
|
||||
- name: cr-logs
|
||||
mountPath: /tmp/
|
||||
readOnly: false
|
||||
serviceAccountName: polaris
|
||||
nodeSelector:
|
||||
tolerations:
|
||||
volumes:
|
||||
- name: secret
|
||||
secret:
|
||||
secretName: polaris
|
||||
- name: cr-logs
|
||||
emptyDir: {}
|
||||
---
|
||||
# Source: polaris/templates/webhook.cert.yaml
|
||||
apiVersion: cert-manager.io/v1alpha2
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: polaris-cert
|
||||
namespace: polaris
|
||||
labels:
|
||||
app: polaris
|
||||
spec:
|
||||
commonName: polaris-webhook.polaris.svc
|
||||
dnsNames:
|
||||
- polaris-webhook.polaris.svc
|
||||
- polaris-webhook.polaris
|
||||
- polaris-webhook
|
||||
- polaris-webhook.polaris.svc.
|
||||
issuerRef:
|
||||
kind: Issuer
|
||||
name: polaris-selfsigned
|
||||
secretName: polaris
|
||||
---
|
||||
# Source: polaris/templates/webhook.cert.yaml
|
||||
apiVersion: cert-manager.io/v1alpha2
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: polaris-selfsigned
|
||||
namespace: polaris
|
||||
spec:
|
||||
selfSigned: {}
|
||||
---
|
||||
# Source: polaris/templates/webhook.configuration.yaml
|
||||
apiVersion: admissionregistration.k8s.io/v1beta1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
name: polaris-webhook
|
||||
annotations:
|
||||
cert-manager.io/inject-ca-from: polaris/polaris-cert
|
||||
webhooks:
|
||||
- admissionReviewVersions:
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
service:
|
||||
name: polaris-webhook
|
||||
namespace: polaris
|
||||
path: /validate
|
||||
port: 443
|
||||
failurePolicy: Fail
|
||||
matchPolicy: Exact
|
||||
name: polaris.fairwinds.com
|
||||
namespaceSelector:
|
||||
|
||||
matchExpressions:
|
||||
- key: control-plane
|
||||
operator: DoesNotExist
|
||||
objectSelector:
|
||||
|
||||
{}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps
|
||||
apiVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
- v1beta2
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- daemonsets
|
||||
- deployments
|
||||
- statefulsets
|
||||
scope: Namespaced
|
||||
- apiGroups:
|
||||
- batch
|
||||
apiVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- jobs
|
||||
- cronjobs
|
||||
scope: Namespaced
|
||||
- apiGroups:
|
||||
- ""
|
||||
apiVersions:
|
||||
- v1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- pods
|
||||
- replicationcontrollers
|
||||
scope: Namespaced
|
||||
sideEffects: None
|
||||
timeoutSeconds: 10
|
||||
@@ -11,16 +11,6 @@ var sf14gv = 32793;
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(sf14g, s);
|
||||
})();
|
||||
|
||||
(function() {
|
||||
var gtag = document.createElement('script');
|
||||
gtag.src = "https://www.googletagmanager.com/gtag/js?id=G-ZR5M5SRYKY";
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gtag, s);
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'G-ZR5M5SRYKY');
|
||||
})();
|
||||
|
||||
!function(f,b,e,v,n,t,s)
|
||||
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
|
||||
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
|
||||
@@ -31,3 +21,9 @@ s.parentNode.insertBefore(t,s)}(window,document,'script',
|
||||
'https://connect.facebook.net/en_US/fbevents.js');
|
||||
fbq('init', '521127644762074');
|
||||
fbq('track', 'PageView');
|
||||
|
||||
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','GTM-TM95WXQ');
|
||||
|
||||
@@ -25,6 +25,11 @@ If you don't use cert-manager, you'll need to:
|
||||
* Create a TLS secret in your cluster with a valid certificate that uses that CA
|
||||
* Pass the name of that secret with the webhook.secretName parameter.
|
||||
|
||||
### kubectl
|
||||
```bash
|
||||
kubectl apply -f https://github.com/fairwindsops/polaris/releases/latest/download/webhook.yaml
|
||||
```
|
||||
|
||||
### Helm
|
||||
```bash
|
||||
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
|
||||
@@ -45,38 +50,3 @@ output unless we are rejecting a workload altogether.
|
||||
This 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. This will change in a future version of Kubernetes.
|
||||
|
||||
## Mutating Webhook
|
||||
By default, the Admission Controller is just pass/fail, but
|
||||
Polaris can also operate as a mutating webhook for many of the issues it checks for.
|
||||
This means Polaris will remediate the issue it finds, rather than rejecting
|
||||
the deployment.
|
||||
|
||||
To enable the mutating webhook, add `--set webhook.mutate=true` to your
|
||||
Helm installation command.
|
||||
|
||||
The following default checks currently have mutation support enabled:
|
||||
* `hostPIDSet`
|
||||
* `hostNetworkSet`
|
||||
* `hostIPCSet`
|
||||
* `priorityClassNotSet`
|
||||
* `hostPortSet`
|
||||
* `pullPolicyNotAlways`
|
||||
* `deploymentMissingReplicas`
|
||||
* `dangerousCapabilities`
|
||||
* `cpuLimitsMissing`
|
||||
* `memoryLimitsMissing`
|
||||
* `livenessProbeMissing`
|
||||
* `memoryRequestsMissing`
|
||||
* `cpuRequestsMissing`
|
||||
* `runAsPrivileged`
|
||||
* `readinessProbeMissing`
|
||||
* `privilegeEscalationAllowed`
|
||||
* `notReadOnlyRootFilesystem`
|
||||
* `insecureCapabilities`
|
||||
* `runAsRootAllowed`
|
||||
|
||||
If you'd like to
|
||||
enable other mutations, you can set the `webhook.mutations` flag.
|
||||
|
||||
|
||||
|
||||
@@ -6,125 +6,6 @@ meta:
|
||||
|
||||
---
|
||||
|
||||
## 9.1.1
|
||||
* Fix `hpaMinAvailability` failure message
|
||||
* Fix `missingPodDisruptionBudget` typo
|
||||
* Rewrite `hpaMaxAvailability` check to use go-template
|
||||
|
||||
## 9.1.0
|
||||
* Add HPA `minAvailable` and HPA `maxAvailable` checks
|
||||
* Fix typo for PDB `minAvailable`
|
||||
|
||||
## 9.0.1
|
||||
* Fix comments handling in `addOrReplaceValue` function
|
||||
|
||||
## 9.0.0
|
||||
* Expose issue fixer and mutations in the library
|
||||
* Remove `packr` in favor of `go:embed`
|
||||
|
||||
## 8.5.6
|
||||
* Fix trying to list cluster-level resources
|
||||
|
||||
## 8.5.5
|
||||
* Fix missing PDB check
|
||||
|
||||
## 8.5.4
|
||||
* Fix conditional expressions should be at very top of `additionalSchemaStrings`
|
||||
* Update alpine to 3.19
|
||||
|
||||
## 8.5.3
|
||||
* Add quiet flag to polaris audit CLI command to suppress 'upload to Insights' prompt
|
||||
|
||||
## 8.5.2
|
||||
* Switch to `controller-utils` package to get workloads
|
||||
|
||||
## 8.5.1
|
||||
* Update `topologySpreadConstraint` check
|
||||
|
||||
## 8.5.0
|
||||
* Add helm-skip-tests flag
|
||||
* Update CLI docs
|
||||
* Handle multiple helm-values files
|
||||
|
||||
## 8.4.0
|
||||
* Change kubernetes.io/ label from name to instance
|
||||
|
||||
## 8.3.0
|
||||
* Add option to filter audit results by severity level
|
||||
* Add insights prompt
|
||||
|
||||
## 8.2.4
|
||||
* Fix nil pointer issue with webhook
|
||||
|
||||
## 8.2.3
|
||||
* Add category for `metadataAndNameMismatched`.
|
||||
* Fix category for `priorityClassNotSet`.
|
||||
|
||||
## 8.2.2
|
||||
* Fix webhook server cert dir argument
|
||||
|
||||
## 8.2.1
|
||||
* Fix on Insights integration
|
||||
|
||||
## 8.2.0
|
||||
* Minor fixes for NSA checks
|
||||
|
||||
## 8.1.0
|
||||
* Add `insights-host` global flag to configure Fairwinds Insights host (defaults to `https://insights.fairwinds.com`).
|
||||
* Add new `auth` sub-commands be able to authenticate on Polaris using Fairwinds Insights credentials
|
||||
- `login` - login using Fairwinds Insights credentials via the web interface or provide a token
|
||||
- `logout` - logout from Fairwinds Insights
|
||||
- `status` - show relevant information regarding login state
|
||||
- `token` - prints the token from local storage
|
||||
* Add new `audit` flags to be able to upload Workloads and Polaris results to Fairwinds Insights
|
||||
- `upload-insights` - indicates that the results should be uploaded to Fairwinds Insights. (defaults to `false`)
|
||||
- `cluster-name` - cluster name that the results belongs to. Creates the cluster if it does not exist. (required if `upload-insights` is used)
|
||||
|
||||
|
||||
## 8.0.0
|
||||
* Change default severity from `ignore` to `warning` for `priorityClassNotSet`, `metadataAndNameMismatched`, `missingPodDisruptionBudget`, `automountServiceAccountToken`, `missingNetworkPolicy` checks.
|
||||
* Change default severity from `warning` to `danger` for `sensitiveContainerEnvVar`, `sensitiveConfigmapContent`, `clusterrolePodExecAttach`, `rolePodExecAttach`, `clusterrolebindingPodExecAttach`, `rolebindingClusterRolePodExecAttach`, `rolebindingRolePodExecAttach`,`clusterrolebindingClusterAdmin`,`rolebindingClusterAdminClusterRole`,`rolebindingClusterAdminRole` checks.
|
||||
|
||||
## 7.4.0
|
||||
* Skip https certificate verification (#920)
|
||||
|
||||
## 7.3.0
|
||||
* Add a check for `topologySpreadConstraint` (#879)
|
||||
|
||||
## 7.2.0
|
||||
* Enable new RBAC / sensitive content / Pod exec checks, add `hasPrefix` and `hasSuffix` functions to the GO template, exempt `system:` name prefixes for RBAC checks, sensitive content checks ignore `valueFrom`, (#832)
|
||||
|
||||
## 7.1.0
|
||||
* Let Polaris modify YAML without losing comments/formatting (#821)
|
||||
* Add checks for RBAC allowing exec or attaching to a Pod (#820)
|
||||
* Add `clusterrolebindingClusterAdmin`, `rolebindingClusterAdminRole`, and `rolebindingClusterAdminClusterRole` checks + schema tests (#823)
|
||||
|
||||
## 7.0.2
|
||||
* Fixes for pretty CLI output
|
||||
* Some new checks (disabled by default)
|
||||
* Some additional features in templating engine
|
||||
|
||||
## 7.0.1
|
||||
* Documentation updates
|
||||
|
||||
## 7.0.0
|
||||
* Better support for `polaris fix`
|
||||
* `target: Pod` is now `target: PodSpec` (to differentiate naked Pods from Controllers)
|
||||
|
||||
## 6.0.0
|
||||
* Preliminary support for `polaris fix` command
|
||||
* Changes to how Pod owners are determined
|
||||
* Removed YAML manifests from the `deploy/` directory - Helm is now the default install mechanism
|
||||
|
||||
## 5.1.0
|
||||
* Support `--context` flag for kubecontext
|
||||
* Treat core Kubernetes controllers (`Deployments`, `StatefulSets`, `DaemonSets`, `CronJobs`) as top-level objects, instead of following owner refs
|
||||
|
||||
## 5.0.0
|
||||
* Renamed `multipleReplicasForDeployment` to `deploymentMissingReplicas`
|
||||
* Changed `RunAsRootAllowed` and `hostNetworkSet` default severity to `danger`
|
||||
* Changed `deploymentMissingReplicas` default severity to `warning`
|
||||
|
||||
## 4.2.0
|
||||
* New flags `--disallow-(config|annotation)-exemptions`
|
||||
* Kubernetes dependency updates
|
||||
@@ -251,7 +132,7 @@ JSON schema (see changes to `./checks/multipleReplicasForDeployment.yaml`)
|
||||
* Docker image now includes the default config
|
||||
|
||||
### Breaking Changes
|
||||
* Breaking changes in both input and output formats. See [Examples](https://github.com/FairwindsOps/polaris/tree/master/pkg/config/examples) for examples of the new formats.
|
||||
* Breaking changes in both input and output formats. See [Examples](https://github.com/FairwindsOps/polaris/tree/master/examples) for examples of the new formats.
|
||||
* removed config-level configuration for checks like max/min memory settings
|
||||
* changed severity `error` to `danger`
|
||||
* Breaking changes to the CLI
|
||||
|
||||
@@ -14,58 +14,22 @@ key | default | description
|
||||
`livenessProbeMissing` | `warning` | Fails when a liveness probe is not configured for a pod.
|
||||
`tagNotSpecified` | `danger` | Fails when an image tag is either not specified or `latest`.
|
||||
`pullPolicyNotAlways` | `warning` | Fails when an image pull policy is not `always`.
|
||||
`priorityClassNotSet` | `warning` | Fails when a priorityClassName is not set for a pod.
|
||||
`deploymentMissingReplicas` | `warning` | Fails when there is only one replica for a deployment.
|
||||
`missingPodDisruptionBudget` | `warning` | Fails when PDB is missing.
|
||||
`metadataAndInstanceMismatched` | `warning` | Fails when label `app.kubernetes.io/instance` and `metadata.name` mismatch
|
||||
`topologySpreadConstraint` | `warning` | Fails when there is no topology spread constraint on the pod
|
||||
`hpaMaxAvailability` | `warning` | Fails when `maxAvailable` lesser or equal than `minAvailable` (if defined) for a HorizontalPodAutoscaler
|
||||
`hpaMinAvailability` | `warning` | Fails when `minAvailable` (if defined) lesser or equal to one for a HorizontalPodAutoscaler
|
||||
`pdbMinAvailableGreaterThanHPAMinReplicas` | `warning` | Fails when PDB `minAvailable` is greater than HPA `minReplicas`
|
||||
`priorityClassNotSet` | `ignore` | Fails when a priorityClassName is not set for a pod.
|
||||
`multipleReplicasForDeployment` | `ignore` | Fails when there is only one replica for a deployment.
|
||||
`missingPodDisruptionBudget` | `ignore`
|
||||
|
||||
## Background
|
||||
|
||||
### Liveness and Readiness Probes
|
||||
Readiness and liveness probes can help maintain the health of applications running inside Kubernetes. By default, Kubernetes only knows whether or not a process is running, not if it's healthy. Properly configured readiness and liveness probes will also be able to ensure the health of an application.
|
||||
|
||||
Readiness probes are designed to ensure that an application has reached a "ready" state. In many cases there is a period of time between when a webserver process starts and when it is ready to receive traffic. A readiness probe can ensure the traffic is not sent to a pod until it is actually ready to receive traffic.
|
||||
|
||||
Liveness probes are designed to ensure that an application stays in a healthy state. When a liveness probe fails, the pod will be restarted.
|
||||
|
||||
### Image Pull Policy
|
||||
Docker's `latest` tag is applied by default to images where a tag hasn't been specified. Not specifying a specific version of an image can lead to a wide variety of problems. The underlying image could include unexpected breaking changes that break your application whenever the latest image is pulled. Reusing the same tag for multiple versions of an image can lead to different nodes in the same cluster having different versions of an image, even if the tag is identical.
|
||||
|
||||
Related to that, relying on cached versions of a Docker image can become a security vulnerability. By default, an image will be pulled if it isn't already cached on the node attempting to run it. This can result in variations in images that are running per node, or potentially provide a way to gain access to an image without having direct access to the ImagePullSecret. With that in mind, it's often better to ensure the a pod has `pullPolicy: Always` specified, so images are always pulled directly from their source.
|
||||
|
||||
### Topology Spread Constraints
|
||||
|
||||
By default, the Kubernetes scheduler uses a bin-packing algorithm to fit as many pods as possible into a cluster. The scheduler prefers a more evenly distributed general node load to app replicas precisely spread across nodes. Therefore, by default, multi-replica is not guaranteed to be spread across multiple availability zones. Kubernetes provides topologySpreadConstraint configuration in order to better ensure pod spread across multiple AZs and/or Hosts.
|
||||
|
||||
Example of a topologySpreadConstraint spreading across zones:
|
||||
|
||||
```
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: demo-basic-demo
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: basic-demo
|
||||
app.kubernetes.io/instance: demo
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: basic-demo
|
||||
app.kubernetes.io/instance: demo
|
||||
spec:
|
||||
topologySpreadConstraints:
|
||||
- maxSkew: 1
|
||||
topologyKey: "topology.kubernetes.io/zone"
|
||||
whenUnsatisfiable: ScheduleAnyway
|
||||
```
|
||||
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [What's Wrong With The Docker :latest Tag?](https://vsupalov.com/docker-latest-tag/)
|
||||
@@ -73,4 +37,3 @@ spec:
|
||||
- [Kubernetes Docs: Configure Liveness and Readiness Probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)
|
||||
- [Utilizing Kubernetes Liveness and Readiness Probes to Automatically Recover From Failure](https://medium.com/spire-labs/utilizing-kubernetes-liveness-and-readiness-probes-to-automatically-recover-from-failure-2fe0314f2b2e)
|
||||
- [Kubernetes Liveness and Readiness Probes: How to Avoid Shooting Yourself in the Foot](https://blog.colinbreck.com/kubernetes-liveness-and-readiness-probes-how-to-avoid-shooting-yourself-in-the-foot/)
|
||||
- [Topology Spread Constraints](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/)
|
||||
|
||||
@@ -11,30 +11,17 @@ for privilege escalation.
|
||||
|
||||
key | default | description
|
||||
----|---------|------------
|
||||
`automountServiceAccountToken` | `warning` | Fails when `automountServiceAccountToken` is automounted.
|
||||
`hostIPCSet` | `danger` | Fails when `hostIPC` attribute is configured.
|
||||
`hostPIDSet` | `danger` | Fails when `hostPID` attribute is configured.
|
||||
`linuxHardening` | `danger` | Fails when neither `AppArmor`, `Seccomp`, `SELinux`, or dropping Linux Capabilities is in use.
|
||||
`notReadOnlyRootFilesystem` | `warning` | Fails when `securityContext.readOnlyRootFilesystem` is not true.
|
||||
`privilegeEscalationAllowed` | `danger` | Fails when `securityContext.allowPrivilegeEscalation` is true.
|
||||
`runAsRootAllowed` | `warning` | Fails when `securityContext.runAsNonRoot` is not true.
|
||||
`runAsPrivileged` | `danger` | Fails when `securityContext.privileged` is true.
|
||||
`insecureCapabilities` | `warning` | Fails when `securityContext.capabilities` includes one of the capabilities [listed here](https://github.com/FairwindsOps/polaris/tree/master/pkg/config/checks/insecureCapabilities.yaml)
|
||||
`dangerousCapabilities` | `danger` | Fails when `securityContext.capabilities` includes one of the capabilities [listed here](https://github.com/FairwindsOps/polaris/tree/master/pkg/config/checks/dangerousCapabilities.yaml)
|
||||
`insecureCapabilities` | `warning` | Fails when `securityContext.capabilities` includes one of the capabilities [listed here](https://github.com/FairwindsOps/polaris/tree/master/checks/insecureCapabilities.yaml)
|
||||
`dangerousCapabilities` | `danger` | Fails when `securityContext.capabilities` includes one of the capabilities [listed here](https://github.com/FairwindsOps/polaris/tree/master/checks/dangerousCapabilities.yaml)
|
||||
`hostNetworkSet` | `warning` | Fails when `hostNetwork` attribute is configured.
|
||||
`hostPortSet` | `warning` | Fails when `hostPort` attribute is configured.
|
||||
`tlsSettingsMissing` | `warning` | Fails when an Ingress lacks TLS settings.
|
||||
`sensitiveContainerEnvVar` | `danger` | Fails when the container sets potentially sensitive environment variables.
|
||||
`sensitiveConfigmapContent` | `danger` | Fails when potentially sensitive content is detected in the ConfigMap keys or values.
|
||||
`missingNetworkPolicy` | `warning`
|
||||
`clusterrolePodExecAttach` | `danger` | Fails when the ClusterRole allows Pods/exec or pods/attach.
|
||||
`rolePodExecAttach` | `danger` | Fails when the Role allows Pods/exec or pods/attach.
|
||||
`clusterrolebindingPodExecAttach` | `danger` | Fails when the ClusterRoleBinding references a ClusterRole that allows Pods/exec, allows pods/attach, or that does not exist.
|
||||
`rolebindingRolePodExecAttach` | `danger` | Fails when the RoleBinding references a Role that allows Pods/exec, allows pods/attach, or that does not exist.
|
||||
`rolebindingClusterRolePodExecAttach` | `danger` | Fails when the RoleBinding references a ClusterRole that allows Pods/exec, allows pods/attach, or that does not exist.
|
||||
`clusterrolebindingClusterAdmin` | `danger` | Fails when the ClusterRoleBinding references the default cluster-admin ClusterRole or one with wildcard permissions.
|
||||
`rolebindingClusterAdminClusterRole` | `danger` | Fails when the RoleBinding references the default cluster-admin ClusterRole or one with wildcard permissions.
|
||||
`rolebindingClusterAdminRole` | `danger` | Fails when the RoleBinding references a Role with wildcard permissions.
|
||||
|
||||
## Background
|
||||
|
||||
|
||||
@@ -9,27 +9,21 @@ meta:
|
||||
# top-level commands
|
||||
audit
|
||||
Runs a one-time audit.
|
||||
auth
|
||||
Authenticate polaris with Fairwinds Insights
|
||||
dashboard
|
||||
Runs the webserver for Polaris dashboard.
|
||||
fix
|
||||
Fix Infrastructure as code files.
|
||||
help
|
||||
Prints help, if you give it a command then it will print help for that command. Same as -h
|
||||
version
|
||||
Prints the version of Polaris
|
||||
webhook
|
||||
Runs the webhook webserver.
|
||||
Runs the webhook webserver
|
||||
|
||||
# global flags
|
||||
-c, --config string Location of Polaris configuration file.
|
||||
-x, --context string Set the kube context.
|
||||
--disallow-exemptions Disallow any exemptions from configuration file.
|
||||
--disallow-config-exemptions Disallow exemptions set within the configuration file.
|
||||
--disallow-annotation-exemptions Disallow any exemption defined as a controller annotation.
|
||||
--kubeconfig string Paths to a kubeconfig. Only required if out-of-cluster.
|
||||
--insights-host string Fairwinds Insights host URL. (default "https://insights.fairwinds.com")
|
||||
--log-level string Logrus log level. (default "info")
|
||||
|
||||
# dashboard flags
|
||||
@@ -43,48 +37,22 @@ webhook
|
||||
|
||||
# audit flags
|
||||
--audit-path string If specified, audits one or more YAML files instead of a cluster.
|
||||
--checks strings Optional flag to specify specific checks to check
|
||||
--cluster-name string Set --cluster-name to a descriptive name for the cluster you're auditing
|
||||
--color Whether to use color in pretty format. (default true)
|
||||
--display-name string An optional identifier for the audit.
|
||||
-f, --format string Output format for results - json, yaml, pretty, or score. (default "json")
|
||||
--helm-chart string Will fill out Helm template
|
||||
--helm-values string Optional flag to add helm values
|
||||
--helm-skip-tests bool Corresponds to --skip-tests of helm template
|
||||
-h, --help help for audit
|
||||
--namespace string Namespace to audit. Only applies to in-cluster audits
|
||||
--only-show-failed-tests If specified, audit output will only show failed tests.
|
||||
--output-file string Destination file for audit results.
|
||||
--output-url string Destination URL to send audit results.
|
||||
--quiet Suppress the 'upload to Insights' prompt.
|
||||
--resource string Audit a specific resource, in the format namespace/kind/version/name, e.g. nginx-ingress/Deployment.apps/v1/default-backend.
|
||||
--set-exit-code-below-score int Set an exit code of 4 when the score is below this threshold (1-100).
|
||||
--set-exit-code-on-danger Set an exit code of 3 when the audit contains danger-level issues.
|
||||
--severity string Severity level used to filter results. Behaves like log levels. 'danger' is the least verbose (warning, danger)
|
||||
--skip-ssl-validation Skip https certificate verification
|
||||
--upload-insights Upload scan results to Fairwinds Insights
|
||||
|
||||
# fix flags
|
||||
--checks strings Optional flag to specify specific checks to fix eg. checks=hostIPCSet,hostPIDSet and checks=all applies fix to all defined checks mutations
|
||||
--files-path string mutate and fix one or more YAML files in a specified folder
|
||||
-h, --help help for fix
|
||||
--template set to true when modifyng a YAML template, like a Helm chart (experimental)
|
||||
|
||||
|
||||
# webhook flags
|
||||
--disable-webhook-config-installer disable the installer in the webhook server, so it won't install webhook configuration resources during bootstrapping.
|
||||
-h, --help help for webhook
|
||||
-p, --port int Port for the dashboard webserver. (default 9876)
|
||||
|
||||
# auth sub-commands
|
||||
login Authenticate polaris with Fairwinds Insights.
|
||||
logout Log out of a Fairwinds Insights.
|
||||
status View authentication status.
|
||||
token Print the auth token gh is configured to use.
|
||||
```
|
||||
|
||||
#### Suppressing 'upload to Insights' output
|
||||
|
||||
When running the `polaris audit` subcommand, you can suppress the following output using the `--quiet flag`:
|
||||
|
||||
> 🚀 Upload your Polaris findings to Fairwinds Insights to see remediation advice, add teammates, integrate with Slack or Jira, and more:
|
||||
|
||||
@@ -49,7 +49,8 @@ kind create cluster --wait=90s --image kindest/node:v1.15.11 --name polaris-test
|
||||
docker build -t quay.io/fairwinds/polaris:debug . # or use your own registry
|
||||
docker push quay.io/fairwinds/polaris:debug
|
||||
helm repo add jetstack https://charts.jetstack.io
|
||||
helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.12.1 --set "installCRDs=true" --wait
|
||||
kubectl create ns cert-manager
|
||||
helm install cert-manager jetstack/cert-manager --namespace cert-manager --version 0.16.1 --set "installCRDs=true" --wait
|
||||
POLARIS_IMAGE=quay.io/fairwinds/polaris:debug ./test/webhook_test.sh
|
||||
```
|
||||
to avoid the final cleanup for debugging purposes, you can run
|
||||
@@ -72,7 +73,50 @@ Each new pull request should:
|
||||
- Be up to date and/or rebased on the master branch
|
||||
|
||||
## Creating a new release
|
||||
To create a new release, simply tag this repo with the new version.
|
||||
|
||||
For major and minor releases, don't forget to update the Helm chart at
|
||||
https://github.com/FairwindsOps/charts
|
||||
### Patch releases
|
||||
Patch releases only need to change this repo. The Helm chart and deploy scripts
|
||||
will automatically pull in the latest changes.
|
||||
|
||||
If the release involves changes to anything in the `deploy/` folder (e.g. new RBAC permissions),
|
||||
it needs to be a minor or major release in order to prevent breaking the Helm chart.
|
||||
|
||||
1. Create a PR for this repo
|
||||
1. Bump the version number in:
|
||||
1. main.go
|
||||
2. README.md
|
||||
2. Update CHANGELOG.md
|
||||
3. Merge your PR
|
||||
2. Tag the latest branch for this repo
|
||||
1. Pull the latest commit for the `master` branch (which you just merged in your PR)
|
||||
2. Run `git tag $VERSION && git push --tags`
|
||||
3. Make sure CircleCI runs successfully for the new tag - this will push images to quay.io and create a release in GitHub
|
||||
1. If CircleCI fails, check with Codeowners ASAP
|
||||
|
||||
### Minor/Major releases
|
||||
Minor and major releases need to change both this repository and the
|
||||
[Helm chart repo](https://github.com/FairwindsOps/charts/).
|
||||
|
||||
The steps are:
|
||||
1. Modify the [Helm chart](https://github.com/FairwindsOps/charts/stable/polaris)
|
||||
1. Clone the helm charts repo
|
||||
1. `git clone https://github.com/FairwindsOps/charts`
|
||||
2. `git checkout -b yourname/update-polaris`
|
||||
1. Bump the version number in `stable/polaris/Chart.yaml`
|
||||
2. Make any necessary changes to the chart to support the new version of Polaris (e.g. new RBAC permissions)
|
||||
3. **Don't merge yet!**
|
||||
2. Create a PR for this repo
|
||||
1. Create a new branch named `yourname/update-version`
|
||||
2. Bump the version number in:
|
||||
1. main.go
|
||||
2. README.md
|
||||
3. Regenerate the deployment files. Assuming you've cloned the charts repo to `~/git/charts`:
|
||||
1. `CHARTS_DIR=~/git/charts ./scripts/generate-deployment-files.sh`
|
||||
4. Update CHANGELOG.md
|
||||
5. Merge your PR
|
||||
3. Tag the latest branch for this repo
|
||||
1. Pull the latest for the `master` branch
|
||||
2. Run `git tag $VERSION && git push --tags`
|
||||
3. Make sure CircleCI runs successfully for the new tag - this will push images to quay.io and create a release in GitHub
|
||||
1. If CircleCI fails, check with Codeowners ASAP
|
||||
4. Create and merge a PR for your changes to the Helm chart
|
||||
|
||||
@@ -5,7 +5,7 @@ meta:
|
||||
---
|
||||
# Configuration
|
||||
|
||||
The default Polaris configuration can be [seen here](https://github.com/FairwindsOps/polaris/blob/master/pkg/config/default.yaml).
|
||||
The default Polaris configuration can be [seen here](https://github.com/FairwindsOps/polaris/blob/master/examples/config.yaml).
|
||||
|
||||
You can customize the configuration to do things like:
|
||||
* Turn checks [on and off](checks.md)
|
||||
|
||||
@@ -7,7 +7,7 @@ meta:
|
||||
|
||||
If you'd like to create your own checks, you can use [JSON Schema](https://json-schema.org/).
|
||||
This is how built-in Polaris checks are defined as well - you can see all the built-in checks
|
||||
in the [checks folder](https://github.com/FairwindsOps/polaris/tree/master/pkg/config/checks) for examples.
|
||||
in the [checks folder](https://github.com/FairwindsOps/polaris/tree/master/checks) for examples.
|
||||
|
||||
If you write a check that could be useful for others, feel free to open a PR to add it in!
|
||||
|
||||
@@ -43,11 +43,10 @@ check ID. Note that you'll also have to set its severity in the `checks` section
|
||||
* `category` - one of `Security`, `Efficiency`, or `Reliability`
|
||||
* `target` - specifies the type of resource to check. This can be:
|
||||
* a group and kind, e.g. `apps/Deployment` or `networking.k8s.io/Ingress`
|
||||
* `Controller`, to check _any_ resource that creates Pods (e.g. Deployments, CronJobs, StatefulSets), as well as naked Pods
|
||||
* `PodTemplate`, same as `Controller`, but the schema applies to the Pod template rather than the top-level controller
|
||||
* `PodSpec`, same as `Controller`, but the schema applies to the Pod spec rather than the top-level controller
|
||||
* `Controller`, to check _any_ resource that contains a pod spec (e.g. Deployments, CronJobs, StatefulSets), as well as naked Pods
|
||||
* `Pod`, same as `Controller`, but the schema applies to the Pod spec rather than the top-level controller
|
||||
* `Container` same as `Controller`, but the schema applies to all Container specs rather than the top-level controller
|
||||
* `controllers` - if `target` is `Controller`, `PodSpec` or `Container`, you can use this to change which types of controllers are checked
|
||||
* `controllers` - if `target` is `Controller`, `Pod` or `Container`, you can use this to change which types of controllers are checked
|
||||
* `controllers.include` - _only_ check these controllers
|
||||
* `controllers.exclude` - check all controllers except these
|
||||
* `containers` - if `target` is `Container`, you can use this to decide if `initContainers`, `containers`, or both should be checked
|
||||
@@ -135,11 +134,6 @@ schema:
|
||||
const: "{{ .metadata.name }}"
|
||||
```
|
||||
|
||||
* The object available via the go template is the full object, and not limited by `target`.
|
||||
* A check of `target: PodSpec` can directly access the pod specification via the go template variable `.Polaris.PodSpec`.
|
||||
* A check of `target: PodTemplate` can directly access the pod template via the go template variable `.Polaris.PodTemplate`.
|
||||
* A check of `target: Container` can directly access the container being checked via the go template variable `.Polaris.container`. The pod template and pod specification can also be accessed via the respective variables `.Polaris.PodTemplate` and `.Polaris.PodSpec`. Access to pod-level fields allows a container check to consult related fields from the pod, such as `securityContext`.
|
||||
|
||||
You can also use the full [Go template syntax](https://golang.org/pkg/text/template/), though
|
||||
you may need to specify your schema as a string in order to use concepts like `range`. E.g.
|
||||
this check ensures that at least one of the object's labels is present in `matchLabels`:
|
||||
@@ -167,18 +161,6 @@ schemaString: |
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
### Additional Go Template Functions
|
||||
|
||||
These functions are also available in the GO template.
|
||||
|
||||
* [hasPrefix](https://pkg.go.dev/strings#HasPrefix) - for example, `hasPrefix "string" "prefix"`
|
||||
* [hasSuffix](https://pkg.go.dev/strings#HasSuffix) - for example, `hasSuffix "string" "suffix"`
|
||||
|
||||
For example, the `hasPrefix` function can be used in a template to determine whether a resource name starts with `system:`
|
||||
```
|
||||
{{ if hasPrefix .metadata.name "system:" }}
|
||||
```
|
||||
|
||||
## Multi-Resource Checks
|
||||
You can write checks that span multiple resources. This is helpful for ensuring e.g.
|
||||
that every Deployment has a PDB or an HPA associated with it.
|
||||
|
||||
@@ -16,6 +16,11 @@ don't conform to best practices.
|
||||
|
||||
## Installation
|
||||
|
||||
### kubectl
|
||||
```bash
|
||||
kubectl apply -f https://github.com/fairwindsops/polaris/releases/latest/download/dashboard.yaml
|
||||
kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80
|
||||
```
|
||||
### Helm
|
||||
```bash
|
||||
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
|
||||
|
||||
@@ -25,32 +25,6 @@ brew install FairwindsOps/tap/polaris
|
||||
polaris version
|
||||
```
|
||||
|
||||
## Checking Infrastructure as Code files
|
||||
You can audit Kubernetes YAML files by running:
|
||||
```bash
|
||||
polaris audit --audit-path ./deploy/ --format=pretty
|
||||
```
|
||||
This will print out any issues Polaris finds in your manifests.
|
||||
|
||||
Polaris can only check raw YAML manifests. If you'd like to check a Helm template,
|
||||
you can run `helm template` to generate a manifest that Polaris can check.
|
||||
|
||||
## Fixing Issues
|
||||
Polaris can automatically fix many of the issues it finds. For example, you can run
|
||||
```bash
|
||||
polaris fix --files-path ./deploy/ --checks=all
|
||||
```
|
||||
|
||||
to fix any issues inside the `deploy` directory. Polaris may leave
|
||||
comments next to some changes (e.g. liveness and readiness probes) prompting
|
||||
the user to set them to something more appropriate given the context of their
|
||||
application.
|
||||
|
||||
Note that not all issues can be automatically fixed.
|
||||
|
||||
Currently only raw YAML manifests can be mutated. Helm charts etc.
|
||||
still need to be changed manually.
|
||||
|
||||
## Running in a CI pipeline
|
||||
|
||||
### Set minimum score for an exit code
|
||||
@@ -116,7 +90,7 @@ The version number of the release tag.
|
||||
```yaml
|
||||
uses: fairwindsops/polaris/.github/actions/setup-polaris@master
|
||||
with:
|
||||
version: 5.0.0
|
||||
version: 4.2.0
|
||||
```
|
||||
|
||||
Example inside a job:
|
||||
@@ -127,7 +101,7 @@ steps:
|
||||
- name: Setup polaris
|
||||
uses: fairwindsops/polaris/.github/actions/setup-polaris@master
|
||||
with:
|
||||
version: 5.0.0
|
||||
version: 4.2.0
|
||||
|
||||
- name: Use command
|
||||
run: polaris version
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
},
|
||||
"description": "A repository with a Vuepress template for Fairwinds projects",
|
||||
"devDependencies": {
|
||||
"vuepress": "^1.9.7",
|
||||
"vuepress": "^1.4.0",
|
||||
"vuepress-plugin-clean-urls": "^1.1.1",
|
||||
"vuepress-plugin-redirect": "^1.2.5"
|
||||
"vuepress-plugin-redirect": "^1.2.3"
|
||||
},
|
||||
"directories": {
|
||||
"doc": "docs"
|
||||
@@ -26,8 +26,7 @@
|
||||
"scripts": {
|
||||
"build": "npm run build:readme && npm run build:docs",
|
||||
"build:docs": "vuepress build -d ../dist/",
|
||||
"build:metadata": "cat main-metadata.md > README.md || true",
|
||||
"build:readme": "npm run build:metadata && cat ../README.md | grep -v 'ocumentation' | sed \"s/https:\\/\\/\\w\\+.docs.fairwinds.com//g\" >> README.md",
|
||||
"build:readme": "cat ../README.md | grep -v 'ocumentation' | sed \"s/https:\\/\\/\\w\\+.docs.fairwinds.com//g\" > README.md",
|
||||
"check-links": "vuepress check-md",
|
||||
"serve": "npm run build:readme && vuepress dev --port 3003",
|
||||
"vuepress": "vuepress"
|
||||
|
||||
@@ -1,53 +1,27 @@
|
||||
checks:
|
||||
# reliability
|
||||
deploymentMissingReplicas: warning
|
||||
multipleReplicasForDeployment: warning
|
||||
priorityClassNotSet: warning
|
||||
tagNotSpecified: danger
|
||||
pullPolicyNotAlways: warning
|
||||
readinessProbeMissing: warning
|
||||
livenessProbeMissing: warning
|
||||
topologySpreadConstraint: warning
|
||||
pdbDisruptionsIsZero: warning
|
||||
missingPodDisruptionBudget: warning
|
||||
metadataAndInstanceMismatched: warning
|
||||
hpaMaxAvailability: warning
|
||||
hpaMinAvailability: warning
|
||||
pdbMinAvailableGreaterThanHPAMinReplicas: warning
|
||||
|
||||
# efficiency
|
||||
cpuRequestsMissing: warning
|
||||
cpuLimitsMissing: warning
|
||||
memoryRequestsMissing: warning
|
||||
memoryLimitsMissing: warning
|
||||
|
||||
# security
|
||||
automountServiceAccountToken: warning
|
||||
hostIPCSet: danger
|
||||
hostPathSet: warning
|
||||
hostProcess: warning
|
||||
hostPIDSet: danger
|
||||
linuxHardening: danger
|
||||
missingNetworkPolicy: warning
|
||||
notReadOnlyRootFilesystem: warning
|
||||
privilegeEscalationAllowed: danger
|
||||
procMount: warning
|
||||
runAsRootAllowed: danger
|
||||
runAsRootAllowed: warning
|
||||
runAsPrivileged: danger
|
||||
dangerousCapabilities: danger
|
||||
insecureCapabilities: warning
|
||||
hostNetworkSet: danger
|
||||
hostNetworkSet: warning
|
||||
hostPortSet: warning
|
||||
tlsSettingsMissing: warning
|
||||
sensitiveContainerEnvVar: danger
|
||||
sensitiveConfigmapContent: danger
|
||||
clusterrolePodExecAttach: danger
|
||||
rolePodExecAttach: danger
|
||||
clusterrolebindingPodExecAttach: danger
|
||||
rolebindingClusterRolePodExecAttach: danger
|
||||
rolebindingRolePodExecAttach: danger
|
||||
clusterrolebindingClusterAdmin: danger
|
||||
rolebindingClusterAdminClusterRole: danger
|
||||
rolebindingClusterAdminRole: danger
|
||||
# custom
|
||||
resourceLimits: warning
|
||||
imageRegistry: danger
|
||||
@@ -112,3 +86,4 @@ customChecks:
|
||||
type: string
|
||||
not:
|
||||
pattern: ^quay.io
|
||||
|
||||
@@ -1,98 +1,34 @@
|
||||
checks:
|
||||
# reliability
|
||||
deploymentMissingReplicas: warning
|
||||
priorityClassNotSet: warning
|
||||
multipleReplicasForDeployment: ignore
|
||||
priorityClassNotSet: ignore
|
||||
tagNotSpecified: danger
|
||||
pullPolicyNotAlways: warning
|
||||
readinessProbeMissing: warning
|
||||
livenessProbeMissing: warning
|
||||
metadataAndInstanceMismatched: warning
|
||||
metadataAndNameMismatched: ignore
|
||||
pdbDisruptionsIsZero: warning
|
||||
missingPodDisruptionBudget: warning
|
||||
topologySpreadConstraint: warning
|
||||
hpaMaxAvailability: warning
|
||||
hpaMinAvailability: warning
|
||||
pdbMinAvailableGreaterThanHPAMinReplicas: warning
|
||||
missingPodDisruptionBudget: ignore
|
||||
|
||||
# efficiency
|
||||
cpuRequestsMissing: warning
|
||||
cpuLimitsMissing: warning
|
||||
memoryRequestsMissing: warning
|
||||
memoryLimitsMissing: warning
|
||||
|
||||
# security
|
||||
automountServiceAccountToken: warning
|
||||
hostIPCSet: danger
|
||||
hostPathSet: warning
|
||||
hostProcess: warning
|
||||
hostPIDSet: danger
|
||||
linuxHardening: warning
|
||||
missingNetworkPolicy: warning
|
||||
notReadOnlyRootFilesystem: warning
|
||||
privilegeEscalationAllowed: danger
|
||||
procMount: warning
|
||||
runAsRootAllowed: danger
|
||||
runAsRootAllowed: warning
|
||||
runAsPrivileged: danger
|
||||
dangerousCapabilities: danger
|
||||
insecureCapabilities: warning
|
||||
hostNetworkSet: danger
|
||||
hostNetworkSet: warning
|
||||
hostPortSet: warning
|
||||
tlsSettingsMissing: warning
|
||||
sensitiveContainerEnvVar: danger
|
||||
sensitiveConfigmapContent: danger
|
||||
clusterrolePodExecAttach: danger
|
||||
rolePodExecAttach: danger
|
||||
clusterrolebindingPodExecAttach: danger
|
||||
rolebindingClusterRolePodExecAttach: danger
|
||||
rolebindingRolePodExecAttach: danger
|
||||
clusterrolebindingClusterAdmin: danger
|
||||
rolebindingClusterAdminClusterRole: danger
|
||||
rolebindingClusterAdminRole: danger
|
||||
|
||||
|
||||
mutations:
|
||||
- pullPolicyNotAlways
|
||||
|
||||
exemptions:
|
||||
- namespace: kube-system
|
||||
controllerNames:
|
||||
- dns-controller
|
||||
- ebs-csi-controller
|
||||
- ebs-csi-node
|
||||
- kindnet
|
||||
- kops-controller
|
||||
- kube-dns
|
||||
- kube-flannel-ds
|
||||
- kube-proxy
|
||||
- kube-scheduler
|
||||
- vpa-recommender
|
||||
rules:
|
||||
- automountServiceAccountToken
|
||||
- linuxHardening
|
||||
- missingNetworkPolicy
|
||||
- namespace: kube-system
|
||||
controllerNames:
|
||||
- coredns
|
||||
rules:
|
||||
- automountServiceAccountToken
|
||||
- missingNetworkPolicy
|
||||
- namespace: kube-system
|
||||
controllerNames:
|
||||
- ebs-csi-controller
|
||||
rules:
|
||||
- sensitiveContainerEnvVar
|
||||
- namespace: kube-system
|
||||
controllerNames:
|
||||
- coredns-autoscaler
|
||||
rules:
|
||||
- linuxHardening
|
||||
- namespace: local-path-storage
|
||||
controllerNames:
|
||||
- local-path-provisioner
|
||||
rules:
|
||||
- automountServiceAccountToken
|
||||
- linuxHardening
|
||||
- missingNetworkPolicy
|
||||
- namespace: kube-system
|
||||
controllerNames:
|
||||
- kube-apiserver
|
||||
@@ -115,48 +51,7 @@ exemptions:
|
||||
- runAsPrivileged
|
||||
- notReadOnlyRootFilesystem
|
||||
- hostPIDSet
|
||||
- namespace: datadog
|
||||
controllerNames:
|
||||
- datadogtoken
|
||||
rules:
|
||||
- sensitiveConfigmapContent
|
||||
- namespace: datadog
|
||||
controllerNames:
|
||||
- datadog-cluster-agent-apiserver
|
||||
rules:
|
||||
- rolebindingClusterAdminRole
|
||||
- rolebindingRolePodExecAttach
|
||||
|
||||
- controllerNames:
|
||||
- ingress-nginx-controller
|
||||
rules:
|
||||
- sensitiveConfigmapContent
|
||||
- controllerNames:
|
||||
- ingress-nginx-controller
|
||||
- ingress-nginx-default-backend
|
||||
- polaris
|
||||
- rbac-manager
|
||||
rules:
|
||||
- automountServiceAccountToken
|
||||
- missingNetworkPolicy
|
||||
- controllerNames:
|
||||
- aws-iam-authenticator
|
||||
- aws-load-balancer-controller
|
||||
- docker-registry
|
||||
- external-dns
|
||||
- kube2iam
|
||||
- metrics-server
|
||||
rules:
|
||||
- automountServiceAccountToken
|
||||
- linuxHardening
|
||||
- missingNetworkPolicy
|
||||
- controllerNames:
|
||||
- oauth2-proxy
|
||||
rules:
|
||||
- automountServiceAccountToken
|
||||
- linuxHardening
|
||||
- missingNetworkPolicy
|
||||
- sensitiveContainerEnvVar
|
||||
- controllerNames:
|
||||
- kube-flannel-ds
|
||||
rules:
|
||||
@@ -174,9 +69,6 @@ exemptions:
|
||||
- runAsRootAllowed
|
||||
- readinessProbeMissing
|
||||
- livenessProbeMissing
|
||||
- automountServiceAccountToken
|
||||
- linuxHardening
|
||||
- missingNetworkPolicy
|
||||
|
||||
- controllerNames:
|
||||
- cluster-autoscaler
|
||||
@@ -184,9 +76,6 @@ exemptions:
|
||||
- notReadOnlyRootFilesystem
|
||||
- runAsRootAllowed
|
||||
- readinessProbeMissing
|
||||
- automountServiceAccountToken
|
||||
- linuxHardening
|
||||
- missingNetworkPolicy
|
||||
|
||||
- controllerNames:
|
||||
- vpa
|
||||
@@ -203,10 +92,6 @@ exemptions:
|
||||
- readinessProbeMissing
|
||||
- livenessProbeMissing
|
||||
- notReadOnlyRootFilesystem
|
||||
- automountServiceAccountToken
|
||||
- linuxHardening
|
||||
- missingNetworkPolicy
|
||||
- sensitiveContainerEnvVar
|
||||
|
||||
- controllerNames:
|
||||
- nginx-ingress-controller
|
||||
@@ -1,7 +1,14 @@
|
||||
options:
|
||||
organization: fairwinds-production
|
||||
organization: fairwinds-opensource
|
||||
baseBranch: master
|
||||
|
||||
# These images will be scanned for vulnerabilities.
|
||||
images:
|
||||
docker:
|
||||
- quay.io/fairwinds/polaris:$CI_SHA1
|
||||
|
||||
# These manifests will be scanned for configuration issues.
|
||||
manifests:
|
||||
yaml:
|
||||
- ./deploy/dashboard.yaml
|
||||
- ./deploy/webhook.yaml
|
||||
|
||||
@@ -1,83 +1,25 @@
|
||||
module github.com/fairwindsops/polaris
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.4
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||
github.com/fairwindsops/controller-utils v0.3.4
|
||||
github.com/fairwindsops/insights-plugins/plugins/workloads v0.0.0-20241211185107-d14f77fb8b16
|
||||
github.com/fatih/color v1.18.0
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/qri-io/jsonschema v0.1.2
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/thoas/go-funk v0.9.3
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.32.0
|
||||
k8s.io/apimachinery v0.32.0
|
||||
k8s.io/client-go v0.32.0
|
||||
sigs.k8s.io/controller-runtime v0.19.3
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/gnostic-models v0.6.9 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/gobuffalo/packr/v2 v2.8.1
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.61.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/qri-io/jsonpointer v0.1.1 // indirect
|
||||
github.com/samber/lo v1.47.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/oauth2 v0.24.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/term v0.27.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.8.0 // indirect
|
||||
google.golang.org/protobuf v1.35.2 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect
|
||||
github.com/google/uuid v1.1.3 // indirect
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/karrick/godirwalk v1.16.1 // indirect
|
||||
github.com/qri-io/jsonschema v0.1.1
|
||||
github.com/rogpeppe/go-internal v1.6.2 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/cobra v1.2.1
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/thoas/go-funk v0.9.1
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
k8s.io/api v0.22.2
|
||||
k8s.io/apimachinery v0.22.2
|
||||
k8s.io/client-go v0.22.2
|
||||
sigs.k8s.io/controller-runtime v0.10.1
|
||||
sigs.k8s.io/yaml v1.3.0
|
||||
)
|
||||
|
||||