mirror of
https://github.com/FairwindsOps/polaris.git
synced 2026-08-29 22:17:16 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f62454df8d | ||
|
|
7374d8b5dd | ||
|
|
99b9c0af27 | ||
|
|
fbff67c7eb | ||
|
|
6fc1ee0adb | ||
|
|
2bf5a195c1 | ||
|
|
2d326419c2 | ||
|
|
31fc0ab6d9 | ||
|
|
7e2bd017b3 | ||
|
|
5d6446afed | ||
|
|
b1ead662a2 | ||
|
|
bf9173acea | ||
|
|
568a79b4f6 | ||
|
|
e64fb4cdbd | ||
|
|
2b77ac2b1e | ||
|
|
20ea63ebe5 | ||
|
|
11d5200962 | ||
|
|
aefad52704 | ||
|
|
86b856a88c | ||
|
|
33dcb3f267 | ||
|
|
7c9ab1395f | ||
|
|
1a8fb44b78 | ||
|
|
51d91c7d2e | ||
|
|
0cd0d83172 | ||
|
|
b3f1b3b478 | ||
|
|
4ff34de49b | ||
|
|
5bce1db05e | ||
|
|
b27f619d5e | ||
|
|
9cce9fcec7 | ||
|
|
f05d3caa0b | ||
|
|
3c1533790f | ||
|
|
20746518bc | ||
|
|
75808b1dc1 | ||
|
|
7c9f01639b | ||
|
|
6cb9999864 | ||
|
|
a621249787 | ||
|
|
679f135b62 | ||
|
|
5c456ddb86 | ||
|
|
c1c07bcea2 | ||
|
|
c703aa4039 | ||
|
|
1051bc5922 | ||
|
|
155299a8d5 | ||
|
|
f0b63e3cb6 | ||
|
|
479ab1dae6 | ||
|
|
b5058cd906 | ||
|
|
c1115e556b | ||
|
|
617d3d28b5 | ||
|
|
582a631014 | ||
|
|
f4c2ae451f | ||
|
|
b76b2c3df4 | ||
|
|
0bbf43146c | ||
|
|
c33452bba0 | ||
|
|
300c8d9d94 | ||
|
|
7b1f046586 | ||
|
|
4e290e192d | ||
|
|
8d562f2490 | ||
|
|
47150155a0 | ||
|
|
b3d323d742 | ||
|
|
6060cf243f | ||
|
|
e044a540ed | ||
|
|
f6a4bffe88 | ||
|
|
343e24886d | ||
|
|
997d4bfb2b | ||
|
|
9ded3269c6 | ||
|
|
ca65a446bd | ||
|
|
4e9aa21cea | ||
|
|
ed014ecf8e | ||
|
|
2e11c04664 | ||
|
|
80662bd203 | ||
|
|
5705f81911 | ||
|
|
b4e3d40f4b | ||
|
|
cea0ca7fa8 | ||
|
|
69bed16e4f | ||
|
|
5b173cf4a7 | ||
|
|
0a0720a26c | ||
|
|
fa3504c350 | ||
|
|
4020000d68 | ||
|
|
ab7eeccfb0 | ||
|
|
78a16fa0ea | ||
|
|
b26c4be8d6 | ||
|
|
aada33f0e9 | ||
|
|
7b88c48a6e | ||
|
|
ded260ee19 | ||
|
|
3e9c270ac7 | ||
|
|
bf6e41566d | ||
|
|
ededabf00f | ||
|
|
3df9d35c57 | ||
|
|
a90c3b0f12 | ||
|
|
d19b0769b4 | ||
|
|
97f25cd7d1 | ||
|
|
03331147ca | ||
|
|
d44138bead | ||
|
|
eb21b030c2 | ||
|
|
3061756a55 | ||
|
|
2964280976 | ||
|
|
f657071a7f | ||
|
|
2cdc4775e0 | ||
|
|
af5b86e28c | ||
|
|
1021f6b1d7 | ||
|
|
0111b7ec2b | ||
|
|
33524757aa | ||
|
|
eea4a8e2c3 | ||
|
|
fb98d3112d | ||
|
|
97c81ccf60 | ||
|
|
e9b79fbdd4 | ||
|
|
217e3563d6 | ||
|
|
deb33bb05f | ||
|
|
e605eef755 | ||
|
|
c304036f97 | ||
|
|
c1061b50e0 | ||
|
|
3b07496a4d | ||
|
|
3eb2b6e2c9 | ||
|
|
5f5da069fd | ||
|
|
ceeffb97a0 | ||
|
|
27faab919c | ||
|
|
f4fc7c1b5d | ||
|
|
54d796b1f3 | ||
|
|
9065e3b2ae | ||
|
|
bd14ab8bc1 | ||
|
|
2ac6a2b540 | ||
|
|
9d81c393de | ||
|
|
b557786325 | ||
|
|
5572bb8118 | ||
|
|
ac9412920f | ||
|
|
d50d9c81f8 | ||
|
|
de98d9fbeb | ||
|
|
eac15d6258 | ||
|
|
0c671d0f62 | ||
|
|
e9064dfddc | ||
|
|
cf10a9617f | ||
|
|
c571b97bc9 | ||
|
|
fa5954c9ce | ||
|
|
58ec098c05 | ||
|
|
c9211b9e56 | ||
|
|
a3e9939f76 | ||
|
|
450d065f55 | ||
|
|
9ce3c06d5c | ||
|
|
ee951c8460 | ||
|
|
69621f7034 | ||
|
|
4cf3d15af0 | ||
|
|
5d875a225c | ||
|
|
6792fba91f | ||
|
|
f559f3328b | ||
|
|
38e512291d | ||
|
|
cfc0d213cd | ||
|
|
22125549a6 | ||
|
|
9e8378aece | ||
|
|
79603c8cf7 | ||
|
|
c21163aadc | ||
|
|
c03ecbde4a | ||
|
|
57f3a8b911 | ||
|
|
37660e0fe9 | ||
|
|
dcf02b9549 | ||
|
|
3c46f405a9 | ||
|
|
94548d0dcf | ||
|
|
1497c9a872 | ||
|
|
a5828a2d3b | ||
|
|
5769acf820 | ||
|
|
aa0658b5ac | ||
|
|
49dbd1d33b | ||
|
|
68fe23018a | ||
|
|
ea9db7e273 | ||
|
|
56ba00f524 | ||
|
|
d18bf855cb | ||
|
|
cbe1f104da | ||
|
|
6eb12b3bfe | ||
|
|
98533bc11a | ||
|
|
e4b8992301 | ||
|
|
ee2ccb0c26 | ||
|
|
61ecb69ab1 | ||
|
|
c43ace22a3 | ||
|
|
fb0d7c5d82 | ||
|
|
403d424d66 | ||
|
|
760e57c520 | ||
|
|
72b8bfa8f6 | ||
|
|
8c769e445c | ||
|
|
3c685279be | ||
|
|
7fdebfc4db | ||
|
|
0d3fe6130a | ||
|
|
bb34be7e02 | ||
|
|
fe55216e2a | ||
|
|
3191f087bb | ||
|
|
e80311d937 | ||
|
|
d4717302d4 | ||
|
|
a5d54af2b8 | ||
|
|
1b2a930a9c | ||
|
|
33d4192871 | ||
|
|
2a0ed94d0d | ||
|
|
9ff5d5a70e | ||
|
|
6a1cee846a | ||
|
|
cd002d0aff | ||
|
|
d2bb2f126b | ||
|
|
ec4e755f2f | ||
|
|
3e9193af7f | ||
|
|
efd0ec85b9 | ||
|
|
c036c91247 | ||
|
|
dad526245d | ||
|
|
c591765f70 | ||
|
|
51f3eaa3f0 | ||
|
|
574a1483eb | ||
|
|
a0604ba3a5 | ||
|
|
0da4ea69bf | ||
|
|
6213291be8 | ||
|
|
619e17d7a1 | ||
|
|
c64ba4bf91 | ||
|
|
44572936ec | ||
|
|
9c9e58c23d | ||
|
|
b9d6a1ea85 | ||
|
|
4c345f3799 | ||
|
|
6009ee67fa | ||
|
|
ddbf2e8c11 | ||
|
|
edaea49cd0 | ||
|
|
54727d933d | ||
|
|
3e1cc3c9e9 | ||
|
|
1cae69d080 | ||
|
|
6f8028fc17 | ||
|
|
d507039d5f | ||
|
|
b5ac0bc5d6 | ||
|
|
31de106ba8 | ||
|
|
aaa54cc401 | ||
|
|
51d639e2ef | ||
|
|
330d7f0516 | ||
|
|
73c4923334 | ||
|
|
10fdf4ef33 | ||
|
|
ed48daa092 | ||
|
|
7f71a352a7 | ||
|
|
ba412ab407 | ||
|
|
7b0817202c | ||
|
|
36876072f2 | ||
|
|
b7b5c43cdf | ||
|
|
100b4e8b9e | ||
|
|
e873a40cc3 | ||
|
|
1d9968b3af | ||
|
|
6338c53c2e | ||
|
|
0c70bacf4f | ||
|
|
56bba70ef3 | ||
|
|
03cc3fb1bd | ||
|
|
bcc1cc5384 | ||
|
|
5ef97ae896 | ||
|
|
dfa34e1880 | ||
|
|
542694841a | ||
|
|
e6a44c6ff8 | ||
|
|
7637108234 | ||
|
|
23bf4c81b0 | ||
|
|
090700f641 | ||
|
|
e129ba6971 | ||
|
|
51cd3523fc | ||
|
|
ac501a20d2 | ||
|
|
83a7448c99 | ||
|
|
d228acfe71 | ||
|
|
49c540e993 | ||
|
|
9f7caabef4 | ||
|
|
2770be643f | ||
|
|
5cd52242c4 | ||
|
|
6b4227da4d | ||
|
|
2e1aa0db4a | ||
|
|
e7baeac2e5 | ||
|
|
051319fab7 | ||
|
|
917e630697 | ||
|
|
68166559c5 | ||
|
|
fee55ba7f8 | ||
|
|
d0e0009efc | ||
|
|
57ff1d5c06 | ||
|
|
f0834d30a2 | ||
|
|
4d82220212 | ||
|
|
f8d5ce70cf | ||
|
|
5f060801ef | ||
|
|
04da47d83e | ||
|
|
5efa416ea9 | ||
|
|
7b0fe81d01 | ||
|
|
1067255173 | ||
|
|
7cc0be4188 | ||
|
|
b0035158d2 | ||
|
|
7070eb724c | ||
|
|
f7dccc079b | ||
|
|
6c588848ef | ||
|
|
ad3a8e6748 | ||
|
|
3fa627a2cd | ||
|
|
30b49c4d7b | ||
|
|
f2c5752718 | ||
|
|
d0dc7f4b0e | ||
|
|
3304285b4e | ||
|
|
d80d326f7c | ||
|
|
df48615a26 | ||
|
|
59785196d4 | ||
|
|
02252c690d | ||
|
|
25be9e41dd | ||
|
|
ddf815d636 | ||
|
|
95c04b1e9d | ||
|
|
0f2e5e0def | ||
|
|
8b20fd9dcf | ||
|
|
d4e3258d53 | ||
|
|
b4e3f78b72 | ||
|
|
20257cd917 | ||
|
|
317dfcefd2 | ||
|
|
42e8666356 | ||
|
|
49a419548f | ||
|
|
790607c6c0 | ||
|
|
91378c3d92 | ||
|
|
207297c11d | ||
|
|
0d86096f09 | ||
|
|
67ab987f7e | ||
|
|
97457d71c0 | ||
|
|
1159a380ba | ||
|
|
ca6aa76729 | ||
|
|
7ce71f1632 | ||
|
|
98b47e0aeb | ||
|
|
159c165468 | ||
|
|
4eeabb2c7f | ||
|
|
7e35b03452 | ||
|
|
c8e4f766a2 | ||
|
|
0ee39a4470 | ||
|
|
fc7c913122 | ||
|
|
3e15586597 | ||
|
|
3d07ce8004 | ||
|
|
22ab851681 | ||
|
|
152c876067 | ||
|
|
c10b2e0e55 | ||
|
|
2b15f11d57 | ||
|
|
b172f61c5f | ||
|
|
150b812371 | ||
|
|
434b1f604f | ||
|
|
6e3ab067d7 | ||
|
|
2e44d151fe | ||
|
|
c91a85a08a | ||
|
|
f8bb171209 | ||
|
|
f860c34d62 | ||
|
|
b8422a93b7 | ||
|
|
15b14555a6 | ||
|
|
467ab945cd | ||
|
|
dddeeb3332 | ||
|
|
f03f97ab07 | ||
|
|
75f70352ba | ||
|
|
4aa360a933 | ||
|
|
dce24a0a34 | ||
|
|
fae7a9fc17 | ||
|
|
79b0a00d5c | ||
|
|
e4fe5ab085 | ||
|
|
2049698c8e | ||
|
|
20bd32afb6 | ||
|
|
c132f7ee51 | ||
|
|
10025764cd | ||
|
|
c8c0e07a22 | ||
|
|
b55f4717b1 | ||
|
|
f493c380fc | ||
|
|
baa652197a | ||
|
|
a6525fc807 | ||
|
|
e01c39230a | ||
|
|
7b8b5fee4d | ||
|
|
819b77ae1a | ||
|
|
edccf88ccd | ||
|
|
7f42841572 | ||
|
|
b5a180d3de | ||
|
|
69efa2a0a3 | ||
|
|
7f4029386d | ||
|
|
9f7ed8214e | ||
|
|
5e67812d5a | ||
|
|
821de5fa8f | ||
|
|
20bf86ec12 | ||
|
|
87370a4fbc | ||
|
|
7b0e0e7f15 | ||
|
|
962494e47a | ||
|
|
c816e60441 | ||
|
|
d46fd6215a | ||
|
|
7bcd01e6be | ||
|
|
20a6028145 | ||
|
|
f784c48217 | ||
|
|
9b755b8b93 | ||
|
|
29261ed8bf | ||
|
|
1b5557d6ed | ||
|
|
3fd3c04429 | ||
|
|
5b9257b4ce | ||
|
|
d8d0783f29 | ||
|
|
4c7429efbc | ||
|
|
73727bd9d8 |
@@ -1,5 +1,10 @@
|
||||
DOCKERFILE='Dockerfile'
|
||||
|
||||
EXTERNAL_REGISTRY_BASE_DOMAIN=quay.io
|
||||
REPOSITORY_NAME=reactiveops/polaris
|
||||
REPOSITORY_NAME=fairwinds/polaris
|
||||
DOCKERTAG=${EXTERNAL_REGISTRY_BASE_DOMAIN}/${REPOSITORY_NAME}
|
||||
if [[ -n $CI_TAG ]]; then
|
||||
ADDITIONAL_DOCKER_TAG_VERSIONS=()
|
||||
ADDITIONAL_DOCKER_TAG_VERSIONS+=(`echo $CI_TAG | sed -e 's/\(\w\+\)\..*$/\1/'`)
|
||||
ADDITIONAL_DOCKER_TAG_VERSIONS+=(`echo $CI_TAG | sed -e 's/\(\w\+\.\w\+\)\..*$/\1/'`)
|
||||
fi
|
||||
|
||||
+125
-42
@@ -1,4 +1,9 @@
|
||||
version: 2
|
||||
version: 2.1
|
||||
|
||||
executors:
|
||||
vm:
|
||||
machine:
|
||||
enabled: true
|
||||
|
||||
references:
|
||||
set_environment_variables: &set_environment_variables
|
||||
@@ -10,21 +15,48 @@ references:
|
||||
echo 'export CI_BUILD_NUM=$CIRCLE_BUILD_NUM' >> ${BASH_ENV}
|
||||
echo 'export CI_TAG=$CIRCLE_TAG' >> ${BASH_ENV}
|
||||
echo 'export PUSH_ALL_VERSION_TAGS=true' >> ${BASH_ENV}
|
||||
docker_build_and_push: &docker_build_and_push
|
||||
echo 'export GOPROXY=https://proxy.golang.org' >> ${BASH_ENV}
|
||||
echo 'export GO111MODULE=on' >> ${BASH_ENV}
|
||||
|
||||
install_k8s: &install_k8s
|
||||
run:
|
||||
name: Docker login, build, and push
|
||||
name: Install K8s
|
||||
command: |
|
||||
docker-pull -f .circleci/build.config
|
||||
docker-build -f .circleci/build.config
|
||||
if [[ -n $CIRCLE_TAG ]]; then
|
||||
export ADDITIONAL_DOCKER_TAG_VERSIONS=(`echo $CIRCLE_TAG | sed -e 's/\(\w\+\)\..*$/\1/'`)
|
||||
fi
|
||||
if [[ -z $CIRCLE_PR_NUMBER ]]; then
|
||||
docker login quay.io -u="reactiveops+circleci" -p="${quay_token}"
|
||||
docker-push -f .circleci/build.config
|
||||
else
|
||||
echo "Skipping docker push for forked PR"
|
||||
fi
|
||||
sudo apt-get update
|
||||
echo "Installing git and jq"
|
||||
sudo apt-get install -yqq jq git
|
||||
|
||||
echo "Installing KIND"
|
||||
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.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.15.11
|
||||
docker ps -a
|
||||
|
||||
kubectl version
|
||||
|
||||
echo "Installing Helm"
|
||||
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
|
||||
chmod 700 get_helm.sh
|
||||
./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 0.16.1 --set "installCRDs=true" --wait
|
||||
echo "Install cert-manager successful"
|
||||
|
||||
# Test scripts
|
||||
update_coverage: &update_coverage
|
||||
@@ -32,108 +64,159 @@ references:
|
||||
name: Update Coverage
|
||||
command: |
|
||||
if [[ -z $CIRCLE_PR_NUMBER ]]; then
|
||||
go test ./pkg/... -coverprofile=coverage.txt -covermode=count
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
else
|
||||
echo "Skipping coverage for forked PR"
|
||||
fi
|
||||
test_dashboard: &test_dashboard
|
||||
test_binary_dashboard: &test_binary_dashboard
|
||||
run:
|
||||
name: Test Dashboard
|
||||
command: |
|
||||
go run main.go --dashboard --dashboard-port 3000 --audit-path ./examples &
|
||||
sleep 5
|
||||
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
|
||||
curl -f http://localhost:3000/favicon.ico > /dev/null
|
||||
curl -f http://localhost:3000/static/css/main.css > /dev/null
|
||||
curl -f http://localhost:3000/results.json > /dev/null
|
||||
curl -f http://localhost:3000/details/security > /dev/null
|
||||
test_k8s: &test_k8s
|
||||
run:
|
||||
name: Test Kubernetes Deployments
|
||||
command: |
|
||||
if [[ -z $CIRCLE_PR_NUMBER ]]; then
|
||||
./test/webhook_test.sh
|
||||
./test/kube_dashboard_test.sh
|
||||
else
|
||||
echo "Skipping Kubernetes tests for forked PR"
|
||||
fi
|
||||
|
||||
# Release scripts
|
||||
install_goreleaser: &install_goreleaser
|
||||
run:
|
||||
name: Install GoReleaser
|
||||
command: |
|
||||
curl -fsSLo goreleaser.deb https://github.com/goreleaser/goreleaser/releases/download/v0.94.0/goreleaser_amd64.deb
|
||||
echo "8dbad6683d6fc9367e637e6eed8e01a0d63c9660 goreleaser.deb" | sha1sum -c
|
||||
curl -fsSLo goreleaser.deb https://github.com/goreleaser/goreleaser/releases/download/v0.131.1/goreleaser_amd64.deb
|
||||
echo "640790dcbfa864f26de4c26c2d491f293a64525c8c6641c5bbdec7136b38977e 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: |
|
||||
git clone --branch polaris-latest https://github.com/reactiveops/charts
|
||||
mkdir deploy
|
||||
helm template ./charts/stable/polaris --name polaris --namespace polaris --set templateOnly=true > deploy/dashboard.yaml
|
||||
helm template ./charts/stable/polaris --name polaris --namespace polaris --set templateOnly=true --set webhook.enable=true --set dashboard.enable=false > deploy/webhook.yaml
|
||||
upload_url=$(curl --silent https://api.github.com/repos/reactiveops/polaris/releases/latest | grep upload_url)
|
||||
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"
|
||||
rm -rf ./charts
|
||||
rm -rf ./deploy
|
||||
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: quay.io/reactiveops/ci-images:v8.0-stretch
|
||||
- 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:
|
||||
working_directory: /go/src/github.com/reactiveops/polaris/
|
||||
docker:
|
||||
- image: circleci/golang:1.12
|
||||
|
||||
test_k8s:
|
||||
working_directory: ~/polaris
|
||||
resource_class: medium
|
||||
executor: vm
|
||||
steps:
|
||||
- checkout
|
||||
- *install_k8s
|
||||
- *test_k8s
|
||||
|
||||
test:
|
||||
working_directory: /go/src/github.com/fairwindsops/polaris/
|
||||
docker:
|
||||
- image: circleci/golang:1.13
|
||||
steps:
|
||||
- checkout
|
||||
- *set_environment_variables
|
||||
- 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 ./pkg/... -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
|
||||
- *update_coverage
|
||||
- *test_dashboard
|
||||
- *test_binary_dashboard
|
||||
|
||||
release_binary:
|
||||
working_directory: /go/src/github.com/reactiveops/polaris/
|
||||
working_directory: /go/src/github.com/fairwindsops/polaris/
|
||||
docker:
|
||||
- image: circleci/golang:1.12
|
||||
- image: circleci/golang:1.13
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- *set_environment_variables
|
||||
- *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/reactiveops/polaris/
|
||||
working_directory: /go/src/github.com/fairwindsops/polaris/
|
||||
docker:
|
||||
- image: quay.io/reactiveops/ci-images:v8.0-stretch
|
||||
- image: quay.io/reactiveops/ci-images:v11.0-stretch
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- *set_environment_variables
|
||||
- *docker_build_and_push
|
||||
- *release_deploy_configs
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
|
||||
build:
|
||||
jobs:
|
||||
- test
|
||||
- build:
|
||||
requires:
|
||||
- test
|
||||
- push:
|
||||
context: org-global
|
||||
# Allow using testing tags for testing circle test + build steps
|
||||
requires:
|
||||
- build
|
||||
filters:
|
||||
tags:
|
||||
only: /^testing-.*/
|
||||
branches:
|
||||
ignore: /pull\/[0-9]+/
|
||||
- test_k8s:
|
||||
requires:
|
||||
- push
|
||||
filters:
|
||||
branches:
|
||||
ignore: /pull\/[0-9]+/
|
||||
|
||||
release:
|
||||
jobs:
|
||||
- release_binary:
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
deploy
|
||||
examples
|
||||
.gitignore
|
||||
.git/*
|
||||
Dockerfile
|
||||
|
||||
@@ -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
|
||||
|
||||
-->
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Other
|
||||
about: For misc. tasks like research or continued conversation
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# This file is generated from FairwindsOps/documentation-template
|
||||
# DO NOT EDIT MANUALLY
|
||||
|
||||
name: Build Website
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./docs-md
|
||||
env:
|
||||
CI: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- name: Build site
|
||||
run: npm run build
|
||||
- name: Check links
|
||||
run: npm run check-links
|
||||
- name: Push changes
|
||||
run: |
|
||||
username="GitHub Actions"
|
||||
git config user.email "opensource@fairwinds.com"
|
||||
git config user.name $username
|
||||
HAS_CHANGE=$(git diff .)
|
||||
if [ -n "${HAS_CHANGE}" ]; then
|
||||
if [ "$(git log -1 --pretty=format:'%an')" == $username ]; then
|
||||
echo "Build created a diff, but the last commit was a build."
|
||||
exit 1
|
||||
fi
|
||||
git add docs/
|
||||
git commit -m "[CI] rebuild website"
|
||||
git push
|
||||
fi
|
||||
@@ -6,6 +6,7 @@
|
||||
*.dylib
|
||||
polaris
|
||||
|
||||
!cmd/polaris
|
||||
!deploy/helm/polaris
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
@@ -20,3 +21,8 @@ main
|
||||
|
||||
*-packr.go
|
||||
dist
|
||||
.vscode
|
||||
|
||||
*-test.yaml
|
||||
|
||||
node_modules
|
||||
|
||||
+22
-21
@@ -1,29 +1,30 @@
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
binary: polaris
|
||||
archive:
|
||||
replacements:
|
||||
darwin: Darwin
|
||||
linux: Linux
|
||||
windows: Windows
|
||||
386: i386
|
||||
amd64: x86_64
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
snapshot:
|
||||
name_template: "{{ .Tag }}-next"
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
brew:
|
||||
github:
|
||||
owner: reactiveops
|
||||
name: homebrew-tap
|
||||
folder: Formula
|
||||
description: Open Source Best Practices for Kubernetes
|
||||
test: |
|
||||
system "#{bin}/polaris --version"
|
||||
builds:
|
||||
- id: watcher
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
- GO111MODULE=on
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
- 386
|
||||
goarm:
|
||||
- 6
|
||||
- 7
|
||||
brews:
|
||||
- name: polaris
|
||||
github:
|
||||
owner: FairwindsOps
|
||||
name: homebrew-tap
|
||||
folder: Formula
|
||||
description: Open Source Best Practices for Kubernetes
|
||||
test: |
|
||||
system "#{bin}/polaris version"
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# 0.2.0
|
||||
* Added `--output-format` flag for better CI/CD support
|
||||
* Added `--display-name` flag
|
||||
* Added support for StatefulSets
|
||||
* Show error message if no kubeconfig is set
|
||||
|
||||
# 0.1.5
|
||||
* [Fix](https://github.com/reactiveops/polaris/issues/125): ignore limits/requests for initContainers
|
||||
* [Fix](https://github.com/reactiveops/polaris/issues/132): support custom base path
|
||||
|
||||
# 0.1.4
|
||||
* [Fix](https://github.com/reactiveops/polaris/issues/116): details pages getting template errors
|
||||
* [Fix](https://github.com/reactiveops/polaris/issues/114): support all auth providers
|
||||
* [Fix](https://github.com/reactiveops/polaris/issues/112): Ignore readiness probe for initContainers
|
||||
|
||||
# 0.1.3
|
||||
* [Fix](https://github.com/reactiveops/polaris/issues/109): dashboard not updating when running persistently
|
||||
|
||||
# 0.1.2
|
||||
* Stored all third-party assets (e.g. Charts.js) to local files to support offline dashboard viewing
|
||||
* Fix: custom configs in `ConfigMap` not respected
|
||||
|
||||
# 0.1.1
|
||||
* [Fix](https://github.com/reactiveops/polaris/issues/93): missing `config.yaml` and dashboard assets in binary releases
|
||||
* Added some tests and better error handling
|
||||
|
||||
# 0.1.0
|
||||
* Dashboard fully functional
|
||||
* Validating webhook functional, but still considered beta
|
||||
* Checks:
|
||||
* Health
|
||||
* readiness probe missing
|
||||
* liveness probe missing
|
||||
* Images
|
||||
* tag not specified
|
||||
* pull policy not always
|
||||
* Networking
|
||||
* host network set
|
||||
* host port set
|
||||
* Resources
|
||||
* cpu/memory requests missing
|
||||
* cpu/memory limits missing
|
||||
* cpu/memory ranges exceeded
|
||||
* Security
|
||||
* security capabilities
|
||||
* host IPC set
|
||||
* host PID set
|
||||
* not read-only fs
|
||||
* privilege escalation allowed
|
||||
* run as root allowed
|
||||
* run as privileged
|
||||
+1
-1
@@ -1 +1 @@
|
||||
* @bobby-brennan @endzyme @kimschles @robscott
|
||||
* @rbren @makoscafee @jordandoig @baderbuddy
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
@@ -1,92 +0,0 @@
|
||||
# Contributing
|
||||
|
||||
Issues, whether bugs, tasks, or feature requests are essential for keeping Polaris great. We believe it should be as easy as possible to contribute changes that get things working in your environment. There are a few guidelines that we need contributors to follow so that we can keep on top of things.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project adheres to a [code of conduct](CODE_OF_CONDUCT.md). Please review this document before contributing to this project.
|
||||
|
||||
## Sign the CLA
|
||||
Before you can contribute, you will need to sign the [Contributor License Agreement](https://cla-assistant.io/reactiveops/polaris).
|
||||
|
||||
## Project Structure
|
||||
|
||||
Polaris is built on top of [controller-runtime](https://github.com/kubernetes-sigs/controller-runtime). It can run in 3 different modes, a dashboard, a webhook, or a reporter that prints or exports validation results. All of these modes make use of the shared `validator` and `config` packages. Adding new validations is possible by only making additions to those packages.
|
||||
|
||||
## Getting Started
|
||||
|
||||
We label issues with the ["good first issue" tag](https://github.com/reactiveops/polaris/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) if we believe they'll be a good starting point for new contributors. If you're interested in working on an issue, please start a conversation on that issue, and we can help answer any questions as they come up.
|
||||
|
||||
## Setting Up Your Development Environment
|
||||
### Prerequisites
|
||||
* A properly configured Golang environment with Go 1.11 or higher
|
||||
* If you want to see the local changes you make on a Polaris dashboard, you will need access to a Kubernetes cluster defined in `~/.kube/config`
|
||||
|
||||
### Installation
|
||||
* Install the project with `go get github.com/reactiveops/polaris`
|
||||
* Change into the polaris directory which is installed at `$GOPATH/src/github.com/reactiveops/polaris`
|
||||
* See the dashboard with `go run main.go --dashboard`, then open http://localhost:8080/
|
||||
* See the audit data `go run main.go --audit`. This command shows the audit information on the command line.
|
||||
|
||||
## Running Tests
|
||||
|
||||
The following commands are all required to pass as part of Polaris testing:
|
||||
|
||||
```
|
||||
go list ./... | grep -v vendor | xargs golint -set_exit_status
|
||||
go list ./... | grep -v vendor | xargs go vet
|
||||
go test ./pkg/... -v -coverprofile cover.out
|
||||
```
|
||||
|
||||
## Creating a New Issue
|
||||
|
||||
If you've encountered an issue that is not already reported, please create an issue that contains the following:
|
||||
|
||||
- Clear description of the issue
|
||||
- Steps to reproduce it
|
||||
- Appropriate labels
|
||||
|
||||
## Creating a Pull Request
|
||||
|
||||
Each new pull request should:
|
||||
|
||||
- Reference any related issues
|
||||
- Add tests that show the issues have been solved
|
||||
- Pass existing tests and linting
|
||||
- Contain a clear indication of if they're ready for review or a work in progress
|
||||
- Be up to date and/or rebased on the master branch
|
||||
|
||||
## Creating a new release
|
||||
|
||||
### Minor/patch releases
|
||||
Minor and patch releases only need to change this repo. The Helm chart and deploy scripts
|
||||
will automatically pull in the latest changes.
|
||||
|
||||
To deploy a minor or patch release, follow steps 2 and 3 from "Major releases" below.
|
||||
|
||||
### Major releases
|
||||
Major releases need to change both this repository and the
|
||||
[Helm chart repo](https://github.com/reactiveops/charts/).
|
||||
|
||||
The steps are:
|
||||
1. Create a PR in the [charts repo](https://github.com/reactiveops/charts/)
|
||||
1. Use a branch named `polaris-latest`
|
||||
2. Bump the version number in:
|
||||
1. stable/polaris/README.md
|
||||
2. stable/polaris/Chart.yaml
|
||||
3. stable/polaris/values.yaml
|
||||
3. **Don't merge yet!**
|
||||
2. 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
|
||||
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. Wait for CircleCI to finish the build for the tag, which will:
|
||||
1. Create the proper image tag in quay.io
|
||||
2. Add an entry to the releases page on GitHub
|
||||
4. Merge the PR for the charts repo you created in step 1.
|
||||
|
||||
+16
-6
@@ -1,17 +1,27 @@
|
||||
FROM golang:1.12.4 AS build-env
|
||||
WORKDIR /go/src/github.com/reactiveops/polaris/
|
||||
FROM golang:1.13 AS build-env
|
||||
WORKDIR /go/src/github.com/fairwindsops/polaris/
|
||||
|
||||
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 go get -u github.com/gobuffalo/packr/v2/packr2
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 packr2 build -a -o polaris *.go
|
||||
RUN packr2 build -a -o polaris *.go
|
||||
|
||||
FROM alpine:3.9
|
||||
FROM alpine:3.10
|
||||
WORKDIR /usr/local/bin
|
||||
RUN apk --no-cache add ca-certificates
|
||||
|
||||
RUN addgroup -S polaris && adduser -u 1200 -S polaris -G polaris
|
||||
USER 1200
|
||||
COPY --from=build-env /go/src/github.com/reactiveops/polaris/polaris .
|
||||
COPY --from=build-env /go/src/github.com/fairwindsops/polaris/polaris .
|
||||
|
||||
WORKDIR /opt/app
|
||||
|
||||
|
||||
Generated
-512
@@ -1,512 +0,0 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "cloud.google.com/go"
|
||||
packages = ["compute/metadata"]
|
||||
revision = "775730d6e48254a2430366162cf6298e5368833c"
|
||||
version = "v0.39.0"
|
||||
|
||||
[[projects]]
|
||||
name = "contrib.go.opencensus.io/exporter/ocagent"
|
||||
packages = ["."]
|
||||
revision = "dcb33c7f3b7cfe67e8a2cea10207ede1b7c40764"
|
||||
version = "v0.4.12"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/Azure/go-autorest"
|
||||
packages = ["autorest","autorest/adal","autorest/azure","autorest/date","logger","tracing"]
|
||||
revision = "fe1ebaab71ae2a2ab8a55f62ebe54cffd842acc2"
|
||||
version = "v12.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/appscode/jsonpatch"
|
||||
packages = ["."]
|
||||
revision = "7c0e3b262f30165a8ec3d0b4c6059fd92703bfb2"
|
||||
version = "1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/beorn7/perks"
|
||||
packages = ["quantile"]
|
||||
revision = "4b2b341e8d7715fae06375aa633dbb6e91b3fb46"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/census-instrumentation/opencensus-proto"
|
||||
packages = ["gen-go/agent/common/v1","gen-go/agent/metrics/v1","gen-go/agent/trace/v1","gen-go/metrics/v1","gen-go/resource/v1","gen-go/trace/v1"]
|
||||
revision = "a105b96453fe85139acc07b68de48f2cbdd71249"
|
||||
version = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/dgrijalva/jwt-go"
|
||||
packages = ["."]
|
||||
revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
|
||||
version = "v3.2.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/evanphx/json-patch"
|
||||
packages = ["."]
|
||||
revision = "5858425f75500d40c52783dce87d085a483ce135"
|
||||
version = "v4.2.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-logr/logr"
|
||||
packages = ["."]
|
||||
revision = "9fb12b3b21c5415d16ac18dc5cd42c1cfdd40c4e"
|
||||
version = "v0.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-logr/zapr"
|
||||
packages = ["."]
|
||||
revision = "03f06a783fbb7dfaf3f629c7825480e43a7105e6"
|
||||
version = "v0.1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gobuffalo/envy"
|
||||
packages = ["."]
|
||||
revision = "043cb4b8af871b49563291e32c66bb84378a60ac"
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gobuffalo/genny"
|
||||
packages = ["."]
|
||||
revision = "05dc5921e98daa5d406f90c2844ff163cb1e1c4e"
|
||||
version = "v0.1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gobuffalo/gogen"
|
||||
packages = [".","goimports","gomods"]
|
||||
revision = "5482e6ef5d999f8cfa9b038a53953c9b4ee090af"
|
||||
version = "v0.1.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/gobuffalo/logger"
|
||||
packages = ["."]
|
||||
revision = "86e12af44bc273e0063fad5b6ad588890b8cfe6b"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gobuffalo/mapi"
|
||||
packages = ["."]
|
||||
revision = "0bb5e840be332d4280e40f2e6c50777c615bbac5"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gobuffalo/packd"
|
||||
packages = ["."]
|
||||
revision = "9efbb667f2024a9370cadda45a57a0657c88a6fb"
|
||||
version = "v0.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gobuffalo/packr"
|
||||
packages = ["v2","v2/file","v2/file/resolver","v2/file/resolver/encoding/hex","v2/jam/parser","v2/plog"]
|
||||
revision = "cda4ac25577350dac682c8715dc6659327232596"
|
||||
version = "v2.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/gobuffalo/syncx"
|
||||
packages = ["."]
|
||||
revision = "33c29581e754bd354236e977dfe426e55331c45d"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gogo/protobuf"
|
||||
packages = ["proto","sortkeys"]
|
||||
revision = "ba06b47c162d49f2af050fb4c75bcbc86a159d5c"
|
||||
version = "v1.2.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/golang/groupcache"
|
||||
packages = ["lru"]
|
||||
revision = "5b532d6fd5efaf7fa130d4e859a2fde0fc3a9e1b"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["jsonpb","proto","protoc-gen-go/descriptor","protoc-gen-go/generator","protoc-gen-go/generator/internal/remap","protoc-gen-go/plugin","ptypes","ptypes/any","ptypes/duration","ptypes/struct","ptypes/timestamp","ptypes/wrappers"]
|
||||
revision = "b5d812f8a3706043e23a9cd5babf2e5423744d30"
|
||||
version = "v1.3.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/google/btree"
|
||||
packages = ["."]
|
||||
revision = "4030bb1f1f0c35b30ca7009e9ebd06849dd45306"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/google/gofuzz"
|
||||
packages = ["."]
|
||||
revision = "f140a6486e521aad38f5917de355cbf147cc0496"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/google/uuid"
|
||||
packages = ["."]
|
||||
revision = "0cd6bf5da1e1c83f8b45653022c74f71af0538a4"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/googleapis/gnostic"
|
||||
packages = ["OpenAPIv2","compiler","extensions"]
|
||||
revision = "7c663266750e7d82587642f65e60bc4083f1f84e"
|
||||
version = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/gophercloud/gophercloud"
|
||||
packages = [".","openstack","openstack/identity/v2/tenants","openstack/identity/v2/tokens","openstack/identity/v3/tokens","openstack/utils","pagination"]
|
||||
revision = "b3a23cc94cc51857a508733a0bd3d6ef0bfc16d9"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/mux"
|
||||
packages = ["."]
|
||||
revision = "ed099d42384823742bba0bf9a72b53b55c9e2e38"
|
||||
version = "v1.7.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/gregjones/httpcache"
|
||||
packages = [".","diskcache"]
|
||||
revision = "3befbb6ad0cc97d4c25d851e9528915809e1a22f"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/grpc-ecosystem/grpc-gateway"
|
||||
packages = ["internal","runtime","utilities"]
|
||||
revision = "8fd5fd9d19ce68183a6b0934519dfe7fe6269612"
|
||||
version = "v1.9.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/hashicorp/golang-lru"
|
||||
packages = [".","simplelru"]
|
||||
revision = "7087cb70de9f7a8bc0a10c375cb0d2280a8edf9c"
|
||||
version = "v0.5.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/imdario/mergo"
|
||||
packages = ["."]
|
||||
revision = "7c29201646fa3de8506f701213473dd407f19646"
|
||||
version = "v0.3.7"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/joho/godotenv"
|
||||
packages = ["."]
|
||||
revision = "23d116af351c84513e1946b527c88823e476be13"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/json-iterator/go"
|
||||
packages = ["."]
|
||||
revision = "0ff49de124c6f76f8494e194af75bde0f1a49a29"
|
||||
version = "v1.1.6"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/karrick/godirwalk"
|
||||
packages = ["."]
|
||||
revision = "5e617d9cfec6f870e63b168e9a2fb7c490a1c108"
|
||||
version = "v1.10.3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/konsorten/go-windows-terminal-sequences"
|
||||
packages = ["."]
|
||||
revision = "f55edac94c9bbba5d6182a4be46d86a2c9b5b50e"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/markbates/oncer"
|
||||
packages = ["."]
|
||||
revision = "bf2de49a0be218916e69a11d22866e6cd0a560f2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/markbates/safe"
|
||||
packages = ["."]
|
||||
revision = "6fea05a5732486546a4836b7a1d596c5ec687b98"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
packages = ["pbutil"]
|
||||
revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/modern-go/concurrent"
|
||||
packages = ["."]
|
||||
revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
||||
version = "1.0.3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/modern-go/reflect2"
|
||||
packages = ["."]
|
||||
revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd"
|
||||
version = "1.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pborman/uuid"
|
||||
packages = ["."]
|
||||
revision = "adf5a7427709b9deb95d29d3fa8a2bf9cfd388f1"
|
||||
version = "v1.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/petar/GoLLRB"
|
||||
packages = ["llrb"]
|
||||
revision = "33fb24c13b99c46c93183c291836c573ac382536"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/peterbourgon/diskv"
|
||||
packages = ["."]
|
||||
revision = "0be1b92a6df0e4f5cb0a5d15fb7f643d0ad93ce6"
|
||||
version = "v3.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
|
||||
version = "v0.8.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pmezard/go-difflib"
|
||||
packages = ["difflib"]
|
||||
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = ["prometheus","prometheus/internal","prometheus/promhttp"]
|
||||
revision = "50c4339db732beb2165735d2cde0bff78eb3c5a5"
|
||||
version = "v0.9.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
revision = "fd36f4220a901265f90734c3183c5f0c91daa0b8"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/prometheus/common"
|
||||
packages = ["expfmt","internal/bitbucket.org/ww/goautoneg","model"]
|
||||
revision = "1ba88736f028e37bc17328369e94a537ae9e0234"
|
||||
version = "v0.4.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [".","internal/fs"]
|
||||
revision = "9935e8e0588d26307d1d4a07bed7bd47271b6bbd"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/rogpeppe/go-internal"
|
||||
packages = ["modfile","module","semver"]
|
||||
revision = "438578804ca6f31be148c27683afc419ce47c06e"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = ["."]
|
||||
revision = "839c75faf7f98a33d445d181f3018b5c3409a45e"
|
||||
version = "v1.4.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
revision = "298182f68c66c05229eb03ac171abe6e309ee79a"
|
||||
version = "v1.0.3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = ["assert"]
|
||||
revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "gitlab.com/golang-commonmark/html"
|
||||
packages = ["."]
|
||||
revision = "cfaf75183c4a5f0e44e3d51ece1065accafdd2b3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "gitlab.com/golang-commonmark/linkify"
|
||||
packages = ["."]
|
||||
revision = "c22b7bdb117955ff2cc0e3724083d35e3419d71e"
|
||||
|
||||
[[projects]]
|
||||
name = "gitlab.com/golang-commonmark/markdown"
|
||||
packages = ["."]
|
||||
revision = "772775880e1fbf39a7804149ed11c0f714ec89fe"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "gitlab.com/golang-commonmark/mdurl"
|
||||
packages = ["."]
|
||||
revision = "e5bce34c34f29ecf232fec34f3982e55533ec14e"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "gitlab.com/golang-commonmark/puny"
|
||||
packages = ["."]
|
||||
revision = "2cd490539afe7c6fc0eda6c59ef88fa93a00ea0d"
|
||||
|
||||
[[projects]]
|
||||
name = "go.opencensus.io"
|
||||
packages = [".","internal","internal/tagencoding","metric/metricdata","metric/metricproducer","plugin/ocgrpc","plugin/ochttp","plugin/ochttp/propagation/b3","plugin/ochttp/propagation/tracecontext","resource","stats","stats/internal","stats/view","tag","trace","trace/internal","trace/propagation","trace/tracestate"]
|
||||
revision = "43463a80402d8447b7fce0d2c58edf1687ff0b58"
|
||||
version = "v0.19.3"
|
||||
|
||||
[[projects]]
|
||||
name = "go.uber.org/atomic"
|
||||
packages = ["."]
|
||||
revision = "df976f2515e274675050de7b3f42545de80594fd"
|
||||
version = "v1.4.0"
|
||||
|
||||
[[projects]]
|
||||
name = "go.uber.org/multierr"
|
||||
packages = ["."]
|
||||
revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "go.uber.org/zap"
|
||||
packages = [".","buffer","internal/bufferpool","internal/color","internal/exit","zapcore"]
|
||||
revision = "27376062155ad36be76b0f12cf1572a221d3a48c"
|
||||
version = "v1.10.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
revision = "22d7a77e9e5f409e934ed268692e56707cd169e5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
packages = ["context","context/ctxhttp","http/httpguts","http2","http2/hpack","idna","internal/timeseries","trace"]
|
||||
revision = "3ec19112720433827bbce8be9342797f5a6aaaf9"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [".","google","internal","jws","jwt"]
|
||||
revision = "950ef44c6e079baf075030377d90bf0c7e4b7b7a"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sync"
|
||||
packages = ["semaphore"]
|
||||
revision = "112230192c580c3556b8cee6403af37a4fc5f28c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix","windows"]
|
||||
revision = "ad400b1274690a55531a013560dc08706088f82b"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/text"
|
||||
packages = ["collate","collate/build","internal/colltab","internal/gen","internal/language","internal/language/compact","internal/tag","internal/triegen","internal/ucd","language","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
|
||||
revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
|
||||
version = "v0.3.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/time"
|
||||
packages = ["rate"]
|
||||
revision = "9d24e82272b4f38b78bc8cff74fa936d31ccd8ef"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/tools"
|
||||
packages = ["go/ast/astutil","go/gcexportdata","go/internal/gcimporter","go/internal/packagesdriver","go/packages","go/types/typeutil","imports","internal/fastwalk","internal/gopathwalk","internal/module","internal/semver"]
|
||||
revision = "d88f79806bbd013f54a668506864ce559edf6f0a"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/api"
|
||||
packages = ["support/bundler"]
|
||||
revision = "721295fe20d585ce7e948146f82188429d14da33"
|
||||
version = "v0.5.0"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/appengine"
|
||||
packages = [".","internal","internal/app_identity","internal/base","internal/datastore","internal/log","internal/modules","internal/remote_api","internal/urlfetch","urlfetch"]
|
||||
revision = "4c25cacc810c02874000e4f7071286a8e96b2515"
|
||||
version = "v1.6.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = ["googleapis/api/httpbody","googleapis/rpc/status","protobuf/field_mask"]
|
||||
revision = "bb713bdc0e5239f2b68e560efbe1c701a6fe78f9"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [".","balancer","balancer/base","balancer/roundrobin","binarylog/grpc_binarylog_v1","codes","connectivity","credentials","credentials/internal","encoding","encoding/proto","grpclog","internal","internal/backoff","internal/balancerload","internal/binarylog","internal/channelz","internal/envconfig","internal/grpcrand","internal/grpcsync","internal/syscall","internal/transport","keepalive","metadata","naming","peer","resolver","resolver/dns","resolver/passthrough","stats","status","tap"]
|
||||
revision = "25c4f928eaa6d96443009bd842389fb4fa48664e"
|
||||
version = "v1.20.1"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/inf.v0"
|
||||
packages = ["."]
|
||||
revision = "d2d2541c53f18d2a059457998ce2876cc8e67cbf"
|
||||
version = "v0.9.1"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
revision = "51d6538a90f86fe93ac480b35f37b2be17fef232"
|
||||
version = "v2.2.2"
|
||||
|
||||
[[projects]]
|
||||
name = "k8s.io/api"
|
||||
packages = ["admission/v1beta1","admissionregistration/v1alpha1","admissionregistration/v1beta1","apps/v1","apps/v1beta1","apps/v1beta2","auditregistration/v1alpha1","authentication/v1","authentication/v1beta1","authorization/v1","authorization/v1beta1","autoscaling/v1","autoscaling/v2beta1","autoscaling/v2beta2","batch/v1","batch/v1beta1","batch/v2alpha1","certificates/v1beta1","coordination/v1beta1","core/v1","events/v1beta1","extensions/v1beta1","networking/v1","policy/v1beta1","rbac/v1","rbac/v1alpha1","rbac/v1beta1","scheduling/v1alpha1","scheduling/v1beta1","settings/v1alpha1","storage/v1","storage/v1alpha1","storage/v1beta1"]
|
||||
revision = "05914d821849570fba9eacfb29466f2d8d3cd229"
|
||||
version = "kubernetes-1.13.1"
|
||||
|
||||
[[projects]]
|
||||
name = "k8s.io/apimachinery"
|
||||
packages = ["pkg/api/errors","pkg/api/meta","pkg/api/resource","pkg/apis/meta/internalversion","pkg/apis/meta/v1","pkg/apis/meta/v1/unstructured","pkg/apis/meta/v1beta1","pkg/conversion","pkg/conversion/queryparams","pkg/fields","pkg/labels","pkg/runtime","pkg/runtime/schema","pkg/runtime/serializer","pkg/runtime/serializer/json","pkg/runtime/serializer/protobuf","pkg/runtime/serializer/recognizer","pkg/runtime/serializer/streaming","pkg/runtime/serializer/versioning","pkg/selection","pkg/types","pkg/util/cache","pkg/util/clock","pkg/util/diff","pkg/util/errors","pkg/util/framer","pkg/util/intstr","pkg/util/json","pkg/util/mergepatch","pkg/util/naming","pkg/util/net","pkg/util/runtime","pkg/util/sets","pkg/util/strategicpatch","pkg/util/uuid","pkg/util/validation","pkg/util/validation/field","pkg/util/wait","pkg/util/yaml","pkg/version","pkg/watch","third_party/forked/golang/json","third_party/forked/golang/reflect"]
|
||||
revision = "2b1284ed4c93a43499e781493253e2ac5959c4fd"
|
||||
version = "kubernetes-1.13.0"
|
||||
|
||||
[[projects]]
|
||||
name = "k8s.io/client-go"
|
||||
packages = ["discovery","discovery/fake","dynamic","kubernetes","kubernetes/fake","kubernetes/scheme","kubernetes/typed/admissionregistration/v1alpha1","kubernetes/typed/admissionregistration/v1alpha1/fake","kubernetes/typed/admissionregistration/v1beta1","kubernetes/typed/admissionregistration/v1beta1/fake","kubernetes/typed/apps/v1","kubernetes/typed/apps/v1/fake","kubernetes/typed/apps/v1beta1","kubernetes/typed/apps/v1beta1/fake","kubernetes/typed/apps/v1beta2","kubernetes/typed/apps/v1beta2/fake","kubernetes/typed/auditregistration/v1alpha1","kubernetes/typed/auditregistration/v1alpha1/fake","kubernetes/typed/authentication/v1","kubernetes/typed/authentication/v1/fake","kubernetes/typed/authentication/v1beta1","kubernetes/typed/authentication/v1beta1/fake","kubernetes/typed/authorization/v1","kubernetes/typed/authorization/v1/fake","kubernetes/typed/authorization/v1beta1","kubernetes/typed/authorization/v1beta1/fake","kubernetes/typed/autoscaling/v1","kubernetes/typed/autoscaling/v1/fake","kubernetes/typed/autoscaling/v2beta1","kubernetes/typed/autoscaling/v2beta1/fake","kubernetes/typed/autoscaling/v2beta2","kubernetes/typed/autoscaling/v2beta2/fake","kubernetes/typed/batch/v1","kubernetes/typed/batch/v1/fake","kubernetes/typed/batch/v1beta1","kubernetes/typed/batch/v1beta1/fake","kubernetes/typed/batch/v2alpha1","kubernetes/typed/batch/v2alpha1/fake","kubernetes/typed/certificates/v1beta1","kubernetes/typed/certificates/v1beta1/fake","kubernetes/typed/coordination/v1beta1","kubernetes/typed/coordination/v1beta1/fake","kubernetes/typed/core/v1","kubernetes/typed/core/v1/fake","kubernetes/typed/events/v1beta1","kubernetes/typed/events/v1beta1/fake","kubernetes/typed/extensions/v1beta1","kubernetes/typed/extensions/v1beta1/fake","kubernetes/typed/networking/v1","kubernetes/typed/networking/v1/fake","kubernetes/typed/policy/v1beta1","kubernetes/typed/policy/v1beta1/fake","kubernetes/typed/rbac/v1","kubernetes/typed/rbac/v1/fake","kubernetes/typed/rbac/v1alpha1","kubernetes/typed/rbac/v1alpha1/fake","kubernetes/typed/rbac/v1beta1","kubernetes/typed/rbac/v1beta1/fake","kubernetes/typed/scheduling/v1alpha1","kubernetes/typed/scheduling/v1alpha1/fake","kubernetes/typed/scheduling/v1beta1","kubernetes/typed/scheduling/v1beta1/fake","kubernetes/typed/settings/v1alpha1","kubernetes/typed/settings/v1alpha1/fake","kubernetes/typed/storage/v1","kubernetes/typed/storage/v1/fake","kubernetes/typed/storage/v1alpha1","kubernetes/typed/storage/v1alpha1/fake","kubernetes/typed/storage/v1beta1","kubernetes/typed/storage/v1beta1/fake","pkg/apis/clientauthentication","pkg/apis/clientauthentication/v1alpha1","pkg/apis/clientauthentication/v1beta1","pkg/version","plugin/pkg/client/auth","plugin/pkg/client/auth/azure","plugin/pkg/client/auth/exec","plugin/pkg/client/auth/gcp","plugin/pkg/client/auth/oidc","plugin/pkg/client/auth/openstack","rest","rest/watch","restmapper","testing","third_party/forked/golang/template","tools/auth","tools/cache","tools/clientcmd","tools/clientcmd/api","tools/clientcmd/api/latest","tools/clientcmd/api/v1","tools/leaderelection","tools/leaderelection/resourcelock","tools/metrics","tools/pager","tools/record","tools/reference","transport","util/buffer","util/cert","util/connrotation","util/flowcontrol","util/homedir","util/integer","util/jsonpath","util/retry","util/workqueue"]
|
||||
revision = "8d9ed539ba3134352c586810e749e58df4e94e4f"
|
||||
version = "kubernetes-1.13.1"
|
||||
|
||||
[[projects]]
|
||||
name = "k8s.io/klog"
|
||||
packages = ["."]
|
||||
revision = "e531227889390a39d9533dde61f590fe9f4b0035"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "k8s.io/kube-openapi"
|
||||
packages = ["pkg/util/proto"]
|
||||
revision = "a01b7d5d6c2258c80a4a10070f3dee9cd575d9c7"
|
||||
|
||||
[[projects]]
|
||||
name = "sigs.k8s.io/controller-runtime"
|
||||
packages = ["pkg/cache","pkg/cache/internal","pkg/client","pkg/client/apiutil","pkg/client/config","pkg/internal/recorder","pkg/leaderelection","pkg/manager","pkg/metrics","pkg/patch","pkg/recorder","pkg/runtime/inject","pkg/runtime/log","pkg/runtime/signals","pkg/webhook","pkg/webhook/admission","pkg/webhook/admission/builder","pkg/webhook/admission/types","pkg/webhook/internal/cert","pkg/webhook/internal/cert/generator","pkg/webhook/internal/cert/writer","pkg/webhook/internal/cert/writer/atomic","pkg/webhook/internal/metrics","pkg/webhook/types"]
|
||||
revision = "12d98582e72927b6cd0123e2b4e819f9341ce62c"
|
||||
version = "v0.1.10"
|
||||
|
||||
[[projects]]
|
||||
name = "sigs.k8s.io/yaml"
|
||||
packages = ["."]
|
||||
revision = "fd68e9863619f6ec2fdd8625fe1f02e7c877e480"
|
||||
version = "v1.1.0"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "205aba713edfc3b46886718dc86dbc24edc9e9758efd16724c2cdaa4256e6d50"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/stretchr/testify"
|
||||
version = "1.3.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/api"
|
||||
version = "kubernetes-1.13.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/apimachinery"
|
||||
version = "kubernetes-1.13.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/client-go"
|
||||
version = "kubernetes-1.13.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "sigs.k8s.io/controller-runtime"
|
||||
version = "0.1.10"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gobuffalo/packr"
|
||||
version = "2.2.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/mux"
|
||||
version = "1.7.1"
|
||||
|
||||
[[constraint]]
|
||||
revision = "772775880e1fbf39a7804149ed11c0f714ec89fe"
|
||||
name = "gitlab.com/golang-commonmark/markdown"
|
||||
|
||||
[[constraint]]
|
||||
revision = "v1.3.1"
|
||||
name = "github.com/golang/protobuf"
|
||||
@@ -186,7 +186,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2019 ReactiveOps
|
||||
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.
|
||||
|
||||
@@ -1,164 +1,58 @@
|
||||
<div align="center">
|
||||
<img src="/pkg/dashboard/assets/images/polaris-logo.png" alt="Polaris Logo" />
|
||||
<div align="center" class="no-border">
|
||||
<img src="https://polaris.docs.fairwinds.com/img/polaris-logo.png" alt="Polaris Logo">
|
||||
<br>
|
||||
|
||||
[![Version][version-image]][version-link] [![CircleCI][circleci-image]][circleci-link] [![Go Report Card][goreport-image]][goreport-link]
|
||||
<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=2.0.0&color=239922">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/FairwindsOps/polaris">
|
||||
<img src="https://goreportcard.com/badge/github.com/FairwindsOps/polaris">
|
||||
</a>
|
||||
<a href="https://circleci.com/gh/FairwindsOps/polaris.svg">
|
||||
<img src="https://circleci.com/gh/FairwindsOps/polaris.svg?style=svg">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
[version-image]: https://img.shields.io/static/v1.svg?label=Version&message=0.2.0&color=239922
|
||||
[version-link]: https://github.com/reactiveops/polaris
|
||||
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 a few different modes:
|
||||
|
||||
[goreport-image]: https://goreportcard.com/badge/github.com/reactiveops/polaris
|
||||
[goreport-link]: https://goreportcard.com/report/github.com/reactiveops/polaris
|
||||
Polaris can be run in three different modes:
|
||||
* 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.
|
||||
|
||||
[circleci-image]: https://circleci.com/gh/reactiveops/polaris.svg?style=svg
|
||||
[circleci-link]: https://circleci.com/gh/reactiveops/polaris.svg
|
||||
**Want to learn more?** Reach out on [the Slack channel](https://fairwindscommunity.slack.com/messages/polaris) ([request invite](https://join.slack.com/t/fairwindscommunity/shared_invite/zt-e3c6vj4l-3lIH6dvKqzWII5fSSFDi1g)), send an email to `opensource@fairwinds.com`, or join us for [office hours on Zoom](https://fairwindscommunity.slack.com/messages/office-hours)
|
||||
|
||||
Polaris helps keep your cluster healthy. It runs a variety of checks to ensure that Kubernetes deployments are configured using best practices that will avoid potential problems in the future. The project includes two primary components:
|
||||
|
||||
- A dashboard that provides an overview of how well current deployments are configured within a cluster.
|
||||
- An experimental validating webhook that can prevent any future deployments that do not live up to a configured standard.
|
||||
## Documentation
|
||||
Check out the [documentation at docs.fairwinds.com](https://polaris.docs.fairwinds.com)
|
||||
|
||||
**Want to learn more?** ReactiveOps holds [office hours on Zoom](https://zoom.us/j/242508205) the first Friday of every month, at 12pm Eastern. You can also reach out via email at `opensource@reactiveops.com`
|
||||
## Integration with Fairwinds Insights
|
||||
[Fairwinds Insights](https://www.fairwinds.com/insights?utm_campaign=Hosted%20Polaris%20&utm_source=polaris&utm_term=polaris&utm_content=polaris)
|
||||
is a platform for auditing Kubernetes clusters and enforcing policy. If you'd like to:
|
||||
* manage Polaris across a fleet of clusters
|
||||
* track findings over time
|
||||
* send results to services like Slack and Datadog
|
||||
* add additional checks from tools like
|
||||
[Trivy](https://github.com/aquasecurity/trivy),
|
||||
[Goldilocks](https://github.com/FairwindsOps/goldilocks/), and
|
||||
[OPA](https://www.openpolicyagent.org)
|
||||
|
||||
## Quickstart
|
||||
|
||||
```
|
||||
kubectl apply -f https://github.com/reactiveops/polaris/releases/latest/download/dashboard.yaml
|
||||
kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80
|
||||
```
|
||||
With the port forwarding in place, you can open http://localhost:8080 in your browser to view the dashboard.
|
||||
|
||||
## Dashboard
|
||||
|
||||
The Polaris dashboard is a way to get a simple visual overview of the current state of your Kubernetes deployments as well as a roadmap for what can be improved. The dashboard provides a cluster wide overview as well as breaking out results by category, namespace, and deployment.
|
||||
|
||||
<p align="center">
|
||||
<img src="/dashboard-screenshot.png" alt="Polaris Dashboard" />
|
||||
</p>
|
||||
|
||||
Our default standards in Polaris are rather high, so don’t be surprised if your score is lower than you might expect. A key goal for Polaris was to set a high standard and aim for great configuration by default. If the defaults we’ve included are too strict, it’s easy to adjust the configuration as part of the deployment configuration to better suit your workloads.
|
||||
|
||||
## Webhook
|
||||
|
||||
Polaris includes experimental support for an optional validating webhook. This accepts the same configuration as the dashboard, and can run the same validations. This webhook will reject any deployments that trigger a validation error. This is indicative of the greater goal of Polaris, not just to encourage better configuration through dashboard visibility, but to actually enforce it with this webhook. *Although we are working towards greater stability and better test coverage, we do not currently consider this webhook component production ready.*
|
||||
|
||||
Unfortunately we have not found a way to display warnings as part of `kubectl` output unless we are rejecting a deployment altogether. That means that any checks with a severity of `warning` will still pass webhook validation, and the only evidence of that warning will either be in the Polaris dashboard or the Polaris webhook logs.
|
||||
|
||||
## Installation and Usage
|
||||
Polaris can be installed on your cluster using kubectl or Helm. It can also
|
||||
be run as a local binary, which will use your kubeconfig to connect to the cluster
|
||||
or run against local YAML files.
|
||||
|
||||
### kubectl
|
||||
#### Dashboard
|
||||
```
|
||||
kubectl apply -f https://github.com/reactiveops/polaris/releases/latest/download/dashboard.yaml
|
||||
kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80
|
||||
```
|
||||
|
||||
#### Webhook
|
||||
```
|
||||
kubectl apply -f https://github.com/reactiveops/polaris/releases/latest/download/webhook.yaml
|
||||
```
|
||||
|
||||
### Helm
|
||||
Start by adding the ReactiveOps Helm repo:
|
||||
```
|
||||
helm repo add reactiveops-stable https://charts.reactiveops.com/stable
|
||||
```
|
||||
|
||||
#### Dashboard
|
||||
```
|
||||
helm upgrade --install polaris reactiveops-stable/polaris --namespace polaris
|
||||
kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80
|
||||
```
|
||||
|
||||
#### Webhook
|
||||
```
|
||||
helm upgrade --install polaris reactiveops-stable/polaris --namespace polaris \
|
||||
--set webhook.enable=true --set dashboard.enable=false
|
||||
```
|
||||
|
||||
### Local Binary
|
||||
#### Installation
|
||||
Binary releases are available on the [releases page](https://github.com/reactiveops/polaris/releases) or can be installed with [Homebrew](https://brew.sh/):
|
||||
```
|
||||
brew tap reactiveops/tap
|
||||
brew install reactiveops/tap/polaris
|
||||
polaris --version
|
||||
```
|
||||
|
||||
You can run `polaris --help` to see a full list of options.
|
||||
|
||||
#### Dashboard
|
||||
The dashboard can be run on your local machine, without installing anything on the cluster.
|
||||
Polaris will use your local kubeconfig to connect to the cluster.
|
||||
|
||||
```
|
||||
polaris --dashboard --dashboard-port 8080
|
||||
```
|
||||
|
||||
#### Audits
|
||||
You can also run audits on the command line and see the output as JSON, YAML, or a raw score:
|
||||
```
|
||||
polaris --audit --output-format yaml > report.yaml
|
||||
polaris --audit --output-format score
|
||||
# 92
|
||||
```
|
||||
|
||||
Both the dashboard and audits can run against a local directory or YAML file
|
||||
rather than a cluster:
|
||||
```
|
||||
polaris --audit --audit-path ./deploy/
|
||||
```
|
||||
|
||||
##### Running with CI/CD
|
||||
You can integrate Polaris into CI/CD for repositories containing infrastructure-as-code.
|
||||
For example, to fail whenever the Polaris score drops below 90%:
|
||||
```bash
|
||||
score=`polaris --audit --audit-path ./deploy/ --output-format score`
|
||||
if [[ $score -lt 90 ]]; then
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Polaris supports a wide range of validations covering a number of Kubernetes best practices. Here's a sample configuration file that includes all currently supported checks. The [default configuration](https://github.com/reactiveops/polaris/blob/master/examples/config.yaml) contains a number of those checks. This repository also includes a sample [full configuration file](https://github.com/reactiveops/polaris/blob/master/examples/config-full.yaml) that enables all available checks.
|
||||
|
||||
Each check can be assigned a `severity`. Only checks with a severity of `error` or `warning` will be validated. The results of these validations are visible on the dashboard. In the case of the validating webhook, only failures with a severity of `error` will result in a change being rejected.
|
||||
|
||||
Polaris validation checks fall into several different categories:
|
||||
|
||||
- [Health Checks](docs/health-checks.md)
|
||||
- [Images](docs/images.md)
|
||||
- [Networking](docs/networking.md)
|
||||
- [Resources](docs/resources.md)
|
||||
- [Security](docs/security.md)
|
||||
|
||||
## CLI Options
|
||||
|
||||
* `config`: Specify a location for the Polaris config
|
||||
* `dashboard`: Runs the webserver for Polaris dashboard.
|
||||
* `dashboard-port`: Port for the dashboard webserver (default `8080`)
|
||||
* `dashboard-base-path`: Path on which the dashboard is being served (default `/`)
|
||||
* `webhook`: Runs the webhook webserver.
|
||||
* `webhook-port`: Port for the webhook webserver (default `9876`)
|
||||
* `disable-webhook-config-installer`: disable the installer in the webhook server, so it won't install webhook configuration resources during bootstrapping
|
||||
* `kubeconfig`: Paths to a kubeconfig. Only required if out-of-cluster.
|
||||
you can sign up for a [free account here](https://insights.fairwinds.com?source=polaris).
|
||||
|
||||
## Contributing
|
||||
PRs welcome! Check out the [Contributing Guidelines](CONTRIBUTING.md),
|
||||
[Code of Conduct](CODE_OF_CONDUCT.md), and [Roadmap](ROADMAP.md) for more information.
|
||||
PRs welcome! Check out the [Contributing Guidelines](https://polaris.docs.fairwinds.com/contributing) and [Code of Conduct](https://polaris.docs.fairwinds.com/code-of-conduct) for more information.
|
||||
|
||||
## Further Information
|
||||
A history of changes to this project can be viewed in the [Changelog](CHANGELOG.md)
|
||||
A history of changes to this project can be viewed in the [Changelog](https://polaris.docs.fairwinds.com/changelog)
|
||||
|
||||
If you'd like to learn more about Polaris, or if you'd like to speak with
|
||||
a Kubernetes expert, you can contact `info@reactiveops.com` or [visit our website](https://reactiveops.com)
|
||||
a Kubernetes expert, you can contact `info@fairwinds.com` or [visit our website](https://fairwinds.com)
|
||||
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<img src="https://polaris.docs.fairwinds.com/img/dashboard-screenshot.png" alt="Polaris Dashboard" width="550"/>
|
||||
</p>
|
||||
|
||||
## License
|
||||
Apache License 2.0
|
||||
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
# Polaris Roadmap
|
||||
We plan to continue expanding the list of checks available to Polaris users,
|
||||
as well as the project's overall functionality.
|
||||
|
||||
If you have ideas for a new check, or for new Polaris features,
|
||||
you can submit a pull request for this file, or open an issue in GitHub.
|
||||
|
||||
## Features
|
||||
### Validating Webhook
|
||||
The validating webhook rejects incoming workloads if they cause `error`-level
|
||||
issues, as defined by the Polaris configuration.
|
||||
|
||||
The webhook server is currently functional, but largely untested. Because
|
||||
the validating webhook has the potential to cause headaches for users,
|
||||
we have marked it as `beta` for now.
|
||||
|
||||
We will continue to gather feedback here and will move the webhook out of `beta`
|
||||
when we feel it's ready.
|
||||
|
||||
#### TODO
|
||||
* Pass `warning`-level messages back to `kubectl` if possible (may require changes
|
||||
to core k8s or `kubectl`)
|
||||
|
||||
## Ability to override checks
|
||||
We plan to add the ability to override Polaris checks for particular namespaces
|
||||
and workloads. This may be something that is set in the Polaris configuration,
|
||||
or an annotation that can be added to the resource definition.
|
||||
|
||||
This is important, as certain workloads have good reason to skip particular Polaris
|
||||
checks - for instance, the `dns-controller` deployment in `kube-system` needs to have
|
||||
the host network configured.
|
||||
|
||||
## Checks
|
||||
These are checks that we plan to implement. If you have requests or ideas,
|
||||
let us know! You can submit a pull request for this file, or open an issue in GitHub.
|
||||
|
||||
### Images
|
||||
* List of allowed/disallowed registries
|
||||
|
||||
### New controller types
|
||||
Currently we only look at Deployments. We plan to also validate these types of controllers:
|
||||
* StatefulSet
|
||||
* DaemonSet
|
||||
* Job
|
||||
* CronJob
|
||||
* ReplicaSet
|
||||
|
||||
### Check non-controllers
|
||||
We would like to implement checks for non-controller types, such as:
|
||||
* Ingress
|
||||
* Service
|
||||
* Secret
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
successMessage: CPU limits are set
|
||||
failureMessage: CPU limits should be set
|
||||
category: Efficiency
|
||||
target: Container
|
||||
containers:
|
||||
exclude:
|
||||
- initContainer
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
- resources
|
||||
properties:
|
||||
resources:
|
||||
type: object
|
||||
required:
|
||||
- limits
|
||||
properties:
|
||||
limits:
|
||||
type: object
|
||||
required:
|
||||
- cpu
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
not:
|
||||
const: ''
|
||||
@@ -0,0 +1,27 @@
|
||||
successMessage: CPU requests are set
|
||||
failureMessage: CPU requests should be set
|
||||
category: Efficiency
|
||||
target: Container
|
||||
containers:
|
||||
exclude:
|
||||
- initContainer
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
- resources
|
||||
properties:
|
||||
resources:
|
||||
type: object
|
||||
required:
|
||||
- requests
|
||||
properties:
|
||||
requests:
|
||||
type: object
|
||||
required:
|
||||
- cpu
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
not:
|
||||
const: ''
|
||||
@@ -0,0 +1,25 @@
|
||||
successMessage: Container does not have any dangerous capabilities
|
||||
failureMessage: Container should not have dangerous capabilities
|
||||
category: Security
|
||||
target: Container
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
properties:
|
||||
securityContext:
|
||||
type: object
|
||||
properties:
|
||||
capabilities:
|
||||
type: object
|
||||
properties:
|
||||
add:
|
||||
type: array
|
||||
not:
|
||||
contains:
|
||||
const: ALL
|
||||
not:
|
||||
contains:
|
||||
const: SYS_ADMIN
|
||||
not:
|
||||
contains:
|
||||
const: NET_ADMIN
|
||||
@@ -0,0 +1,11 @@
|
||||
successMessage: Host IPC is not configured
|
||||
failureMessage: Host IPC should not be configured
|
||||
category: Security
|
||||
target: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
properties:
|
||||
hostIPC:
|
||||
not:
|
||||
const: true
|
||||
@@ -0,0 +1,11 @@
|
||||
successMessage: Host network is not configured
|
||||
failureMessage: Host network should not be configured
|
||||
category: Security
|
||||
target: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
properties:
|
||||
hostNetwork:
|
||||
not:
|
||||
const: true
|
||||
@@ -0,0 +1,11 @@
|
||||
successMessage: Host PID is not configured
|
||||
failureMessage: Host PID should not be configured
|
||||
category: Security
|
||||
target: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
properties:
|
||||
hostPID:
|
||||
not:
|
||||
const: true
|
||||
@@ -0,0 +1,15 @@
|
||||
successMessage: Host port is not configured
|
||||
failureMessage: Host port should not be configured
|
||||
category: Security
|
||||
target: Container
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
properties:
|
||||
ports:
|
||||
type: array
|
||||
items:
|
||||
properties:
|
||||
hostPort:
|
||||
const: 0
|
||||
@@ -0,0 +1,31 @@
|
||||
successMessage: Container does not have any insecure capabilities
|
||||
failureMessage: Container should not have insecure capabilities
|
||||
category: Security
|
||||
target: Container
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
properties:
|
||||
securityContext:
|
||||
type: object
|
||||
properties:
|
||||
capabilities:
|
||||
type: object
|
||||
properties:
|
||||
add:
|
||||
enum:
|
||||
- CHOWN
|
||||
- DAC_OVERRIDE
|
||||
- FSETID
|
||||
- FOWNER
|
||||
- MKNOD
|
||||
- NET_RAW
|
||||
- SETGID
|
||||
- SETUID
|
||||
- SETFCAP
|
||||
- SETPCAP
|
||||
- NET_BIND_SERVICE
|
||||
- SYS_CHROOT
|
||||
- KILL
|
||||
- AUDIT_WRITE
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
successMessage: Liveness probe is configured
|
||||
failureMessage: Liveness probe should be configured
|
||||
category: Reliability
|
||||
controllers:
|
||||
exclude:
|
||||
- Job
|
||||
- CronJob
|
||||
containers:
|
||||
exclude:
|
||||
- initContainer
|
||||
target: Container
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
- livenessProbe
|
||||
properties:
|
||||
livenessProbe:
|
||||
type: object
|
||||
not:
|
||||
const: null
|
||||
@@ -0,0 +1,27 @@
|
||||
successMessage: Memory limits are set
|
||||
failureMessage: Memory limits should be set
|
||||
category: Efficiency
|
||||
target: Container
|
||||
containers:
|
||||
exclude:
|
||||
- initContainer
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
- resources
|
||||
properties:
|
||||
resources:
|
||||
type: object
|
||||
required:
|
||||
- limits
|
||||
properties:
|
||||
limits:
|
||||
type: object
|
||||
required:
|
||||
- memory
|
||||
properties:
|
||||
memory:
|
||||
type: string
|
||||
not:
|
||||
const: ''
|
||||
@@ -0,0 +1,27 @@
|
||||
successMessage: Memory requests are set
|
||||
failureMessage: Memory requests should be set
|
||||
category: Efficiency
|
||||
target: Container
|
||||
containers:
|
||||
exclude:
|
||||
- initContainer
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
- resources
|
||||
properties:
|
||||
resources:
|
||||
type: object
|
||||
required:
|
||||
- requests
|
||||
properties:
|
||||
requests:
|
||||
type: object
|
||||
required:
|
||||
- memory
|
||||
properties:
|
||||
memory:
|
||||
type: string
|
||||
not:
|
||||
const: ''
|
||||
@@ -0,0 +1,26 @@
|
||||
successMessage: Multiple replicas are scheduled
|
||||
failureMessage: Only one replica is scheduled
|
||||
category: Reliability
|
||||
target: Controller
|
||||
controllers:
|
||||
include:
|
||||
- Deployment
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
- Object
|
||||
properties:
|
||||
Object:
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
required:
|
||||
- replicas
|
||||
properties:
|
||||
replicas:
|
||||
type: integer
|
||||
minimum: 2
|
||||
@@ -0,0 +1,16 @@
|
||||
successMessage: Filesystem is read only
|
||||
failureMessage: Filesystem should be read only
|
||||
category: Security
|
||||
target: Container
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
- securityContext
|
||||
properties:
|
||||
securityContext:
|
||||
required:
|
||||
- readOnlyRootFilesystem
|
||||
properties:
|
||||
readOnlyRootFilesystem:
|
||||
const: true
|
||||
@@ -0,0 +1,9 @@
|
||||
successMessage: Priority class has been set
|
||||
failureMessage: Priority class should be set
|
||||
category: Security
|
||||
target: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
- priorityClassName
|
||||
@@ -0,0 +1,13 @@
|
||||
successMessage: Privilege escalation not allowed
|
||||
failureMessage: Privilege escalation should not be allowed
|
||||
category: Security
|
||||
target: Container
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
properties:
|
||||
securityContext:
|
||||
properties:
|
||||
allowPrivilegeEscalation:
|
||||
not:
|
||||
const: true
|
||||
@@ -0,0 +1,11 @@
|
||||
successMessage: Image pull policy is "Always"
|
||||
failureMessage: Image pull policy should be "Always"
|
||||
category: Reliability
|
||||
target: Container
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
required:
|
||||
- imagePullPolicy
|
||||
properties:
|
||||
imagePullPolicy:
|
||||
const: Always
|
||||
@@ -0,0 +1,21 @@
|
||||
successMessage: Readiness probe is configured
|
||||
failureMessage: Readiness probe should be configured
|
||||
category: Reliability
|
||||
controllers:
|
||||
exclude:
|
||||
- Job
|
||||
- CronJob
|
||||
containers:
|
||||
exclude:
|
||||
- initContainer
|
||||
target: Container
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
required:
|
||||
- readinessProbe
|
||||
properties:
|
||||
readinessProbe:
|
||||
type: object
|
||||
not:
|
||||
const: null
|
||||
@@ -0,0 +1,13 @@
|
||||
successMessage: Not running as privileged
|
||||
failureMessage: Should not be running as privileged
|
||||
category: Security
|
||||
target: Container
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
properties:
|
||||
securityContext:
|
||||
properties:
|
||||
privileged:
|
||||
not:
|
||||
const: true
|
||||
@@ -0,0 +1,52 @@
|
||||
successMessage: Is not allowed to run as root
|
||||
failureMessage: Should not be allowed to run as root
|
||||
category: Security
|
||||
target: Container
|
||||
schemaTarget: Pod
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
definitions:
|
||||
goodSecurityContext:
|
||||
type: object
|
||||
anyOf:
|
||||
- required:
|
||||
- runAsUser
|
||||
properties:
|
||||
runAsUser:
|
||||
minimum: 1
|
||||
- required:
|
||||
- runAsNonRoot
|
||||
properties:
|
||||
runAsNonRoot:
|
||||
const: true
|
||||
notBadSecurityContext:
|
||||
type: object
|
||||
properties:
|
||||
runAsUser:
|
||||
minimum: 1
|
||||
runAsNonRoot:
|
||||
const: true
|
||||
type: object
|
||||
anyOf:
|
||||
# non-root specified at pod-level, and not overridden at container level
|
||||
- required:
|
||||
- securityContext
|
||||
properties:
|
||||
securityContext:
|
||||
$ref: "#/definitions/goodSecurityContext"
|
||||
containers:
|
||||
type: array
|
||||
items:
|
||||
properties:
|
||||
securityContext:
|
||||
$ref: "#/definitions/notBadSecurityContext"
|
||||
# non-root specified at container level
|
||||
- properties:
|
||||
containers:
|
||||
type: array
|
||||
items:
|
||||
required:
|
||||
- securityContext
|
||||
properties:
|
||||
securityContext:
|
||||
$ref: "#/definitions/goodSecurityContext"
|
||||
@@ -0,0 +1,16 @@
|
||||
successMessage: Image tag is specified
|
||||
failureMessage: Image tag should be specified
|
||||
category: Reliability
|
||||
target: Container
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
required:
|
||||
- image
|
||||
allOf:
|
||||
- properties:
|
||||
image:
|
||||
pattern: ^.+:.+$
|
||||
- properties:
|
||||
image:
|
||||
not:
|
||||
pattern: ^.+:latest$
|
||||
@@ -0,0 +1,152 @@
|
||||
// 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 (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
conf "github.com/fairwindsops/polaris/pkg/config"
|
||||
"github.com/fairwindsops/polaris/pkg/kube"
|
||||
"github.com/fairwindsops/polaris/pkg/validator"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var setExitCode bool
|
||||
var minScore int
|
||||
var auditOutputURL string
|
||||
var auditOutputFile string
|
||||
var auditOutputFormat string
|
||||
var resourceToAudit string
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(auditCmd)
|
||||
auditCmd.PersistentFlags().StringVar(&auditPath, "audit-path", "", "If specified, audits one or more YAML files instead of a cluster.")
|
||||
auditCmd.PersistentFlags().BoolVar(&setExitCode, "set-exit-code-on-danger", false, "Set an exit code of 3 when the audit contains danger-level issues.")
|
||||
auditCmd.PersistentFlags().IntVar(&minScore, "set-exit-code-below-score", 0, "Set an exit code of 4 when the score is below this threshold (1-100).")
|
||||
auditCmd.PersistentFlags().StringVar(&auditOutputURL, "output-url", "", "Destination URL to send audit results.")
|
||||
auditCmd.PersistentFlags().StringVar(&auditOutputFile, "output-file", "", "Destination file for audit results.")
|
||||
auditCmd.PersistentFlags().StringVarP(&auditOutputFormat, "format", "f", "json", "Output format for results - json, yaml, or score.")
|
||||
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.")
|
||||
}
|
||||
|
||||
var auditCmd = &cobra.Command{
|
||||
Use: "audit",
|
||||
Short: "Runs a one-time audit.",
|
||||
Long: `Runs a one-time audit.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if displayName != "" {
|
||||
config.DisplayName = displayName
|
||||
}
|
||||
|
||||
auditData := runAndReportAudit(cmd.Context(), config, auditPath, resourceToAudit, auditOutputFile, auditOutputURL, auditOutputFormat)
|
||||
|
||||
summary := auditData.GetSummary()
|
||||
score := summary.GetScore()
|
||||
if setExitCode && summary.Dangers > 0 {
|
||||
logrus.Infof("%d danger items found in audit", summary.Dangers)
|
||||
os.Exit(3)
|
||||
} else if minScore != 0 && score < uint(minScore) {
|
||||
logrus.Infof("Audit score of %d is less than the provided minimum of %d", score, minScore)
|
||||
os.Exit(4)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func runAndReportAudit(ctx context.Context, c conf.Configuration, auditPath, workload, outputFile, outputURL, outputFormat string) validator.AuditData {
|
||||
// Create a kubernetes client resource provider
|
||||
k, err := kube.CreateResourceProvider(ctx, auditPath, workload)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error fetching Kubernetes resources %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
auditData, err := validator.RunAudit(ctx, c, k)
|
||||
|
||||
if err != nil {
|
||||
logrus.Errorf("Error while running audit on resources: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var outputBytes []byte
|
||||
if outputFormat == "score" {
|
||||
outputBytes = []byte(fmt.Sprintf("%d\n", auditData.GetSummary().GetScore()))
|
||||
} else if outputFormat == "yaml" {
|
||||
jsonBytes, err := json.Marshal(auditData)
|
||||
if err == nil {
|
||||
outputBytes, err = yaml.JSONToYAML(jsonBytes)
|
||||
}
|
||||
} else {
|
||||
outputBytes, err = json.MarshalIndent(auditData, "", " ")
|
||||
}
|
||||
if err != nil {
|
||||
logrus.Errorf("Error marshalling audit: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if outputURL == "" && outputFile == "" {
|
||||
os.Stdout.Write(outputBytes)
|
||||
} else {
|
||||
if outputURL != "" {
|
||||
req, err := http.NewRequest("POST", outputURL, bytes.NewBuffer(outputBytes))
|
||||
|
||||
if err != nil {
|
||||
logrus.Errorf("Error building request for output: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if outputFormat == "json" {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
} else if outputFormat == "yaml" {
|
||||
req.Header.Set("Content-Type", "application/x-yaml")
|
||||
} else {
|
||||
req.Header.Set("Content-Type", "text/plain")
|
||||
}
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
|
||||
if err != nil {
|
||||
logrus.Errorf("Error making request for output: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
logrus.Errorf("Error reading response: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
logrus.Infof("Received response: %v", body)
|
||||
}
|
||||
|
||||
if outputFile != "" {
|
||||
err := ioutil.WriteFile(outputFile, []byte(outputBytes), 0644)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error writing output to file: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
return auditData
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// 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 (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/fairwindsops/polaris/pkg/dashboard"
|
||||
"github.com/fairwindsops/polaris/pkg/validator"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var serverPort int
|
||||
var basePath string
|
||||
var loadAuditFile string
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(dashboardCmd)
|
||||
dashboardCmd.PersistentFlags().IntVarP(&serverPort, "port", "p", 8080, "Port for the dashboard webserver.")
|
||||
dashboardCmd.PersistentFlags().StringVar(&basePath, "base-path", "/", "Path on which the dashboard is served.")
|
||||
dashboardCmd.PersistentFlags().StringVar(&loadAuditFile, "load-audit-file", "", "Runs the dashboard with data saved from a past audit.")
|
||||
dashboardCmd.PersistentFlags().StringVar(&auditPath, "audit-path", "", "If specified, audits one or more YAML files instead of a cluster.")
|
||||
dashboardCmd.PersistentFlags().StringVar(&displayName, "display-name", "", "An optional identifier for the audit.")
|
||||
|
||||
}
|
||||
|
||||
var dashboardCmd = &cobra.Command{
|
||||
Use: "dashboard",
|
||||
Short: "Runs the webserver for Polaris dashboard.",
|
||||
Long: `Runs the webserver for Polaris dashboard.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if displayName != "" {
|
||||
config.DisplayName = displayName
|
||||
}
|
||||
|
||||
var auditDataPtr *validator.AuditData
|
||||
if loadAuditFile != "" {
|
||||
auditData := validator.ReadAuditFromFile(loadAuditFile)
|
||||
auditDataPtr = &auditData
|
||||
}
|
||||
router := dashboard.GetRouter(config, auditPath, serverPort, basePath, auditDataPtr)
|
||||
router.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("OK"))
|
||||
})
|
||||
http.Handle("/", router)
|
||||
|
||||
logrus.Infof("Starting Polaris dashboard server on port %d", serverPort)
|
||||
logrus.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", serverPort), nil))
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// 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 (
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
conf "github.com/fairwindsops/polaris/pkg/config"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var configPath string
|
||||
var disallowExemptions bool
|
||||
var logLevel string
|
||||
var auditPath string
|
||||
var displayName string
|
||||
|
||||
var (
|
||||
version string
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Flags
|
||||
rootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "Location of Polaris configuration file.")
|
||||
rootCmd.PersistentFlags().BoolVarP(&disallowExemptions, "disallow-exemptions", "", false, "Disallow any exemptions from configuration file.")
|
||||
rootCmd.PersistentFlags().StringVarP(&logLevel, "log-level", "", logrus.InfoLevel.String(), "Logrus log level.")
|
||||
flag.Parse()
|
||||
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
|
||||
}
|
||||
|
||||
var config conf.Configuration
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "polaris",
|
||||
Short: "polaris",
|
||||
Long: `Validation of best practices in your Kubernetes clusters.`,
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
parsedLevel, err := logrus.ParseLevel(logLevel)
|
||||
if err != nil {
|
||||
logrus.Errorf("log-level flag has invalid value %s", logLevel)
|
||||
} else {
|
||||
logrus.SetLevel(parsedLevel)
|
||||
}
|
||||
|
||||
config, err = conf.ParseFile(configPath)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error parsing config at %s: %v", configPath, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if disallowExemptions {
|
||||
config.DisallowExemptions = true
|
||||
}
|
||||
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
logrus.Error("You must specify a sub-command.")
|
||||
err := cmd.Help()
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
os.Exit(1)
|
||||
},
|
||||
}
|
||||
|
||||
// Execute the stuff
|
||||
func Execute(VERSION string) {
|
||||
version = VERSION
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
logrus.Error(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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 (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
}
|
||||
|
||||
var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Prints the current version.",
|
||||
Long: `Prints the current version of the tool.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("Polaris version:" + version)
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// 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 (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
fwebhook "github.com/fairwindsops/polaris/pkg/webhook"
|
||||
k8sConfig "sigs.k8s.io/controller-runtime/pkg/client/config"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
|
||||
)
|
||||
|
||||
var webhookPort int
|
||||
var disableWebhookConfigInstaller bool
|
||||
|
||||
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.")
|
||||
}
|
||||
|
||||
var webhookCmd = &cobra.Command{
|
||||
Use: "webhook",
|
||||
Short: "Runs the webhook webserver.",
|
||||
Long: `Runs the webhook webserver.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
logrus.Debug("Setting up controller manager")
|
||||
|
||||
mgr, err := manager.New(k8sConfig.GetConfigOrDie(), manager.Options{
|
||||
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("/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"
|
||||
|
||||
// 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()})
|
||||
|
||||
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)
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
---
|
||||
# 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'
|
||||
---
|
||||
# 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/v1beta1
|
||||
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
|
||||
image: 'quay.io/fairwinds/polaris:2.0'
|
||||
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,262 @@
|
||||
---
|
||||
# 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'
|
||||
---
|
||||
# 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/v1beta1
|
||||
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:2.0'
|
||||
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
|
||||
@@ -0,0 +1,58 @@
|
||||
module.exports = {
|
||||
title: "Fairwinds Polaris Documentation",
|
||||
description: "Documentation for Fairwinds Polaris - audit and enforce Kubernetes best practices for your workloads",
|
||||
themeConfig: {
|
||||
docsRepo: "FairwindsOps/polaris",
|
||||
sidebar: [
|
||||
{
|
||||
title: "Polaris",
|
||||
path: "/",
|
||||
sidebarDepth: 0,
|
||||
collapsable: false,
|
||||
children: [
|
||||
{
|
||||
title: "Changelog",
|
||||
path: "/changelog",
|
||||
},
|
||||
{
|
||||
title: "Code of Conduct",
|
||||
path: "/code-of-conduct",
|
||||
},
|
||||
{
|
||||
title: "Contributing",
|
||||
path: "/contributing",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Ways to Run Polaris",
|
||||
collapsable: false,
|
||||
children: [
|
||||
"/dashboard",
|
||||
"/admission-controller",
|
||||
"/infrastructure-as-code",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Customization",
|
||||
collapsable: false,
|
||||
children: [
|
||||
"/customization/configuration",
|
||||
"/customization/checks",
|
||||
"/customization/custom-checks",
|
||||
"/customization/exemptions",
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Checks",
|
||||
collapsable: false,
|
||||
sidebarDepth: 0,
|
||||
children: [
|
||||
"/checks/security",
|
||||
"/checks/efficiency",
|
||||
"/checks/reliability",
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// This file is generated from FairwindsOps/documentation-template
|
||||
// DO NOT EDIT MANUALLY
|
||||
|
||||
const fs = require('fs');
|
||||
const npath = require('path');
|
||||
|
||||
const CONFIG_FILE = npath.join(__dirname, 'config-extras.js');
|
||||
const BASE_DIR = npath.join(__dirname, '..');
|
||||
|
||||
const extras = require(CONFIG_FILE);
|
||||
if (!extras.title || !extras.description || !extras.themeConfig.docsRepo) {
|
||||
throw new Error("Please specify 'title', 'description', and 'themeConfig.docsRepo' in config-extras.js");
|
||||
}
|
||||
|
||||
const docFiles = fs.readdirSync(BASE_DIR)
|
||||
.filter(f => f !== "README.md")
|
||||
.filter(f => f !== ".vuepress")
|
||||
.filter(f => f !== "node_modules")
|
||||
.filter(f => npath.extname(f) === '.md' || npath.extname(f) === '');
|
||||
|
||||
const sidebar = [['/', 'Home']].concat(docFiles.map(f => {
|
||||
const ext = npath.extname(f);
|
||||
if (ext === '') {
|
||||
// this is a directory
|
||||
const title = f;
|
||||
const children = fs.readdirSync(npath.join(BASE_DIR, f)).map(subf => {
|
||||
return '/' + f + '/' + npath.basename(subf);
|
||||
});
|
||||
return {title, children};
|
||||
}
|
||||
const path = npath.basename(f);
|
||||
return path;
|
||||
}));
|
||||
|
||||
const baseConfig = {
|
||||
title: "",
|
||||
description: "",
|
||||
head: [
|
||||
['link', { rel: 'icon', href: '/favicon.png' }],
|
||||
['script', { src: '/scripts/modify.js' }],
|
||||
['script', { src: '/scripts/leadlander.js' }],
|
||||
],
|
||||
themeConfig: {
|
||||
docsRepo: "",
|
||||
docsDir: 'docs-md',
|
||||
editLinks: true,
|
||||
editLinkText: "Help us improve this page",
|
||||
logo: '/img/fairwinds-logo.svg',
|
||||
heroText: "",
|
||||
sidebar,
|
||||
nav: [
|
||||
{text: 'View on GitHub', link: 'https://github.com/' + extras.themeConfig.docsRepo},
|
||||
],
|
||||
},
|
||||
plugins: {
|
||||
'vuepress-plugin-clean-urls': {
|
||||
normalSuffix: '/',
|
||||
notFoundPath: '/404.html',
|
||||
},
|
||||
'check-md': {},
|
||||
},
|
||||
}
|
||||
|
||||
let config = JSON.parse(JSON.stringify(baseConfig))
|
||||
if (!fs.existsSync(CONFIG_FILE)) {
|
||||
throw new Error("Please add config-extras.js to specify your project details");
|
||||
}
|
||||
for (let key in extras) {
|
||||
if (!config[key]) config[key] = extras[key];
|
||||
else if (key === 'head') config[key] = config[key].concat(extras[key]);
|
||||
else Object.assign(config[key], extras[key]);
|
||||
}
|
||||
module.exports = config;
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 400 B |
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 486.5 92.3" style="enable-background:new 0 0 486.5 92.3;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M72.5,24.3H0.4V0.4h84.4V12C84.8,18.8,79.3,24.3,72.5,24.3z"/>
|
||||
<path class="st0" d="M41.8,58H0.4V34.1h53.7v11.6C54.1,52.5,48.6,58,41.8,58z"/>
|
||||
<path class="st0" d="M12,91.7H0.4V67.8h23.9v11.6C24.2,86.2,18.7,91.7,12,91.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M121.7,77V16.9h36.9v4.2c0,3.7-3,6.8-6.8,6.8h-18.4v13.5H150v3.5c0,4.1-3.3,7.5-7.5,7.5h-9.1v19.1 c0,3-2.5,5.5-5.5,5.5H121.7z"/>
|
||||
<path class="st0" d="M161.1,64.7c0-2,0.3-3.7,1-5.1c0.7-1.5,1.6-2.7,2.9-3.6c1.3-1,2.7-1.7,4.2-2.3c1.6-0.6,3.3-1,5.4-1.3l11.3-2 v-1.5c0-2-0.5-3.5-1.6-4.6c-1-1.1-2.6-1.6-4.5-1.6s-3.4,0.5-4.6,1.4c-1.2,1-1.8,2.2-1.8,3.8h-10.8c0.3-4.5,1.9-8.2,5.1-11 c3.1-2.8,7.2-4.3,12.3-4.3c5.3,0,9.5,1.3,12.6,4s4.7,6.6,4.7,11.8V77h-4.7c-2.8,0-5.1-2.1-5.5-4.8l-0.1-1.1 c-2.7,4.6-6.9,6.8-12.4,6.8c-3.9,0-7.1-1.2-9.6-3.6C162.4,72,161.1,68.8,161.1,64.7z M172.3,64c0,1.2,0.4,2.1,1.3,2.8 c0.9,0.7,2.1,1,3.7,1c1.4,0,2.7-0.3,3.9-0.9c1.2-0.6,2.2-1.5,3-2.7c1-1.4,1.5-3.2,1.5-5.3v-1.2l-8.7,1.8c-1.6,0.3-2.8,0.8-3.6,1.5 C172.7,61.8,172.3,62.7,172.3,64z"/>
|
||||
<path class="st0" d="M207,20.9c0-1.8,0.7-3.6,2-4.9c1.3-1.2,2.8-1.9,4.6-1.9c1.8,0,3.6,0.6,4.9,1.9c1.4,1.3,2.1,2.9,2.1,4.8 s-0.7,3.4-2,4.7c-1.3,1.3-2.9,1.9-4.8,1.9s-3.5-0.6-4.8-1.9C207.7,24.2,207.1,22.7,207,20.9z M208.2,77V33.5h11.2v38 c0,3-2.5,5.5-5.5,5.5H208.2z"/>
|
||||
<path class="st0" d="M230.4,77V33.5h9.6l1.1,6.8c0.8-2.1,2.3-3.9,4.4-5.2c2.1-1.4,4.9-2.1,8.3-2.1v11c-3.5,0-6.4,0.9-8.6,2.6 s-3.4,4.4-3.5,8.1v16.7c0,3-2.5,5.5-5.5,5.5L230.4,77L230.4,77z"/>
|
||||
<path class="st0" d="M259.6,33.5h11.9l6.6,26.1l0.8,4.6l1-4.6l7.4-26.1h9.9l7.4,26.1l0.9,4.6l0.8-4.6l6.7-26.1h11.9L313,72.9 c-0.7,2.4-3,4.1-5.5,4.1H300l-7.9-25.6L285,73c-0.8,2.3-3,3.9-5.4,3.9h-7L259.6,33.5z"/>
|
||||
<path class="st0" d="M330.5,20.7c0-1.8,0.7-3.4,2-4.7c1.3-1.3,2.9-1.9,4.8-1.9c1.8,0,3.4,0.6,4.8,1.9c1.3,1.3,2,2.8,2,4.7 c0,1.9-0.7,3.4-2,4.7c-1.3,1.3-2.9,1.9-4.8,1.9s-3.5-0.6-4.8-1.9C331.2,24.2,330.5,22.6,330.5,20.7z M331.7,77V33.5h11.2v38 c0,3-2.5,5.5-5.5,5.5H331.7z"/>
|
||||
<path class="st0" d="M354.8,77V33.5h9.6l0.9,5.8c1.1-2,2.6-3.6,4.6-4.9c2-1.2,4.4-1.9,7.2-1.9c4.5,0,8,1.4,10.4,4.3 s3.6,6.8,3.6,11.9v22.5c0,3.2-2.6,5.7-5.7,5.7h-5.5V51.4c0-2.5-0.5-4.5-1.6-5.8c-1-1.3-2.6-2-4.6-2c-2.3,0-4.1,0.9-5.5,2.7 c-1.4,1.8-2.2,4.4-2.2,7.9v17.1c0,3.2-2.6,5.7-5.7,5.7L354.8,77L354.8,77z"/>
|
||||
<path class="st0" d="M399.1,55.2c0-6.4,1.9-11.8,5.7-16.1c3.8-4.3,8.7-6.5,14.5-6.5c2.9,0,5.5,0.5,7.8,1.6s4,2.4,5.2,4.1V14.4 h11.2V77h-4.8c-2.7,0-5-2-5.4-4.7l-0.2-1.2c-3.1,4.5-7.7,6.8-13.9,6.8c-3.8,0-7.3-1-10.4-3s-5.5-4.7-7.2-8.2 C399.9,63.3,399.1,59.4,399.1,55.2z M410.5,55.2c0,3.7,1,6.6,3.1,8.9c2.1,2.3,4.7,3.4,7.8,3.4c2.9,0,5.5-1.1,7.7-3.2 c2.2-2.2,3.3-5.1,3.3-8.8V55c0-2.5-0.6-4.6-1.7-6.5s-2.5-3.2-4.1-4.1s-3.4-1.3-5.2-1.3c-3.1,0-5.7,1.1-7.8,3.4 S410.5,51.6,410.5,55.2z"/>
|
||||
<path class="st0" d="M452.2,63.8h6.9c2,0,3.7,1.2,4.8,2.9c0.2,0.4,0.6,0.7,0.9,1c1.1,0.9,2.6,1.4,4.5,1.4c1.7,0,3-0.4,4-1.1 c0.9-0.7,1.4-1.8,1.4-3c0-1.4-0.5-2.5-1.6-3.3s-3.2-1.5-6.2-2.1c-4.8-0.8-8.3-2.3-10.5-4.4c-2.3-2.1-3.4-4.9-3.4-8.5 c0-4,1.4-7.4,4.2-10.1c2.8-2.7,6.8-4.1,11.9-4.1c4.6,0,8.4,1.3,11.3,3.8c2.9,2.5,4.5,5.8,4.7,9.9H474c-0.1-3.3-1.7-5-5-5 c-1.5,0-2.7,0.4-3.5,1.2c-0.8,0.8-1.3,1.8-1.3,3.1c0,1.4,0.5,2.4,1.6,3.1s3.1,1.3,6,1.8c5.1,0.9,8.8,2.4,10.9,4.5 c2.2,2.1,3.2,5,3.2,8.7c0,2.4-0.4,4.5-1.3,6.4c-0.9,1.8-2.1,3.3-3.7,4.4c-1.6,1.1-3.3,2-5.3,2.5c-2,0.6-4.1,0.8-6.5,0.8 c-5.3,0-9.4-1.3-12.3-3.8C453.9,71.6,452.3,68.2,452.2,63.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* This file is generated from FairwindsOps/documentation-template
|
||||
* DO NOT EDIT MANUALLY
|
||||
*/
|
||||
|
||||
var llcookieless = true;
|
||||
var sf14gv = 32793;
|
||||
(function() {
|
||||
var sf14g = document.createElement('script');
|
||||
sf14g.src = 'https://lltrck.com/lt-v2.min.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(sf14g, s);
|
||||
})();
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* This file is generated from FairwindsOps/documentation-template
|
||||
* DO NOT EDIT MANUALLY
|
||||
*/
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
setTimeout(function() {
|
||||
var link = document.getElementsByClassName('home-link')[0];
|
||||
linkClone = link.cloneNode(true);
|
||||
linkClone.href = "https://fairwinds.com";
|
||||
link.setAttribute('target', '_blank');
|
||||
link.parentNode.replaceChild(linkClone, link);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* This file is generated from FairwindsOps/documentation-template
|
||||
* DO NOT EDIT MANUALLY
|
||||
*/
|
||||
|
||||
.github-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: $primaryColor;
|
||||
}
|
||||
.text-danger {
|
||||
color: $dangerColor;
|
||||
}
|
||||
.text-warning {
|
||||
color: $warningColor;
|
||||
}
|
||||
.text-info {
|
||||
color: $infoColor;
|
||||
}
|
||||
.text-success {
|
||||
color: $successColor;
|
||||
}
|
||||
|
||||
.theme-default-content:not(.custom),
|
||||
.page-nav,
|
||||
.page-edit,
|
||||
footer {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.theme-default-content:not(.custom) > h2 {
|
||||
padding-top: 7rem;
|
||||
}
|
||||
|
||||
.navbar .site-name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar, .navbar .links {
|
||||
background-color: $primaryColor !important;
|
||||
}
|
||||
|
||||
.navbar .links a {
|
||||
color: #fff;
|
||||
}
|
||||
.navbar .links a svg {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 5px solid #f7f7f7;
|
||||
}
|
||||
|
||||
.no-border img,
|
||||
img.no-border,
|
||||
header img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.mini-img {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.theme-default-content:not(.custom) .mini-img img {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.page {
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is generated from FairwindsOps/documentation-template
|
||||
* DO NOT EDIT MANUALLY
|
||||
*/
|
||||
|
||||
|
||||
$primaryColor = #23103A
|
||||
$dangerColor = #A0204C
|
||||
$warningColor = #FF6C00
|
||||
$infoColor = #8BD2DC
|
||||
$successColor = #28a745
|
||||
|
||||
$accentColor = #FF6C00
|
||||
$textColor = #2c3e50
|
||||
$borderColor = #eaecef
|
||||
$codeBgColor = #282c34
|
||||
$arrowBgColor = #ccc
|
||||
$badgeTipColor = #42b983
|
||||
$badgeWarningColor = darken(#ffe564, 35%)
|
||||
$badgeErrorColor = #DA5961
|
||||
|
||||
// layout
|
||||
$navbarHeight = 3.6rem
|
||||
$sidebarWidth = 20rem
|
||||
$contentWidth = 740px
|
||||
$homePageWidth = 960px
|
||||
|
||||
// responsive breakpoints
|
||||
$MQNarrow = 959px
|
||||
$MQMobile = 719px
|
||||
$MQMobileNarrow = 419px
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extend: '@vuepress/theme-default'
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<ParentLayout>
|
||||
<template #page-bottom>
|
||||
<div class="custom-footer">
|
||||
<div class="left-footer">
|
||||
<a href="https://fairwinds.com" target="_blank">Learn more about Fairwinds</a>
|
||||
<a href="https://fairwinds.com/insights" target="_blank">Try Fairwinds Insights</a>
|
||||
</div>
|
||||
<div class="right-footer">
|
||||
<a href="https://www.fairwinds.com/privacy-policy" target="_blank">Privacy Policy</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</ParentLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ParentLayout from '@parent-theme/layouts/Layout.vue'
|
||||
|
||||
export default {
|
||||
name: 'Layout',
|
||||
|
||||
components: {
|
||||
ParentLayout
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
div.custom-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-top: 1px solid #eaecef;
|
||||
padding: 2rem 2.5rem;
|
||||
}
|
||||
.custom-footer .left-footer {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
.custom-footer .left-footer a:first-of-type {
|
||||
margin-right: 1.5rem;
|
||||
}
|
||||
.custom-footer a {
|
||||
color: #4e6e8e;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,56 @@
|
||||
<div align="center" class="no-border">
|
||||
<img src="/img/polaris-logo.png" alt="Polaris Logo">
|
||||
<br>
|
||||
<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=1.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">
|
||||
</a>
|
||||
<a href="https://circleci.com/gh/FairwindsOps/polaris.svg">
|
||||
<img src="https://circleci.com/gh/FairwindsOps/polaris.svg?style=svg">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
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 a few different modes:
|
||||
|
||||
Polaris can be run in three different modes:
|
||||
* As a [dashboard](/dashboard), so you can audit what's running inside your cluster.
|
||||
* As an [admission controller](/admission-controller), so you can automatically reject workloads that don't adhere to your organization's policies.
|
||||
* As a [command-line tool](/infrastructure-as-code), so you can test local YAML files, e.g. as part of a CI/CD process.
|
||||
|
||||
**Want to learn more?** Reach out on [the Slack channel](https://fairwindscommunity.slack.com/messages/polaris) ([request invite](https://join.slack.com/t/fairwindscommunity/shared_invite/zt-e3c6vj4l-3lIH6dvKqzWII5fSSFDi1g)), send an email to `opensource@fairwinds.com`, or join us for [office hours on Zoom](https://fairwindscommunity.slack.com/messages/office-hours)
|
||||
|
||||
|
||||
|
||||
## Integration with Fairwinds Insights
|
||||
[Fairwinds Insights](https://www.fairwinds.com/insights?utm_campaign=Hosted%20Polaris%20&utm_source=polaris&utm_term=polaris&utm_content=polaris)
|
||||
is a platform for auditing Kubernetes clusters and enforcing policy. If you'd like to:
|
||||
* manage Polaris across a fleet of clusters
|
||||
* track findings over time
|
||||
* send results to services like Slack and Datadog
|
||||
* add additional checks from tools like
|
||||
[Trivy](https://github.com/aquasecurity/trivy),
|
||||
[Goldilocks](https://github.com/FairwindsOps/goldilocks/), and
|
||||
[OPA](https://www.openpolicyagent.org)
|
||||
|
||||
you can sign up for a [free account here](https://insights.fairwinds.com?source=polaris).
|
||||
|
||||
## Contributing
|
||||
PRs welcome! Check out the [Contributing Guidelines](/contributing) and [Code of Conduct](/code-of-conduct) for more information.
|
||||
|
||||
## Further Information
|
||||
A history of changes to this project can be viewed in the [Changelog](/changelog)
|
||||
|
||||
If you'd like to learn more about Polaris, or if you'd like to speak with
|
||||
a Kubernetes expert, you can contact `info@fairwinds.com` or [visit our website](https://fairwinds.com)
|
||||
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<img src="/img/dashboard-screenshot.png" alt="Polaris Dashboard" width="550"/>
|
||||
</p>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# Admission Controller
|
||||
Polaris can be run as an admission controller that acts as a validating webhook.
|
||||
This accepts the same configuration as the dashboard, and can run the same validations.
|
||||
|
||||
The webhook will reject any workloads that trigger a danger-level check.
|
||||
This is indicative of the greater goal of Polaris, not just to encourage better
|
||||
configuration through dashboard visibility, but to actually enforce it with this webhook.
|
||||
|
||||
Note that Polaris will not alter your workloads, only block workloads that don't conform to the configured policies.
|
||||
|
||||
## Installation
|
||||
### kubectl
|
||||
```bash
|
||||
kubectl apply -f https://github.com/fairwindsops/polaris/releases/latest/download/webhook.yaml
|
||||
```
|
||||
|
||||
### Helm
|
||||
```bash
|
||||
helm repo add fairwindsops-stable https://charts.fairwindsops.com/stable
|
||||
helm upgrade --install polaris fairwindsops-stable/polaris --namespace polaris \
|
||||
--set webhook.enable=true --set dashboard.enable=false
|
||||
```
|
||||
|
||||
## Workload Types
|
||||
The webhook comes with built-in support for a handful of known controller types,
|
||||
such as Deployments, Jobs, and DaemonSets. To add new controller types,
|
||||
you can set `webhook.rules` in the
|
||||
[Helm chart](https://github.com/FairwindsOps/charts/tree/master/stable/polaris)
|
||||
|
||||
## Warnings
|
||||
Unfortunately we have not found a way to display warnings as part of `kubectl`
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
---
|
||||
sidebarDepth: 0
|
||||
---
|
||||
## 2.0.0
|
||||
* Standardize categories of checks into Security, Reliability, and Efficiency
|
||||
* Changes to the dashboard UI
|
||||
* Update controller-runtime
|
||||
|
||||
## 1.2.1
|
||||
* Update date on dashboard footer
|
||||
|
||||
## 1.2.0
|
||||
* Add ability to audit a single workload
|
||||
* Enable `pullPolicyAlways` by default
|
||||
* Fix for finding parent resources
|
||||
|
||||
## 1.1.1
|
||||
* Show controller checks on dashboard
|
||||
* Fix for orphaned pods w/ controller checks
|
||||
|
||||
## 1.1.0
|
||||
* Add namespace filter in UI
|
||||
* Add priorityClass check
|
||||
* Support reading from STDIN
|
||||
* Ensure severity is set for all custom checks
|
||||
* Support audit files which use \r or \r\n as newline character
|
||||
* Add option to exempt an entire controller from checks via config file
|
||||
* Fixed case where parent resources trigger error
|
||||
* Fixed UI zero-state
|
||||
|
||||
## 1.0.3
|
||||
* Fixed case where parent resources trigger error
|
||||
* Fixed dashboard link when `--base-path` is set
|
||||
|
||||
## 1.0.2
|
||||
* Fixed case where custom CRDs are not covered by RBAC
|
||||
|
||||
## 1.0.1
|
||||
* Added ARM binaries to releases
|
||||
|
||||
## 1.0.0
|
||||
### New Features
|
||||
* Added support for custom checks using JSON Schema
|
||||
* Added support for arbitrary controllers, rather than a pre-configured set
|
||||
* removed support for `controllers_to_scan` in config
|
||||
* Added the ability to exempt a particular controller from a particular check.
|
||||
* 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/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
|
||||
* CLI flag `--set-exit-code-on-error` is now `--set-exit-code-on-danger`
|
||||
* Flags `--version`, `--dashboard`, `--webhook`, and `--audit` are now arguments
|
||||
* Port flags are now just `--port`
|
||||
|
||||
## 0.6.0
|
||||
* Fixed webhook support in Kubernetes 1.16
|
||||
* this also removes support for 1.8
|
||||
* Added support for exemptions via controller annotations
|
||||
|
||||
## 0.5.2
|
||||
* Fixed missing success messages for resource requests/limits
|
||||
|
||||
## 0.5.1
|
||||
* Added a few more exemptions
|
||||
* Started checking exemptions based on controller name prefix
|
||||
* `runAsUser != 0` now passes the `runAsNonRoot` check
|
||||
|
||||
## 0.5.0
|
||||
* Added `--load-audit-file` flag to run the dashboard from an existing audit
|
||||
* Added an `ID` field to each check in the output
|
||||
* Skip health checks for jobs, cronjobs, initcontainers
|
||||
* Added support for exemptions
|
||||
* Fixed dashboard base path option
|
||||
|
||||
## 0.4.0
|
||||
* Added additional Pod Controllers to scan PodSpec (`jobs`, `cronjobs`, `daemonsets`, `replicationcontrollers`)
|
||||
|
||||
## 0.3.1
|
||||
* Changed dashboard branding to refer to new org name Fairwinds
|
||||
|
||||
## 0.3.0
|
||||
* Added `--set-exit-code-on-error` and `--set-exit-code-below-score` flags to better support CI/CD
|
||||
|
||||
## 0.2.1
|
||||
* [Fix](https://github.com/FairwindsOps/polaris/issues/146): Fixed logic on RunAsNonRoot check to incorporate settings in podSpec
|
||||
|
||||
## 0.2.0
|
||||
* Added `--output-format` flag for better CI/CD support
|
||||
* Added `--display-name` flag
|
||||
* Added support for StatefulSets
|
||||
* Show error message if no kubeconfig is set
|
||||
|
||||
## 0.1.5
|
||||
* [Fix](https://github.com/FairwindsOps/polaris/issues/125): ignore limits/requests for initContainers
|
||||
* [Fix](https://github.com/FairwindsOps/polaris/issues/132): support custom base path
|
||||
|
||||
## 0.1.4
|
||||
* [Fix](https://github.com/FairwindsOps/polaris/issues/116): details pages getting template errors
|
||||
* [Fix](https://github.com/FairwindsOps/polaris/issues/114): support all auth providers
|
||||
* [Fix](https://github.com/FairwindsOps/polaris/issues/112): Ignore readiness probe for initContainers
|
||||
|
||||
## 0.1.3
|
||||
* [Fix](https://github.com/FairwindsOps/polaris/issues/109): dashboard not updating when running persistently
|
||||
|
||||
## 0.1.2
|
||||
* Stored all third-party assets (e.g. Charts.js) to local files to support offline dashboard viewing
|
||||
* Fix: custom configs in `ConfigMap` not respected
|
||||
|
||||
## 0.1.1
|
||||
* [Fix](https://github.com/FairwindsOps/polaris/issues/93): missing `config.yaml` and dashboard assets in binary releases
|
||||
* Added some tests and better error handling
|
||||
|
||||
## 0.1.0
|
||||
* Dashboard fully functional
|
||||
* Validating webhook functional, but still considered beta
|
||||
* Checks:
|
||||
* Health
|
||||
* readiness probe missing
|
||||
* liveness probe missing
|
||||
* Images
|
||||
* tag not specified
|
||||
* pull policy not always
|
||||
* Networking
|
||||
* host network set
|
||||
* host port set
|
||||
* Resources
|
||||
* cpu/memory requests missing
|
||||
* cpu/memory limits missing
|
||||
* cpu/memory ranges exceeded
|
||||
* Security
|
||||
* security capabilities
|
||||
* host IPC set
|
||||
* host PID set
|
||||
* not read-only fs
|
||||
* privilege escalation allowed
|
||||
* run as root allowed
|
||||
* run as privileged
|
||||
@@ -0,0 +1,31 @@
|
||||
# Efficiency
|
||||
|
||||
These checks ensure that CPU and memory settings are configured, so that
|
||||
Kubernetes can schedule your workload effectively.
|
||||
|
||||
## Presence Checks
|
||||
|
||||
To simplify ensure that these values have been set, the following attributes are available:
|
||||
|
||||
key | default | description
|
||||
----|---------|------------
|
||||
`resources.cpuRequestsMissing` | `warning` | Fails when `resources.requests.cpu` attribute is not configured.
|
||||
`resources.memoryRequestsMissing` | `warning` | Fails when `resources.requests.memory` attribute is not configured.
|
||||
`resources.cpuLimitsMissing` | `warning` | Fails when `resources.limits.cpu` attribute is not configured.
|
||||
`resources.memoryLimitsMissing` | `warning` | Fails when `resources.limits.memory` attribute is not configured.
|
||||
|
||||
## Background
|
||||
|
||||
Configuring resource requests and limits for containers running in Kubernetes is an important best practice to follow. Setting appropriate resource requests will ensure that all your applications have sufficient compute resources. Setting appropriate resource limits will ensure that your applications do not consume too many resources.
|
||||
|
||||
Having these values appropriately configured ensures that:
|
||||
|
||||
* Cluster autoscaling can function as intended. New nodes are scheduled once pods are unable to be scheduled on an existing node due to insufficient resources. This will not happen if resource requests are not configured.
|
||||
|
||||
* Each container has sufficient access to compute resources. Without resource requests, a pod may be scheduled on a node that is already overutilized. Without resource limits, a single poorly behaving pod could utilize the majority of resources on a node, significantly impacting the performance of other pods on the same node.
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Kubernetes Docs: Managing Compute Resources for Containers](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/)
|
||||
- [Kubernetes best practices: Resource requests and limits](https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-resource-requests-and-limits)
|
||||
- [Vertical Pod Autoscaler (can automatically set resource requests and limits)](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler)
|
||||
@@ -0,0 +1,33 @@
|
||||
# Reliability
|
||||
|
||||
These checks help to make sure your workloads are always available,
|
||||
and are running the correct image.
|
||||
|
||||
key | default | description
|
||||
----|---------|------------
|
||||
`reliability.readinessProbeMissing` | `warning` | Fails when a readiness probe is not configured for a pod.
|
||||
`reliability.livenessProbeMissing` | `warning` | Fails when a liveness probe is not configured for a pod.
|
||||
`reliability.tagNotSpecified` | `danger` | Fails when an image tag is either not specified or `latest`.
|
||||
`reliability.pullPolicyNotAlways` | `warning` | Fails when an image pull policy is not `always`.
|
||||
`reliability.priorityClassNotSet` | `ignore` | Fails when a priorityClassName is not set for a pod.
|
||||
`reliability.multipleReplicasForDeployment` | `ignore` | Fails when there is only one replica for a deployment.
|
||||
|
||||
## Background
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [What's Wrong With The Docker :latest Tag?](https://vsupalov.com/docker-latest-tag/)
|
||||
- [Kubernetes’ AlwaysPullImages Admission Control — the Importance, Implementation, and Security Vulnerability in its Absence](https://medium.com/@trstringer/kubernetes-alwayspullimages-admission-control-the-importance-implementation-and-security-d83ff3815840)
|
||||
- [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/)
|
||||
@@ -0,0 +1,37 @@
|
||||
# Security
|
||||
|
||||
These checks are related to security concerns. Workloads that fail these
|
||||
checks may make your cluster more vulnerable, often by introducing a path
|
||||
for privilege escalation.
|
||||
|
||||
key | default | description
|
||||
----|---------|------------
|
||||
`security.hostIPCSet` | `danger` | Fails when `hostIPC` attribute is configured.
|
||||
`security.hostPIDSet` | `danger` | Fails when `hostPID` attribute is configured.
|
||||
`security.notReadOnlyRootFilesystem` | `warning` | Fails when `securityContext.readOnlyRootFilesystem` is not true.
|
||||
`security.privilegeEscalationAllowed` | `danger` | Fails when `securityContext.allowPrivilegeEscalation` is true.
|
||||
`security.runAsRootAllowed` | `warning` | Fails when `securityContext.runAsNonRoot` is not true.
|
||||
`security.runAsPrivileged` | `danger` | Fails when `securityContext.privileged` is true.
|
||||
`security.insecureCapabilities` | `warning` | Fails when `securityContext.capabilities` includes one of the capabilities [listed here](https://github.com/FairwindsOps/polaris/tree/master/checks/insecureCapabilities.yaml)
|
||||
`security.dangerousCapabilities` | `danger` | Fails when `securityContext.capabilities` includes one of the capabilities [listed here](https://github.com/FairwindsOps/polaris/tree/master/checks/dangerousCapabilities.yaml)
|
||||
`security.hostNetworkSet` | `warning` | Fails when `hostNetwork` attribute is configured.
|
||||
`security.hostPortSet` | `warning` | Fails when `hostPort` attribute is configured.
|
||||
|
||||
## Background
|
||||
|
||||
Securing workloads in Kubernetes is an important part of overall cluster security. The overall goal should be to ensure that containers are running with as minimal privileges as possible. This includes avoiding privilege escalation, not running containers with a root user, not giving excessive access to the host network, and using read only file systems wherever possible.
|
||||
|
||||
A pod running with the `hostNetwork` attribute enabled will have access to the loopback device, services listening on localhost, and could be used to snoop on network activity of other pods on the same node. There are certain examples where setting `hostNetwork` to true is required, such as deploying a networking plugin like Flannel.
|
||||
|
||||
Setting the `hostPort` attribute on a container will ensure that it is accessible on that specific port on each node it is deployed to. Unfortunately when this is specified, it limits where a pod can actually be scheduled in a cluster.
|
||||
|
||||
Much of this configuration can be found in the `securityContext` attribute for both Kubernetes pods and containers. Where configuration is available at both a pod and container level, Polaris validates both.
|
||||
|
||||
## Further Reading
|
||||
- [Kubernetes Docs: Configure a Security Context for a Pod or Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
- [KubeCon 2018 Keynote: Running with Scissors](https://www.youtube.com/watch?v=ltrV-Qmh3oY)
|
||||
- [Kubernetes Security Book](https://kubernetes-security.info/)
|
||||
- [Kubernetes Docs: Set capabilities for a Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container)
|
||||
- [Linux Programmer's Manual: Capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html)
|
||||
- [Kubernetes Docs: Configuration Best Practices](https://kubernetes.io/docs/concepts/configuration/overview/#services)
|
||||
- [Accessing Kubernetes Pods from Outside of the Cluster](http://alesnosek.com/blog/2017/02/14/accessing-kubernetes-pods-from-outside-of-the-cluster/)
|
||||
@@ -0,0 +1,66 @@
|
||||
#### CLI Options
|
||||
|
||||
```
|
||||
# top-level commands
|
||||
audit
|
||||
Runs a one-time audit.
|
||||
dashboard
|
||||
Runs the webserver for Polaris dashboard.
|
||||
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
|
||||
|
||||
# high-level flags
|
||||
-c, --config string
|
||||
Location of Polaris configuration file
|
||||
--disallow-exemptions
|
||||
Disallow any exemptions from configuration file.
|
||||
-h, --help
|
||||
Help for Polaris (same as help command)
|
||||
--kubeconfig string
|
||||
Path to a kubeconfig. Only required if out-of-cluster.
|
||||
--log-level string
|
||||
Logrus log level (default "info")
|
||||
--master string
|
||||
The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.
|
||||
|
||||
# dashboard flags
|
||||
--audit-path string
|
||||
If specified, audits one or more YAML files instead of a cluster
|
||||
--base-path string
|
||||
Path on which the dashboard is served (default "/")
|
||||
--display-name string
|
||||
An optional identifier for the audit
|
||||
--load-audit-file string
|
||||
Runs the dashboard with data saved from a past audit.
|
||||
-p, --port int
|
||||
Port for the dashboard webserver (default 8080)
|
||||
|
||||
# audit flags
|
||||
--audit-path string
|
||||
If specified, audits one or more YAML files instead of a cluster
|
||||
--resource string
|
||||
If specified, audit a specific resource, in the format namespace/kind/version/name, e.g. nginx-ingress/Deployment.apps/v1/default-backend
|
||||
--display-name string
|
||||
An optional identifier for the audit
|
||||
--format string
|
||||
Output format for results - json, yaml, or score (default "json")
|
||||
--output-file string
|
||||
Destination file for audit results
|
||||
--output-url string
|
||||
Destination URL to send audit results
|
||||
--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.
|
||||
|
||||
# webhook flags
|
||||
--disable-webhook-config-installer
|
||||
disable the installer in the webhook server, so it won't install webhook configuration resources during bootstrapping
|
||||
-p, --port int
|
||||
Port for the webhook webserver (default 9876)
|
||||
```
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
# Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
@@ -0,0 +1,107 @@
|
||||
# Contributing
|
||||
|
||||
Issues, whether bugs, tasks, or feature requests are essential for keeping Polaris great. We believe it should be as easy as possible to contribute changes that get things working in your environment. There are a few guidelines that we need contributors to follow so that we can keep on top of things.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project adheres to a [code of conduct](code-of-conduct.md). Please review this document before contributing to this project.
|
||||
|
||||
## Sign the CLA
|
||||
Before you can contribute, you will need to sign the [Contributor License Agreement](https://cla-assistant.io/fairwindsops/polaris).
|
||||
|
||||
## Project Structure
|
||||
|
||||
Polaris is built on top of [controller-runtime](https://github.com/kubernetes-sigs/controller-runtime). It can run in 3 different modes, a dashboard, a webhook, or a reporter that prints or exports validation results. All of these modes make use of the shared `validator` and `config` packages. Adding new validations is possible by only making additions to those packages.
|
||||
|
||||
## Getting Started
|
||||
|
||||
We label issues with the ["good first issue" tag](https://github.com/FairwindsOps/polaris/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) if we believe they'll be a good starting point for new contributors. If you're interested in working on an issue, please start a conversation on that issue, and we can help answer any questions as they come up.
|
||||
|
||||
## Setting Up Your Development Environment
|
||||
### Prerequisites
|
||||
* A properly configured Golang environment with Go 1.11 or higher
|
||||
* If you want to see the local changes you make on a Polaris dashboard, you will need access to a Kubernetes cluster defined in `~/.kube/config`
|
||||
|
||||
### Installation
|
||||
* Install the project with `go get github.com/fairwindsops/polaris`
|
||||
* Change into the polaris directory which is installed at `$GOPATH/src/github.com/fairwindsops/polaris`
|
||||
* See the dashboard with `go run main.go dashboard`, then open http://localhost:8080/
|
||||
* See the audit data `go run main.go audit`. This command shows the audit information on the command line.
|
||||
|
||||
## Running Tests
|
||||
|
||||
The following commands are all required to pass as part of Polaris testing:
|
||||
|
||||
```
|
||||
go list ./... | grep -v vendor | xargs golint -set_exit_status
|
||||
go list ./... | grep -v vendor | xargs go vet
|
||||
go test ./pkg/... -v -coverprofile cover.out
|
||||
```
|
||||
|
||||
## Creating a New Issue
|
||||
|
||||
If you've encountered an issue that is not already reported, please create a [new issue](https://github.com/FairwindsOps/polaris/issues), choose `Bug Report`, `Feature Request` or `Misc.` and follow the instructions in the template.
|
||||
|
||||
|
||||
## Creating a Pull Request
|
||||
|
||||
Each new pull request should:
|
||||
|
||||
- Reference any related issues
|
||||
- Add tests that show the issues have been solved
|
||||
- Pass existing tests and linting
|
||||
- Contain a clear indication of if they're ready for review or a work in progress
|
||||
- Be up to date and/or rebased on the master branch
|
||||
|
||||
## Creating a new release
|
||||
|
||||
### 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:
|
||||
1. stable/polaris/README.md
|
||||
2. stable/polaris/Chart.yaml
|
||||
3. stable/polaris/values.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
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# Check Settings
|
||||
Each check can be assigned a `severity`. Only checks with a severity of `danger` or `warning` will be validated. The results of these validations are visible on the dashboard. In the case of the validating webhook, only failures with a severity of `danger` will result in a change being rejected.
|
||||
|
||||
Polaris validation checks fall into several different categories:
|
||||
|
||||
- [Security](/checks/security.md)
|
||||
- [Reliability](/checks/reliability.md)
|
||||
- [Efficiency](/checks/efficiency.md)
|
||||
|
||||
To change the default severity levels, or to turn checks on or off, you can create your own `config.yaml`:
|
||||
```yaml
|
||||
checks:
|
||||
tagNotSpecified: ignore
|
||||
runAsRootAllowed: danger
|
||||
pullPolicyNotAlways: warning
|
||||
```
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# Configuration
|
||||
|
||||
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)
|
||||
* Change the [severity level](checks.md) of checks
|
||||
* Add new [custom checks](custom-checks.md)
|
||||
* Add [exemptions](exemptions.md) for particular workloads or namespaces
|
||||
|
||||
To pass in your custom configuration, follow the instructions for your environment:
|
||||
|
||||
* CLI - set the `--config` argument to point to your `config.yaml`
|
||||
* Helm - set the `config` variable in your values file
|
||||
* kubectl - create a ConfigMap with your `config.yaml`, mount it as a volume, and use the `--config` argument in your Deployment
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# Custom Checks
|
||||
If you'd like to create your own checks, you can use [JSON Schema](https://json-schema.org/). For example,
|
||||
to disallow images from quay.io:
|
||||
|
||||
```yaml
|
||||
checks:
|
||||
imageRegistry: warning
|
||||
customChecks:
|
||||
imageRegistry:
|
||||
successMessage: Image comes from allowed registries
|
||||
failureMessage: Image should not be from disallowed registry
|
||||
category: Images
|
||||
target: Container # target can be "Container" or "Pod"
|
||||
schema:
|
||||
'$schema': http://json-schema.org/draft-07/schema
|
||||
type: object
|
||||
properties:
|
||||
image:
|
||||
type: string
|
||||
not:
|
||||
pattern: ^quay.io
|
||||
```
|
||||
|
||||
Schemas can also be specified as JSON strings instead of YAML, for easier copy/pasting:
|
||||
```yaml
|
||||
customChecks:
|
||||
foo:
|
||||
jsonSchema: |
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"type": "object"
|
||||
}
|
||||
```
|
||||
|
||||
We extend JSON Schema with `resourceMinimum` and `resourceMaximum` fields to help compare memory and CPU resource
|
||||
strings like `1000m` and `1G`. You can see an example in [the extended config](https://github.com/FairwindsOps/polaris/tree/master/examples/config-full.yaml)
|
||||
|
||||
There are additional examples in the [checks folder](https://github.com/FairwindsOps/polaris/tree/master/checks).
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Exemptions
|
||||
Sometimes a workload really does need to do things that Polaris considers insecure. For instance,
|
||||
many of the `kube-system` workloads need to run as root, or need access to the host network. In these
|
||||
cases, we can add **exemptions** to allow the workload to pass Polaris checks.
|
||||
|
||||
Exemptions can be added two ways: by annotating a controller, or editing the Polaris config.
|
||||
|
||||
## Annotations
|
||||
To exempt a controller from all checks via annotations, use the annotation `polaris.fairwinds.com/exempt=true`, e.g.
|
||||
```
|
||||
kubectl annotate deployment my-deployment polaris.fairwinds.com/exempt=true
|
||||
```
|
||||
|
||||
To exempt a controller from a particular check via annotations, use an annotation in the form of `polaris.fairwinds.com/<check>-exempt=true`, e.g.
|
||||
```
|
||||
kubectl annotate deployment my-deployment polaris.fairwinds.com/cpuRequestsMissing-exempt=true
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
To exempt a controller via the config, you have to specify a namespace (optional), a list of controller names and a list of rules, e.g.
|
||||
```yaml
|
||||
exemptions:
|
||||
# exemption valid for kube-system namespace
|
||||
- namespace: kube-system
|
||||
controllerNames:
|
||||
- dns-controller
|
||||
rules:
|
||||
- hostNetworkSet
|
||||
# exemption valid in all namespaces
|
||||
- controllerNames:
|
||||
- dns-controller
|
||||
rules:
|
||||
- hostNetworkSet
|
||||
```
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# Dashboard
|
||||
|
||||
The Polaris dashboard can be installed on a cluster using kubectl or Helm. It
|
||||
can also be run locally, connecting to your cluster using the credentials stored in your `KUBECONFIG`.
|
||||
|
||||
The dashboard is a good way to understand what workloads inside your cluster or Infrastructure as Code
|
||||
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
|
||||
helm upgrade --install polaris fairwinds-stable/polaris --namespace polaris
|
||||
kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80
|
||||
```
|
||||
|
||||
### Local Binary
|
||||
You'll need a valid `KUBECONFIG` set up for the dashboard to connect to your cluster.
|
||||
|
||||
Binary releases can be dowloaded from the [releases page](https://github.com/fairwindsops/polaris/releases)
|
||||
or can be installed with [Homebrew](https://brew.sh/):
|
||||
```bash
|
||||
brew tap reactiveops/tap
|
||||
brew install reactiveops/tap/polaris
|
||||
polaris dashboard --port 8080
|
||||
```
|
||||
|
||||
You can also point the dashboard to the local filesystem, instead of a live cluster:
|
||||
```bash
|
||||
polaris dashboard --port 8080 --audit-path=./deploy/
|
||||
```
|
||||
|
||||
### Local Docker container
|
||||
|
||||
```
|
||||
docker run -d -p8080:8080 -v ~/.kube/config:/opt/app/config:ro quay.io/fairwinds/polaris:1.2 polaris dashboard --kubeconfig /opt/app/config
|
||||
```
|
||||
|
||||
## Using the Dashboard
|
||||
The Polaris dashboard is a way to get a simple visual overview of the current state of your Kubernetes workloads as well as a roadmap for what can be improved. The dashboard provides a cluster wide overview as well as breaking out results by category, namespace, and workload.
|
||||
|
||||
<p align="center">
|
||||
<img src="/img/dashboard-screenshot.png" alt="Polaris Dashboard" width="550"/>
|
||||
</p>
|
||||
|
||||
Our default standards in Polaris are rather high, so don’t be surprised if your score is lower than you might expect. A key goal for Polaris was to set a high standard and aim for great configuration by default. If the defaults we’ve included are too strict, it’s easy to adjust the configuration as part of the deployment configuration to better suit your workloads.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Infrastructure as Code
|
||||
Polaris can be used on the command line to audit local Kubernetes manifests stored in YAML files.
|
||||
This is particularly helpful for running Polaris against your infrastructure-as-code as part of a
|
||||
CI/CD pipeline. Use the available [command line flags](#running-in-a-ci-pipeline)
|
||||
to cause CI/CD to fail if your Polaris score drops below a certain threshold, or if any danger-level issues arise.
|
||||
|
||||
|
||||
## Install the CLI
|
||||
To run Polaris against your YAML manifests, e.g. as part of a Continuous Integration process,
|
||||
you'll need to install the CLI.
|
||||
|
||||
Binary releases can be downloaded from the [releases page](https://github.com/fairwindsops/polaris/releases)
|
||||
or can be installed with [Homebrew](https://brew.sh/):
|
||||
```bash
|
||||
brew tap FairwindsOps/tap
|
||||
brew install FairwindsOps/tap/polaris
|
||||
polaris version
|
||||
```
|
||||
|
||||
## Running in a CI pipeline
|
||||
You can tell the CLI to set an exit code if it detects certain issues with your
|
||||
YAML files.
|
||||
For example, to fail if polaris detects *any* danger-level issues, or if the score drops below 90%:
|
||||
```bash
|
||||
polaris audit --audit-path ./deploy/ \
|
||||
--set-exit-code-on-danger \
|
||||
--set-exit-code-below-score 90
|
||||
```
|
||||
|
||||
Generated
+10676
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "fairwinds-docs-template",
|
||||
"version": "0.0.1",
|
||||
"description": "A repository with a Vuepress template for Fairwinds projects",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
"doc": "docs"
|
||||
},
|
||||
"scripts": {
|
||||
"check-links": "vuepress check-md",
|
||||
"build": "npm run build:readme && npm run build:docs && npm run reset-cname",
|
||||
"build:readme": "cat ../README.md | grep -v 'ocumentation' | sed \"s/https:\\/\\/\\w\\+.docs.fairwinds.com//g\" > README.md",
|
||||
"build:docs": "vuepress build -d ../docs/ && touch ../docs/CNAME && git checkout -- ../docs/CNAME",
|
||||
"reset-cname": "touch ../docs/CNAME && git checkout -- ../docs/CNAME",
|
||||
"serve": "vuepress dev --port 3003",
|
||||
"vuepress": "vuepress"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/FairwindsOps/insights-docs.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/FairwindsOps/insights-docs/issues"
|
||||
},
|
||||
"homepage": "https://github.com/FairwindsOps/insights-docs#readme",
|
||||
"devDependencies": {
|
||||
"vuepress": "^1.4.0",
|
||||
"vuepress-plugin-clean-urls": "^1.1.1",
|
||||
"vuepress-plugin-redirect": "^1.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"vuepress-plugin-check-md": "0.0.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Fairwinds Polaris Documentation</title>
|
||||
<meta name="generator" content="VuePress 1.7.1">
|
||||
<link rel="icon" href="/favicon.png">
|
||||
<script src="/scripts/modify.js"></script>
|
||||
<script src="/scripts/leadlander.js"></script>
|
||||
<meta name="description" content="Documentation for Fairwinds Polaris - audit and enforce Kubernetes best practices for your workloads">
|
||||
|
||||
<link rel="preload" href="/assets/css/0.styles.db69974e.css" as="style"><link rel="preload" href="/assets/js/app.65b94829.js" as="script"><link rel="preload" href="/assets/js/7.dbd47d64.js" as="script"><link rel="prefetch" href="/assets/js/10.9d1a1701.js"><link rel="prefetch" href="/assets/js/11.d7eadcf0.js"><link rel="prefetch" href="/assets/js/12.85c0eab0.js"><link rel="prefetch" href="/assets/js/13.0487faf0.js"><link rel="prefetch" href="/assets/js/14.60ea393e.js"><link rel="prefetch" href="/assets/js/15.00f25aaa.js"><link rel="prefetch" href="/assets/js/16.cb0515ce.js"><link rel="prefetch" href="/assets/js/17.013e9969.js"><link rel="prefetch" href="/assets/js/18.a0fcb2d2.js"><link rel="prefetch" href="/assets/js/19.9fe045af.js"><link rel="prefetch" href="/assets/js/2.28adca5d.js"><link rel="prefetch" href="/assets/js/20.5bcacf34.js"><link rel="prefetch" href="/assets/js/21.2f58615f.js"><link rel="prefetch" href="/assets/js/22.90ebc6b9.js"><link rel="prefetch" href="/assets/js/3.0cb25b42.js"><link rel="prefetch" href="/assets/js/4.be9896b6.js"><link rel="prefetch" href="/assets/js/5.665b3e6a.js"><link rel="prefetch" href="/assets/js/6.a5e340ed.js"><link rel="prefetch" href="/assets/js/8.5a82b7c2.js"><link rel="prefetch" href="/assets/js/9.4f55b6b3.js">
|
||||
<link rel="stylesheet" href="/assets/css/0.styles.db69974e.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" data-server-rendered="true"><div class="theme-container"><div class="theme-default-content"><h1>404</h1> <blockquote>Looks like we've got some broken links.</blockquote> <a href="/" class="router-link-active">
|
||||
Take me home.
|
||||
</a></div></div><div class="global-ui"></div></div>
|
||||
<script src="/assets/js/app.65b94829.js" defer></script><script src="/assets/js/7.dbd47d64.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
polaris.docs.fairwinds.com
|
||||
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Admission Controller | Fairwinds Polaris Documentation</title>
|
||||
<meta name="generator" content="VuePress 1.7.1">
|
||||
<link rel="icon" href="/favicon.png">
|
||||
<script src="/scripts/modify.js"></script>
|
||||
<script src="/scripts/leadlander.js"></script>
|
||||
<meta name="description" content="Documentation for Fairwinds Polaris - audit and enforce Kubernetes best practices for your workloads">
|
||||
|
||||
<link rel="preload" href="/assets/css/0.styles.db69974e.css" as="style"><link rel="preload" href="/assets/js/app.65b94829.js" as="script"><link rel="preload" href="/assets/js/3.0cb25b42.js" as="script"><link rel="preload" href="/assets/js/2.28adca5d.js" as="script"><link rel="preload" href="/assets/js/9.4f55b6b3.js" as="script"><link rel="prefetch" href="/assets/js/10.9d1a1701.js"><link rel="prefetch" href="/assets/js/11.d7eadcf0.js"><link rel="prefetch" href="/assets/js/12.85c0eab0.js"><link rel="prefetch" href="/assets/js/13.0487faf0.js"><link rel="prefetch" href="/assets/js/14.60ea393e.js"><link rel="prefetch" href="/assets/js/15.00f25aaa.js"><link rel="prefetch" href="/assets/js/16.cb0515ce.js"><link rel="prefetch" href="/assets/js/17.013e9969.js"><link rel="prefetch" href="/assets/js/18.a0fcb2d2.js"><link rel="prefetch" href="/assets/js/19.9fe045af.js"><link rel="prefetch" href="/assets/js/20.5bcacf34.js"><link rel="prefetch" href="/assets/js/21.2f58615f.js"><link rel="prefetch" href="/assets/js/22.90ebc6b9.js"><link rel="prefetch" href="/assets/js/4.be9896b6.js"><link rel="prefetch" href="/assets/js/5.665b3e6a.js"><link rel="prefetch" href="/assets/js/6.a5e340ed.js"><link rel="prefetch" href="/assets/js/7.dbd47d64.js"><link rel="prefetch" href="/assets/js/8.5a82b7c2.js">
|
||||
<link rel="stylesheet" href="/assets/css/0.styles.db69974e.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/img/fairwinds-logo.svg" alt="Fairwinds Polaris Documentation" class="logo"> <span class="site-name can-hide">Fairwinds Polaris Documentation</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="https://github.com/FairwindsOps/polaris" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
||||
View on GitHub
|
||||
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="https://github.com/FairwindsOps/polaris" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
||||
View on GitHub
|
||||
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <!----></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><a href="/" class="sidebar-heading clickable router-link-active"><span>Polaris</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/changelog/" class="sidebar-link">Changelog</a></li><li><a href="/code-of-conduct/" class="sidebar-link">Code of Conduct</a></li><li><a href="/contributing/" class="sidebar-link">Contributing</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Ways to Run Polaris</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/dashboard/" class="sidebar-link">Dashboard</a></li><li><a href="/admission-controller/" aria-current="page" class="active sidebar-link">Admission Controller</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/admission-controller/#installation" class="sidebar-link">Installation</a></li><li class="sidebar-sub-header"><a href="/admission-controller/#workload-types" class="sidebar-link">Workload Types</a></li><li class="sidebar-sub-header"><a href="/admission-controller/#warnings" class="sidebar-link">Warnings</a></li></ul></li><li><a href="/infrastructure-as-code/" class="sidebar-link">Infrastructure as Code</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Customization</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/customization/configuration/" class="sidebar-link">Configuration</a></li><li><a href="/customization/checks/" class="sidebar-link">Check Settings</a></li><li><a href="/customization/custom-checks/" class="sidebar-link">Custom Checks</a></li><li><a href="/customization/exemptions/" class="sidebar-link">Exemptions</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Checks</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/checks/security/" class="sidebar-link">Security</a></li><li><a href="/checks/efficiency/" class="sidebar-link">Efficiency</a></li><li><a href="/checks/reliability/" class="sidebar-link">Reliability</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="admission-controller"><a href="#admission-controller" class="header-anchor">#</a> Admission Controller</h1> <p>Polaris can be run as an admission controller that acts as a validating webhook.
|
||||
This accepts the same configuration as the dashboard, and can run the same validations.</p> <p>The webhook will reject any workloads that trigger a danger-level check.
|
||||
This is indicative of the greater goal of Polaris, not just to encourage better
|
||||
configuration through dashboard visibility, but to actually enforce it with this webhook.</p> <p>Note that Polaris will not alter your workloads, only block workloads that don't conform to the configured policies.</p> <h2 id="installation"><a href="#installation" class="header-anchor">#</a> Installation</h2> <h3 id="kubectl"><a href="#kubectl" class="header-anchor">#</a> kubectl</h3> <div class="language-bash extra-class"><pre class="language-bash"><code>kubectl apply -f https://github.com/fairwindsops/polaris/releases/latest/download/webhook.yaml
|
||||
</code></pre></div><h3 id="helm"><a href="#helm" class="header-anchor">#</a> Helm</h3> <div class="language-bash extra-class"><pre class="language-bash"><code>helm repo <span class="token function">add</span> fairwindsops-stable https://charts.fairwindsops.com/stable
|
||||
helm upgrade --install polaris fairwindsops-stable/polaris --namespace polaris <span class="token punctuation">\</span>
|
||||
--set webhook.enable<span class="token operator">=</span>true --set dashboard.enable<span class="token operator">=</span>false
|
||||
</code></pre></div><h2 id="workload-types"><a href="#workload-types" class="header-anchor">#</a> Workload Types</h2> <p>The webhook comes with built-in support for a handful of known controller types,
|
||||
such as Deployments, Jobs, and DaemonSets. To add new controller types,
|
||||
you can set <code>webhook.rules</code> in the
|
||||
<a href="https://github.com/FairwindsOps/charts/tree/master/stable/polaris" target="_blank" rel="noopener noreferrer">Helm chart<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h2 id="warnings"><a href="#warnings" class="header-anchor">#</a> Warnings</h2> <p>Unfortunately we have not found a way to display warnings as part of <code>kubectl</code>
|
||||
output unless we are rejecting a workload altogether.</p> <p>This means that any checks with a severity of <code>warning</code> 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.</p></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/FairwindsOps/polaris/edit/master/docs-md/admission-controller.md" target="_blank" rel="noopener noreferrer">Help us improve this page</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
|
||||
←
|
||||
<a href="/dashboard/" class="prev">
|
||||
Dashboard
|
||||
</a></span> <span class="next"><a href="/infrastructure-as-code/">
|
||||
Infrastructure as Code
|
||||
</a>
|
||||
→
|
||||
</span></p></div> <div class="custom-footer"><div class="left-footer"><a href="https://fairwinds.com" target="_blank">Learn more about Fairwinds</a> <a href="https://fairwinds.com/insights" target="_blank">Try Fairwinds Insights</a></div> <div class="right-footer"><a href="https://www.fairwinds.com/privacy-policy" target="_blank">Privacy Policy</a></div></div></main></div><div class="global-ui"></div></div>
|
||||
<script src="/assets/js/app.65b94829.js" defer></script><script src="/assets/js/3.0cb25b42.js" defer></script><script src="/assets/js/2.28adca5d.js" defer></script><script src="/assets/js/9.4f55b6b3.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13"><g stroke-width="2" stroke="#aaa" fill="none"><path d="M11.29 11.71l-4-4"/><circle cx="5" cy="5" r="4"/></g></svg>
|
||||
|
After Width: | Height: | Size: 216 B |
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[11],{373:function(e,t,r){"use strict";r.r(t);var s=r(42),o=Object(s.a)({},(function(){var e=this,t=e.$createElement,r=e._self._c||t;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h1",{attrs:{id:"efficiency"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#efficiency"}},[e._v("#")]),e._v(" Efficiency")]),e._v(" "),r("p",[e._v("These checks ensure that CPU and memory settings are configured, so that\nKubernetes can schedule your workload effectively.")]),e._v(" "),r("h2",{attrs:{id:"presence-checks"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#presence-checks"}},[e._v("#")]),e._v(" Presence Checks")]),e._v(" "),r("p",[e._v("To simplify ensure that these values have been set, the following attributes are available:")]),e._v(" "),r("table",[r("thead",[r("tr",[r("th",[e._v("key")]),e._v(" "),r("th",[e._v("default")]),e._v(" "),r("th",[e._v("description")])])]),e._v(" "),r("tbody",[r("tr",[r("td",[r("code",[e._v("resources.cpuRequestsMissing")])]),e._v(" "),r("td",[r("code",[e._v("warning")])]),e._v(" "),r("td",[e._v("Fails when "),r("code",[e._v("resources.requests.cpu")]),e._v(" attribute is not configured.")])]),e._v(" "),r("tr",[r("td",[r("code",[e._v("resources.memoryRequestsMissing")])]),e._v(" "),r("td",[r("code",[e._v("warning")])]),e._v(" "),r("td",[e._v("Fails when "),r("code",[e._v("resources.requests.memory")]),e._v(" attribute is not configured.")])]),e._v(" "),r("tr",[r("td",[r("code",[e._v("resources.cpuLimitsMissing")])]),e._v(" "),r("td",[r("code",[e._v("warning")])]),e._v(" "),r("td",[e._v("Fails when "),r("code",[e._v("resources.limits.cpu")]),e._v(" attribute is not configured.")])]),e._v(" "),r("tr",[r("td",[r("code",[e._v("resources.memoryLimitsMissing")])]),e._v(" "),r("td",[r("code",[e._v("warning")])]),e._v(" "),r("td",[e._v("Fails when "),r("code",[e._v("resources.limits.memory")]),e._v(" attribute is not configured.")])])])]),e._v(" "),r("h2",{attrs:{id:"background"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#background"}},[e._v("#")]),e._v(" Background")]),e._v(" "),r("p",[e._v("Configuring resource requests and limits for containers running in Kubernetes is an important best practice to follow. Setting appropriate resource requests will ensure that all your applications have sufficient compute resources. Setting appropriate resource limits will ensure that your applications do not consume too many resources.")]),e._v(" "),r("p",[e._v("Having these values appropriately configured ensures that:")]),e._v(" "),r("ul",[r("li",[r("p",[e._v("Cluster autoscaling can function as intended. New nodes are scheduled once pods are unable to be scheduled on an existing node due to insufficient resources. This will not happen if resource requests are not configured.")])]),e._v(" "),r("li",[r("p",[e._v("Each container has sufficient access to compute resources. Without resource requests, a pod may be scheduled on a node that is already overutilized. Without resource limits, a single poorly behaving pod could utilize the majority of resources on a node, significantly impacting the performance of other pods on the same node.")])])]),e._v(" "),r("h2",{attrs:{id:"further-reading"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#further-reading"}},[e._v("#")]),e._v(" Further Reading")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Kubernetes Docs: Managing Compute Resources for Containers"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-resource-requests-and-limits",target:"_blank",rel:"noopener noreferrer"}},[e._v("Kubernetes best practices: Resource requests and limits"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler",target:"_blank",rel:"noopener noreferrer"}},[e._v("Vertical Pod Autoscaler (can automatically set resource requests and limits)"),r("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=o.exports}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[14],{371:function(e,n,t){"use strict";t.r(n);var s=t(42),i=Object(s.a)({},(function(){var e=this.$createElement,n=this._self._c||e;return n("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[n("h4",{attrs:{id:"cli-options"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#cli-options"}},[this._v("#")]),this._v(" CLI Options")]),this._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[this._v('# top-level commands\naudit\n Runs a one-time audit.\ndashboard\n Runs the webserver for Polaris dashboard.\nhelp\n Prints help, if you give it a command then it will print help for that command. Same as -h\nversion\n Prints the version of Polaris\nwebhook\n Runs the webhook webserver\n\n# high-level flags\n-c, --config string\n Location of Polaris configuration file\n--disallow-exemptions\n Disallow any exemptions from configuration file.\n-h, --help\n Help for Polaris (same as help command)\n--kubeconfig string\n Path to a kubeconfig. Only required if out-of-cluster.\n--log-level string\n Logrus log level (default "info")\n--master string\n The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.\n\n# dashboard flags\n--audit-path string\n If specified, audits one or more YAML files instead of a cluster\n--base-path string\n Path on which the dashboard is served (default "/")\n--display-name string\n An optional identifier for the audit\n--load-audit-file string\n Runs the dashboard with data saved from a past audit.\n-p, --port int\n Port for the dashboard webserver (default 8080)\n\n# audit flags\n--audit-path string\n If specified, audits one or more YAML files instead of a cluster\n--resource string\n If specified, audit a specific resource, in the format namespace/kind/version/name, e.g. nginx-ingress/Deployment.apps/v1/default-backend\n--display-name string\n An optional identifier for the audit\n--format string\n Output format for results - json, yaml, or score (default "json")\n--output-file string\n Destination file for audit results\n--output-url string\n Destination URL to send audit results\n--set-exit-code-below-score int\n Set an exit code of 4 when the score is below this threshold (1-100)\n--set-exit-code-on-danger\n Set an exit code of 3 when the audit contains danger-level issues.\n\n# webhook flags\n--disable-webhook-config-installer\n disable the installer in the webhook server, so it won\'t install webhook configuration resources during bootstrapping\n-p, --port int\n Port for the webhook webserver (default 9876)\n')])])])])}),[],!1,null,null,null);n.default=i.exports}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{368:function(e,t,a){"use strict";a.r(t);var s=a(42),n=Object(s.a)({},(function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[a("h1",{attrs:{id:"check-settings"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#check-settings"}},[e._v("#")]),e._v(" Check Settings")]),e._v(" "),a("p",[e._v("Each check can be assigned a "),a("code",[e._v("severity")]),e._v(". Only checks with a severity of "),a("code",[e._v("danger")]),e._v(" or "),a("code",[e._v("warning")]),e._v(" will be validated. The results of these validations are visible on the dashboard. In the case of the validating webhook, only failures with a severity of "),a("code",[e._v("danger")]),e._v(" will result in a change being rejected.")]),e._v(" "),a("p",[e._v("Polaris validation checks fall into several different categories:")]),e._v(" "),a("ul",[a("li",[a("RouterLink",{attrs:{to:"/checks/security.html"}},[e._v("Security")])],1),e._v(" "),a("li",[a("RouterLink",{attrs:{to:"/checks/reliability.html"}},[e._v("Reliability")])],1),e._v(" "),a("li",[a("RouterLink",{attrs:{to:"/checks/efficiency.html"}},[e._v("Efficiency")])],1)]),e._v(" "),a("p",[e._v("To change the default severity levels, or to turn checks on or off, you can create your own "),a("code",[e._v("config.yaml")]),e._v(":")]),e._v(" "),a("div",{staticClass:"language-yaml extra-class"},[a("pre",{pre:!0,attrs:{class:"language-yaml"}},[a("code",[a("span",{pre:!0,attrs:{class:"token key atrule"}},[e._v("checks")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token key atrule"}},[e._v("tagNotSpecified")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" ignore\n "),a("span",{pre:!0,attrs:{class:"token key atrule"}},[e._v("runAsRootAllowed")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" danger\n "),a("span",{pre:!0,attrs:{class:"token key atrule"}},[e._v("pullPolicyNotAlways")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" warning\n")])])])])}),[],!1,null,null,null);t.default=n.exports}}]);
|
||||
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[18],{369:function(t,o,e){"use strict";e.r(o);var n=e(42),i=Object(n.a)({},(function(){var t=this,o=t.$createElement,e=t._self._c||o;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"configuration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),e("p",[t._v("The default Polaris configuration can be "),e("a",{attrs:{href:"https://github.com/FairwindsOps/polaris/blob/master/examples/config.yaml",target:"_blank",rel:"noopener noreferrer"}},[t._v("seen here"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("You can customize the configuration to do things like:")]),t._v(" "),e("ul",[e("li",[t._v("Turn checks "),e("RouterLink",{attrs:{to:"/customization/checks.html"}},[t._v("on and off")])],1),t._v(" "),e("li",[t._v("Change the "),e("RouterLink",{attrs:{to:"/customization/checks.html"}},[t._v("severity level")]),t._v(" of checks")],1),t._v(" "),e("li",[t._v("Add new "),e("RouterLink",{attrs:{to:"/customization/custom-checks.html"}},[t._v("custom checks")])],1),t._v(" "),e("li",[t._v("Add "),e("RouterLink",{attrs:{to:"/customization/exemptions.html"}},[t._v("exemptions")]),t._v(" for particular workloads or namespaces")],1)]),t._v(" "),e("p",[t._v("To pass in your custom configuration, follow the instructions for your environment:")]),t._v(" "),e("ul",[e("li",[t._v("CLI - set the "),e("code",[t._v("--config")]),t._v(" argument to point to your "),e("code",[t._v("config.yaml")])]),t._v(" "),e("li",[t._v("Helm - set the "),e("code",[t._v("config")]),t._v(" variable in your values file")]),t._v(" "),e("li",[t._v("kubectl - create a ConfigMap with your "),e("code",[t._v("config.yaml")]),t._v(", mount it as a volume, and use the "),e("code",[t._v("--config")]),t._v(" argument in your Deployment")])])])}),[],!1,null,null,null);o.default=i.exports}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{376:function(t,a,e){"use strict";e.r(a);var s=e(42),n=Object(s.a)({},(function(){var t=this,a=t.$createElement,e=t._self._c||a;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"exemptions"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#exemptions"}},[t._v("#")]),t._v(" Exemptions")]),t._v(" "),e("p",[t._v("Sometimes a workload really does need to do things that Polaris considers insecure. For instance,\nmany of the "),e("code",[t._v("kube-system")]),t._v(" workloads need to run as root, or need access to the host network. In these\ncases, we can add "),e("strong",[t._v("exemptions")]),t._v(" to allow the workload to pass Polaris checks.")]),t._v(" "),e("p",[t._v("Exemptions can be added two ways: by annotating a controller, or editing the Polaris config.")]),t._v(" "),e("h2",{attrs:{id:"annotations"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#annotations"}},[t._v("#")]),t._v(" Annotations")]),t._v(" "),e("p",[t._v("To exempt a controller from all checks via annotations, use the annotation "),e("code",[t._v("polaris.fairwinds.com/exempt=true")]),t._v(", e.g.")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("kubectl annotate deployment my-deployment polaris.fairwinds.com/exempt=true\n")])])]),e("p",[t._v("To exempt a controller from a particular check via annotations, use an annotation in the form of "),e("code",[t._v("polaris.fairwinds.com/<check>-exempt=true")]),t._v(", e.g.")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("kubectl annotate deployment my-deployment polaris.fairwinds.com/cpuRequestsMissing-exempt=true\n")])])]),e("h2",{attrs:{id:"config"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#config"}},[t._v("#")]),t._v(" Config")]),t._v(" "),e("p",[t._v("To exempt a controller via the config, you have to specify a namespace (optional), a list of controller names and a list of rules, e.g.")]),t._v(" "),e("div",{staticClass:"language-yaml extra-class"},[e("pre",{pre:!0,attrs:{class:"language-yaml"}},[e("code",[e("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("exemptions")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# exemption valid for kube-system namespace")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("namespace")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" kube"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v("system\n "),e("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("controllerNames")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" dns"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v("controller\n "),e("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("rules")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" hostNetworkSet\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# exemption valid in all namespaces")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("controllerNames")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" dns"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v("controller\n "),e("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("rules")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" hostNetworkSet\n")])])])])}),[],!1,null,null,null);a.default=n.exports}}]);
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[22],{372:function(e,a,s){"use strict";s.r(a);var t=s(42),n=Object(t.a)({},(function(){var e=this,a=e.$createElement,s=e._self._c||a;return s("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[s("h1",{attrs:{id:"infrastructure-as-code"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#infrastructure-as-code"}},[e._v("#")]),e._v(" Infrastructure as Code")]),e._v(" "),s("p",[e._v("Polaris can be used on the command line to audit local Kubernetes manifests stored in YAML files.\nThis is particularly helpful for running Polaris against your infrastructure-as-code as part of a\nCI/CD pipeline. Use the available "),s("a",{attrs:{href:"#running-in-a-ci-pipeline"}},[e._v("command line flags")]),e._v("\nto cause CI/CD to fail if your Polaris score drops below a certain threshold, or if any danger-level issues arise.")]),e._v(" "),s("h2",{attrs:{id:"install-the-cli"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#install-the-cli"}},[e._v("#")]),e._v(" Install the CLI")]),e._v(" "),s("p",[e._v("To run Polaris against your YAML manifests, e.g. as part of a Continuous Integration process,\nyou'll need to install the CLI.")]),e._v(" "),s("p",[e._v("Binary releases can be downloaded from the "),s("a",{attrs:{href:"https://github.com/fairwindsops/polaris/releases",target:"_blank",rel:"noopener noreferrer"}},[e._v("releases page"),s("OutboundLink")],1),e._v("\nor can be installed with "),s("a",{attrs:{href:"https://brew.sh/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Homebrew"),s("OutboundLink")],1),e._v(":")]),e._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[e._v("brew tap FairwindsOps/tap\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[e._v("install")]),e._v(" FairwindsOps/tap/polaris\npolaris version\n")])])]),s("h2",{attrs:{id:"running-in-a-ci-pipeline"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#running-in-a-ci-pipeline"}},[e._v("#")]),e._v(" Running in a CI pipeline")]),e._v(" "),s("p",[e._v("You can tell the CLI to set an exit code if it detects certain issues with your\nYAML files.\nFor example, to fail if polaris detects "),s("em",[e._v("any")]),e._v(" danger-level issues, or if the score drops below 90%:")]),e._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[e._v("polaris audit --audit-path ./deploy/ "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("\\")]),e._v("\n --set-exit-code-on-danger "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("\\")]),e._v("\n --set-exit-code-below-score "),s("span",{pre:!0,attrs:{class:"token number"}},[e._v("90")]),e._v("\n")])])])])}),[],!1,null,null,null);a.default=n.exports}}]);
|
||||
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{326:function(t,a,s){},355:function(t,a,s){"use strict";s(326)},362:function(t,a,s){"use strict";s.r(a);var n={name:"Layout",components:{ParentLayout:s(359).a}},r=(s(355),s(42)),i=Object(r.a)(n,(function(){var t=this,a=t.$createElement,s=t._self._c||a;return s("ParentLayout",{scopedSlots:t._u([{key:"page-bottom",fn:function(){return[s("div",{staticClass:"custom-footer"},[s("div",{staticClass:"left-footer"},[s("a",{attrs:{href:"https://fairwinds.com",target:"_blank"}},[t._v("Learn more about Fairwinds")]),t._v(" "),s("a",{attrs:{href:"https://fairwinds.com/insights",target:"_blank"}},[t._v("Try Fairwinds Insights")])]),t._v(" "),s("div",{staticClass:"right-footer"},[s("a",{attrs:{href:"https://www.fairwinds.com/privacy-policy",target:"_blank"}},[t._v("Privacy Policy")])])])]},proxy:!0}])})}),[],!1,null,null,null);a.default=i.exports}}]);
|
||||
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{327:function(t,e,n){},356:function(t,e,n){"use strict";n(327)},374:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:function(t,e){var n=e.props,i=e.slots;return t("span",{class:["badge",n.type],style:{verticalAlign:n.vertical}},n.text||i().default)}},r=(n(356),n(42)),p=Object(r.a)(i,void 0,void 0,!1,null,"15b7b770",null);e.default=p.exports}}]);
|
||||
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[5],{328:function(e,t,c){},357:function(e,t,c){"use strict";c(328)},360:function(e,t,c){"use strict";c.r(t);var i={name:"CodeBlock",props:{title:{type:String,required:!0},active:{type:Boolean,default:!1}}},n=(c(357),c(42)),s=Object(n.a)(i,(function(){var e=this.$createElement;return(this._self._c||e)("div",{staticClass:"theme-code-block",class:{"theme-code-block__active":this.active}},[this._t("default")],2)}),[],!1,null,"6d04095e",null);t.default=s.exports}}]);
|
||||
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[6],{329:function(e,t,o){},358:function(e,t,o){"use strict";o(329)},361:function(e,t,o){"use strict";o.r(t);o(23),o(92),o(65),o(94);var a={name:"CodeGroup",data:function(){return{codeTabs:[],activeCodeTabIndex:-1}},watch:{activeCodeTabIndex:function(e){this.codeTabs.forEach((function(e){e.elm.classList.remove("theme-code-block__active")})),this.codeTabs[e].elm.classList.add("theme-code-block__active")}},mounted:function(){var e=this;this.codeTabs=(this.$slots.default||[]).filter((function(e){return Boolean(e.componentOptions)})).map((function(t,o){return""===t.componentOptions.propsData.active&&(e.activeCodeTabIndex=o),{title:t.componentOptions.propsData.title,elm:t.elm}})),-1===this.activeCodeTabIndex&&this.codeTabs.length>0&&(this.activeCodeTabIndex=0)},methods:{changeCodeTab:function(e){this.activeCodeTabIndex=e}}},c=(o(358),o(42)),n=Object(c.a)(a,(function(){var e=this,t=e.$createElement,o=e._self._c||t;return o("div",{staticClass:"theme-code-group"},[o("div",{staticClass:"theme-code-group__nav"},[o("ul",{staticClass:"theme-code-group__ul"},e._l(e.codeTabs,(function(t,a){return o("li",{key:t.title,staticClass:"theme-code-group__li"},[o("button",{staticClass:"theme-code-group__nav-tab",class:{"theme-code-group__nav-tab-active":a===e.activeCodeTabIndex},on:{click:function(t){return e.changeCodeTab(a)}}},[e._v("\n "+e._s(t.title)+"\n ")])])})),0)]),e._v(" "),e._t("default"),e._v(" "),e.codeTabs.length<1?o("pre",{staticClass:"pre-blank"},[e._v("// Make sure to add code blocks to your code group")]):e._e()],2)}),[],!1,null,"32c2d7ed",null);t.default=n.exports}}]);
|
||||
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[7],{363:function(t,e,s){"use strict";s.r(e);var n=["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],o={methods:{getMsg:function(){return n[Math.floor(Math.random()*n.length)]}}},i=s(42),h=Object(i.a)(o,(function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"theme-container"},[e("div",{staticClass:"theme-default-content"},[e("h1",[this._v("404")]),this._v(" "),e("blockquote",[this._v(this._s(this.getMsg()))]),this._v(" "),e("RouterLink",{attrs:{to:"/"}},[this._v("\n Take me home.\n ")])],1)])}),[],!1,null,null,null);e.default=h.exports}}]);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user