├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── ci.yml │ ├── cosign.pub │ ├── helm-release.yaml │ ├── helm-vib-lint.yaml │ ├── helm-vib.yaml │ ├── publish-release.yaml │ ├── release.yaml │ └── stale.yml ├── .gitignore ├── .golangci.yaml ├── .goreleaser.yml ├── .vib ├── vib-pipeline.json ├── vib-platform-verify-openshift.json ├── vib-platform-verify-skip-recreate.json └── vib-platform-verify.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── MAINTAINERS.md ├── Makefile ├── README.md ├── RELEASE-NOTES.md ├── SECURITY.md ├── carvel └── package.yaml ├── cmd ├── controller │ ├── main.go │ └── main_test.go └── kubeseal │ ├── main.go │ └── main_test.go ├── contrib └── prometheus-mixin │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── alerts │ ├── alerts.libsonnet │ └── sealed-secrets-alerts.libsonnet │ ├── config.libsonnet │ ├── dashboards │ ├── dashboards.libsonnet │ └── sealed-secrets-controller.json │ ├── lib │ ├── alerts.jsonnet │ ├── dashboards.jsonnet │ └── rules.jsonnet │ ├── mixin.libsonnet │ ├── rules │ └── rules.libsonnet │ └── tests.yaml ├── controller-norbac.jsonnet ├── controller-podmonitor.jsonnet ├── controller.jsonnet ├── docker ├── controller.Dockerfile └── kubeseal.Dockerfile ├── docs ├── GKE.md ├── bring-your-own-certificates.md ├── developer │ ├── README.md │ ├── controller.md │ ├── crypto.md │ ├── kubeseal.md │ └── swagger.yml └── examples │ └── config-template │ ├── README.md │ ├── deployment.yaml │ └── sealedsecret.yaml ├── githooks └── pre-commit │ └── doc-toc ├── go.mod ├── go.sum ├── hack ├── boilerplate.go.txt ├── tools.go └── update-codegen.sh ├── helm └── sealed-secrets │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── crds │ └── bitnami.com_sealedsecrets.yaml │ ├── dashboards │ └── sealed-secrets-controller.json │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── cluster-role-binding.yaml │ ├── cluster-role.yaml │ ├── configmap-dashboards.yaml │ ├── deployment.yaml │ ├── extra-list.yaml │ ├── ingress.yaml │ ├── networkpolicy.yaml │ ├── pdb.yaml │ ├── psp-clusterrole.yaml │ ├── psp-clusterrolebinding.yaml │ ├── psp.yaml │ ├── role-binding.yaml │ ├── role.yaml │ ├── service-account.yaml │ ├── service.yaml │ ├── servicemonitor.yaml │ └── tls-secret.yaml │ └── values.yaml ├── integration ├── controller_test.go ├── integration_suite_test.go └── kubeseal_test.go ├── jsonnetfile.json ├── jsonnetfile.lock.json ├── kube-fixes.libsonnet ├── pkg ├── apis │ └── sealedsecrets │ │ └── v1alpha1 │ │ ├── doc.go │ │ ├── register.go │ │ ├── sealedsecret_expansion.go │ │ ├── sealedsecret_test.go │ │ ├── types.go │ │ └── zz_generated.deepcopy.go ├── buildinfo │ └── version.go ├── client │ ├── clientset │ │ └── versioned │ │ │ ├── clientset.go │ │ │ ├── fake │ │ │ ├── clientset_generated.go │ │ │ ├── doc.go │ │ │ └── register.go │ │ │ ├── scheme │ │ │ ├── doc.go │ │ │ └── register.go │ │ │ └── typed │ │ │ └── sealedsecrets │ │ │ └── v1alpha1 │ │ │ ├── doc.go │ │ │ ├── fake │ │ │ ├── doc.go │ │ │ ├── fake_sealedsecret.go │ │ │ └── fake_sealedsecrets_client.go │ │ │ ├── generated_expansion.go │ │ │ ├── sealedsecret.go │ │ │ └── sealedsecrets_client.go │ ├── informers │ │ └── externalversions │ │ │ ├── factory.go │ │ │ ├── generic.go │ │ │ ├── internalinterfaces │ │ │ └── factory_interfaces.go │ │ │ └── sealedsecrets │ │ │ ├── interface.go │ │ │ └── v1alpha1 │ │ │ ├── interface.go │ │ │ └── sealedsecret.go │ └── listers │ │ └── sealedsecrets │ │ └── v1alpha1 │ │ ├── expansion_generated.go │ │ └── sealedsecret.go ├── controller │ ├── controller.go │ ├── controller_test.go │ ├── funcs.go │ ├── keyregistry.go │ ├── keyregistry_test.go │ ├── keys.go │ ├── keys_test.go │ ├── main.go │ ├── main_test.go │ ├── metrics.go │ ├── server.go │ ├── server_test.go │ ├── signal_notwin.go │ └── signal_windows.go ├── crypto │ ├── crypto.go │ ├── keys.go │ └── keys_test.go ├── flagenv │ ├── flagenv.go │ └── flagenv_test.go ├── kubeseal │ ├── kubeseal.go │ └── kubeseal_test.go ├── log │ └── log.go ├── multidocyaml │ ├── multidocyaml.go │ └── multidocyaml_test.go └── pflagenv │ ├── flagenv.go │ └── flagenv_test.go ├── schema-v1alpha1.yaml ├── scripts ├── check-k8s ├── kubeseal-sudo └── release-check ├── site ├── .gitignore ├── .hugo_build.lock ├── README.md ├── archetypes │ └── default.md ├── config.yaml ├── content │ ├── community │ │ └── _index.html │ ├── contributors │ │ ├── agarcia-oss.md │ │ ├── alvneiayu.md │ │ └── index.md │ ├── docs │ │ ├── CONTRIBUTING.md │ │ ├── _index.md │ │ ├── img │ │ │ ├── _index.md │ │ │ └── placeholder-750x250.png │ │ └── latest │ │ │ ├── README.md │ │ │ ├── _index.md │ │ │ ├── background │ │ │ ├── README.md │ │ │ ├── _index.md │ │ │ └── cryptography.md │ │ │ ├── howto │ │ │ ├── README.md │ │ │ ├── _index.md │ │ │ └── validate-sealed-secrets.md │ │ │ ├── project │ │ │ ├── .placeholder │ │ │ ├── _index.md │ │ │ ├── chart-readme.md │ │ │ └── readme.md │ │ │ ├── reference │ │ │ ├── README.md │ │ │ ├── _index.md │ │ │ └── faq.md │ │ │ └── tutorials │ │ │ ├── README.md │ │ │ ├── _index.md │ │ │ ├── getting-started.md │ │ │ └── install-sealed-secrets.md │ ├── posts │ │ └── _index.md │ └── resources │ │ └── _index.html ├── data │ └── docs │ │ ├── latest-toc.yml │ │ └── toc-mapping.yml ├── resources │ └── _gen │ │ └── assets │ │ └── scss │ │ └── scss │ │ ├── site.scss_8967e03afb92eb0cac064520bf021ba2.content │ │ └── site.scss_8967e03afb92eb0cac064520bf021ba2.json └── themes │ └── template │ ├── archetypes │ └── default.md │ ├── assets │ └── scss │ │ ├── _base.scss │ │ ├── _components.scss │ │ ├── _footer.scss │ │ ├── _header.scss │ │ ├── _mixins.scss │ │ ├── _variables.scss │ │ └── site.scss │ ├── layouts │ ├── _default │ │ ├── _markup │ │ │ ├── render-image.html │ │ │ └── render-link.html │ │ ├── baseof.html │ │ ├── docs.html │ │ ├── list.html │ │ ├── posts.html │ │ ├── search.html │ │ ├── section.html │ │ ├── single.html │ │ ├── summary.html │ │ ├── tag.html │ │ └── versions.html │ ├── index.html │ ├── index.redirects │ ├── partials │ │ ├── blog-post-card.html │ │ ├── contributors.html │ │ ├── docs-right-bar.html │ │ ├── docs-sidebar.html │ │ ├── footer.html │ │ ├── getting-started.html │ │ ├── header.html │ │ ├── hero.html │ │ ├── homepage-grid.html │ │ ├── pagination.html │ │ └── use-cases.html │ └── shortcodes │ │ └── readfile.html │ └── static │ ├── fonts │ ├── Metropolis-Bold.eot │ ├── Metropolis-Bold.woff │ ├── Metropolis-Bold.woff2 │ ├── Metropolis-BoldItalic.eot │ ├── Metropolis-BoldItalic.woff │ ├── Metropolis-BoldItalic.woff2 │ ├── Metropolis-Light.eot │ ├── Metropolis-Light.woff │ ├── Metropolis-Light.woff2 │ ├── Metropolis-LightItalic.eot │ ├── Metropolis-LightItalic.woff │ ├── Metropolis-LightItalic.woff2 │ ├── Metropolis-Medium.eot │ ├── Metropolis-Medium.woff │ ├── Metropolis-Medium.woff2 │ ├── Metropolis-MediumItalic.eot │ ├── Metropolis-MediumItalic.woff │ ├── Metropolis-MediumItalic.woff2 │ ├── Metropolis-Regular.eot │ ├── Metropolis-Regular.woff │ ├── Metropolis-Regular.woff2 │ ├── Metropolis-RegularItalic.eot │ ├── Metropolis-RegularItalic.woff │ ├── Metropolis-RegularItalic.woff2 │ ├── Metropolis-SemiBold.eot │ ├── Metropolis-SemiBold.woff │ ├── Metropolis-SemiBold.woff2 │ ├── Metropolis-SemiBoldItalic.eot │ ├── Metropolis-SemiBoldItalic.woff │ ├── Metropolis-SemiBoldItalic.woff2 │ ├── Open Font License.md │ └── README.md │ ├── img │ ├── administration.svg │ ├── arrow.svg │ ├── authentication.svg │ ├── blog-placeholder.png │ ├── calendar.svg │ ├── close.svg │ ├── cloud.svg │ ├── docs-placeholder.png │ ├── down-arrow.svg │ ├── favicon.png │ ├── frictionless.svg │ ├── github-blue.svg │ ├── github-image.svg │ ├── github.svg │ ├── hamburger.svg │ ├── kubernetes.svg │ ├── left-arrow.svg │ ├── right-arrow.svg │ ├── sealedsecrets-logo.svg │ ├── seamless.svg │ ├── search-icon.svg │ ├── security.svg │ ├── simple.svg │ ├── slack.png │ ├── slack.svg │ ├── storagesecure.svg │ ├── team-placeholder.png │ ├── team │ │ ├── agarcia-oss.png │ │ ├── alemorcuq.png │ │ ├── alvneiayu.png │ │ └── josvazg.png │ ├── twitter.png │ ├── vmware-broadcom-logo.svg │ └── youtube.svg │ └── js │ └── main.js ├── vendor_jsonnet └── kube-libsonnet │ ├── .travis.yml │ ├── CODEOWNERS │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── bitnami.libsonnet │ ├── examples │ ├── guestbook │ │ ├── guestbook.jsonnet │ │ └── lib │ └── wordpress │ │ ├── backend.jsonnet │ │ ├── frontend.jsonnet │ │ ├── lib │ │ └── wordpress.jsonnet │ ├── kube.libsonnet │ └── tests │ ├── .env │ ├── Dockerfile │ ├── Makefile │ ├── docker-compose.yaml │ ├── golden │ ├── test-sealedsecrets-datalines.json │ ├── test-sealedsecrets.json │ ├── test-simple-validate.json │ └── unittests.json │ ├── test-sealedsecrets-datalines.jsonnet │ ├── test-sealedsecrets-datalines.txt │ ├── test-sealedsecrets.jsonnet │ ├── test-simple-validate.jsonnet │ └── unittests.jsonnet └── versions.env /.gitattributes: -------------------------------------------------------------------------------- 1 | vendor_jsonnet/ linguist-generated=true 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # These owners will be the default owners for everything in 2 | # the repo. Unless a later match takes precedence, 3 | # @alvneiayu @agarcia-oss @alemorcuq will be requested for 4 | # review when someone opens a pull request. 5 | * @alvneiayu @agarcia-oss 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | 15 | 16 | **Which component**: 17 | The name (and version) of the affected component (controller or kubeseal) 18 | 19 | **Describe the bug** 20 | A clear and concise description of what the bug is. 21 | 22 | **To Reproduce** 23 | Steps to reproduce the behavior: 24 | 25 | 1. Go to '...' 26 | 2. Run the command '....' 27 | 3. Wait for '....' 28 | 4. See error 29 | 30 | **Expected behavior** 31 | A clear and concise description of what you expected to happen. 32 | 33 | **Version of Kubernetes**: 34 | 35 | - Output of `kubectl version`: 36 | 37 | ``` 38 | (paste your output here) 39 | ``` 40 | 41 | **Additional context** 42 | Add any other context about the problem here. 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Which component**: 11 | The name (and version) of the affected component (controller or kubeseal) 12 | 13 | **Is your feature request related to a problem? Please describe.** 14 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 15 | 16 | **Describe the solution you'd like** 17 | A clear and concise description of what you want to happen. 18 | 19 | **Describe alternatives you've considered** 20 | A clear and concise description of any alternative solutions or features you've considered. 21 | 22 | **Additional context** 23 | Add any other context or screenshots about the feature request here. 24 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | **Description of the change** 14 | 15 | 16 | 17 | **Benefits** 18 | 19 | 20 | 21 | **Possible drawbacks** 22 | 23 | 24 | 25 | **Applicable issues** 26 | 27 | 28 | - fixes # 29 | 30 | **Additional information** 31 | 32 | 34 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "gomod" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/workflows/cosign.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEseWNtEaI73oDVgjfLzU4eQYHE11i 3 | MzRSNs1TA+cTT/Lw70ckfCC/vHnOXKACF2dnhsZsNNj647p9mAiYNVl9ug== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /.github/workflows/helm-release.yaml: -------------------------------------------------------------------------------- 1 | name: Release Helm Chart and Carvel package 2 | 3 | on: 4 | push: 5 | paths: 6 | # update this file to trigger helm chart release 7 | - 'helm/sealed-secrets/Chart.yaml' 8 | branches: 9 | - main 10 | 11 | jobs: 12 | release: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v3.1.0 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Configure Git 21 | run: | 22 | git config user.name "$GITHUB_ACTOR" 23 | git config user.email "$GITHUB_ACTOR@users.noreply.github.com" 24 | 25 | - name: Install Helm 26 | uses: azure/setup-helm@v3.4 27 | with: 28 | version: v3.4.2 29 | 30 | - name: Run chart-releaser 31 | uses: helm/chart-releaser-action@v1.4.1 32 | with: 33 | charts_dir: helm 34 | env: 35 | CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 36 | CR_RELEASE_NAME_TEMPLATE: "helm-v{{ .Version }}" 37 | 38 | - name: Install Carvel 39 | uses: carvel-dev/setup-action@v1.3.0 40 | with: 41 | only: kbld, imgpkg 42 | token: ${{ secrets.GITHUB_TOKEN }} 43 | 44 | - name: Install yq 45 | run: | 46 | mkdir -p ~/bin 47 | wget https://github.com/mikefarah/yq/releases/download/v4.30.8/yq_linux_amd64 -O ~/bin/yq 48 | chmod +x ~/bin/yq 49 | 50 | - name: Get chart version 51 | run: | 52 | export PATH=~/bin:$PATH 53 | echo "chart_version=$(yq .version < ./helm/sealed-secrets/Chart.yaml)" >> $GITHUB_ENV 54 | 55 | - name: Create imglock file 56 | working-directory: ./helm 57 | run: | 58 | mkdir -p .imgpkg 59 | kbld -f <(helm template sealed-secrets) --imgpkg-lock-output .imgpkg/images.yml 60 | 61 | - name: Push imgpkg bundle 62 | working-directory: ./helm 63 | env: 64 | IMGPKG_REGISTRY_HOSTNAME: ghcr.io 65 | IMGPKG_REGISTRY_USERNAME: ${{ github.actor }} 66 | IMGPKG_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} 67 | run: | 68 | imgpkg push -b ghcr.io/${{ github.repository_owner }}/sealed-secrets-carvel:${{ env.chart_version }} -f . --json > output 69 | echo carvel_pkg=$(cat output | grep Pushed | cut -d "'" -f2 ) >> $GITHUB_ENV 70 | 71 | - name: Update package.yaml 72 | run: | 73 | yq -i '.spec.version = "${{ env.chart_version }}"' carvel/package.yaml 74 | yq -i '.metadata.name = "sealedsecrets.bitnami.com.${{ env.chart_version }}"' carvel/package.yaml 75 | yq -i '.spec.template.spec.fetch.0.imgpkgBundle.image = "${{ env.carvel_pkg }}"' carvel/package.yaml 76 | git checkout -B 'release-carvel-${{ env.chart_version }}' 77 | git add carvel/package.yaml 78 | git commit -sm 'Release carvel package ${{ env.chart_version }}' 79 | git push origin 'release-carvel-${{ env.chart_version }}' 80 | 81 | - name: Create PR 82 | run: gh pr create --fill --base main --repo $GITHUB_REPOSITORY 83 | env: 84 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 85 | -------------------------------------------------------------------------------- /.github/workflows/helm-vib-lint.yaml: -------------------------------------------------------------------------------- 1 | name: Lint Helm Chart 2 | on: 3 | workflow_dispatch: 4 | pull_request_target: 5 | branches: 6 | - main 7 | - bitnami-labs:main 8 | paths: 9 | - 'helm/**' 10 | 11 | env: 12 | CSP_API_URL: https://console.tanzu.broadcom.com 13 | CSP_API_TOKEN: ${{ secrets.CSP_API_TOKEN }} 14 | VIB_PUBLIC_URL: https://cp.bromelia.vmware.com 15 | 16 | jobs: 17 | # make sure chart is linted/safe 18 | vib-validate: 19 | runs-on: ubuntu-latest 20 | name: Lint chart 21 | steps: 22 | - uses: actions/checkout@v3.1.0 23 | with: 24 | ref: ${{github.event.pull_request.head.ref}} 25 | repository: ${{github.event.pull_request.head.repo.full_name}} 26 | - uses: vmware-labs/vmware-image-builder-action@v0.6.0 27 | -------------------------------------------------------------------------------- /.github/workflows/helm-vib.yaml: -------------------------------------------------------------------------------- 1 | name: Verify Helm Chart 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - 'helm/**' 9 | 10 | env: 11 | CSP_API_URL: https://console.tanzu.broadcom.com 12 | CSP_API_TOKEN: ${{ secrets.CSP_API_TOKEN }} 13 | VIB_PUBLIC_URL: https://cp.bromelia.vmware.com 14 | 15 | jobs: 16 | # verify chart in multiple target platforms 17 | vib-k8s-verify: 18 | runs-on: ubuntu-latest 19 | environment: vmware-image-builder 20 | strategy: 21 | matrix: 22 | include: 23 | - name: GKE 24 | target-platform: gke 25 | target-platform-id: 91d398a2-25c4-4cda-8732-75a3cfc179a1 26 | target-pipeline: vib-platform-verify.json 27 | - name: GKE Skip Recreate 28 | target-platform: gke 29 | target-platform-id: 91d398a2-25c4-4cda-8732-75a3cfc179a1 30 | target-pipeline: vib-platform-verify-skip-recreate.json 31 | - name: Openshift 32 | target-platform: openshift 33 | target-platform-id: ebac9e0d-3931-4515-ba54-e6adada1f174 34 | target-pipeline: vib-platform-verify-openshift.json 35 | fail-fast: false 36 | name: Verify chart (${{ matrix.name }}) 37 | steps: 38 | - uses: actions/checkout@v3.1.0 39 | with: 40 | ref: ${{ github.event.pull_request.head.ref }} 41 | repository: ${{ github.event.pull_request.head.repo.full_name }} 42 | - uses: vmware-labs/vmware-image-builder-action@v0.6.0 43 | with: 44 | pipeline: ${{ matrix.target-pipeline }} 45 | max-pipeline-duration: 7200 46 | env: 47 | TARGET_PLATFORM: ${{ matrix.target-platform-id }} 48 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Prepare Release 2 | 3 | # Only release when a new GH release branch is pushed 4 | on: 5 | push: 6 | branches: 7 | - 'release/v[0-9]+.[0-9]+.[0-9]+' 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | # Checkout and set env 14 | - name: Checkout 15 | uses: actions/checkout@v3.1.0 16 | - id: load-version 17 | run: | 18 | source $GITHUB_WORKSPACE/versions.env 19 | echo "GO_VERSION=$GO_VERSION" >> $GITHUB_ENV 20 | - name: Configure Git 21 | run: | 22 | git config user.name "$GITHUB_ACTOR" 23 | git config user.email "$GITHUB_ACTOR@users.noreply.github.com" 24 | - name: Set up Go 25 | uses: actions/setup-go@v3.3.1 26 | with: 27 | go-version: ${{ env.GO_VERSION }} 28 | - name: Setup kubecfg 29 | run: | 30 | mkdir -p ~/bin 31 | curl -sLf https://github.com/kubecfg/kubecfg/releases/download/v0.26.0/kubecfg_Linux_X64 >~/bin/kubecfg 32 | chmod +x ~/bin/kubecfg 33 | 34 | - name: Install dependencies 35 | run: | 36 | go install gotest.tools/gotestsum@v1.8.1 37 | 38 | # Run tests 39 | - name: Tests 40 | run: make test 41 | 42 | # Tag for GoReleaser from release branch name 43 | - name: Tag Release 44 | run: | 45 | RELEASE_BRANCH="${{ github.ref }}" 46 | VERSION_TAG=$(echo "${RELEASE_BRANCH}" | awk -F'/' '{print $NF}') 47 | git tag -a "${VERSION_TAG}" -m "Tag autogenerated ${VERSION_TAG}" 48 | git push origin "${VERSION_TAG}" 49 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues and PRs' 2 | on: 3 | schedule: 4 | # Stalebot will be executed at 1:00 AM every day 5 | - cron: '0 1 * * *' 6 | 7 | jobs: 8 | stale: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/stale@v6.0.0 12 | with: 13 | repo-token: ${{ secrets.GITHUB_TOKEN }} 14 | stale-issue-message: 'This Issue has been automatically marked as "stale" because it has not had recent activity (for 15 days). It will be closed if no further activity occurs. Thanks for the feedback.' 15 | stale-pr-message: 'This Pull Request has been automatically marked as "stale" because it has not had recent activity (for 15 days). It will be closed if no further activity occurs. Thank you for your contribution.' 16 | close-issue-message: 'Due to the lack of activity in the last 7 days since it was marked as "stale", we proceed to close this Issue. Do not hesitate to reopen it later if necessary.' 17 | close-pr-message: 'Due to the lack of activity in the last 7 days since it was marked as "stale", we proceed to close this Pull Request. Do not hesitate to reopen it later if necessary.' 18 | days-before-stale: 15 19 | days-before-close: 7 20 | exempt-issue-labels: 'backlog,help wanted,triage' 21 | exempt-pr-labels: 'backlog,help wanted,triage' 22 | operations-per-run: 500 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | 16 | # Project-local vscode config 17 | .vscode/ 18 | 19 | /controller 20 | /kubeseal 21 | /kubeseal-arm 22 | /kubeseal-arm64 23 | 24 | /controller.image 25 | /controller.image.* 26 | /kubeseal.image 27 | /kubeseal.image.* 28 | /pushed.controller.image.* 29 | /pushed.kubeseal.image.* 30 | /controller-manifest-* 31 | /push-controller-image 32 | /*-static 33 | /*-static-* 34 | /controller.yaml 35 | /controller-norbac.yaml 36 | /controller-podmonitor.yaml 37 | /docker/controller 38 | *.iml 39 | .idea 40 | 41 | # GoReleaser output dir 42 | dist/ 43 | 44 | # Vendor folder 45 | vendor/ 46 | report.xml 47 | -------------------------------------------------------------------------------- /.vib/vib-pipeline.json: -------------------------------------------------------------------------------- 1 | { 2 | "phases": { 3 | "package": { 4 | "context": { 5 | "resources": { 6 | "url": "{SHA_ARCHIVE}", 7 | "path": "/helm/sealed-secrets" 8 | } 9 | }, 10 | "actions": [ 11 | { 12 | "action_id": "helm-package" 13 | }, 14 | { 15 | "action_id": "helm-lint" 16 | } 17 | ] 18 | }, 19 | "verify": { 20 | "context": { 21 | "runtime_parameters": "IyMgQ3JlYXRlIFNlYWxlZCBTZWNyZXRzIGNvbnRyb2xsZXIgc2hvdWxkIGJlIGNyZWF0ZWQKY3JlYXRlQ29udHJvbGxlcjogdHJ1ZQojIyBTZWNyZXQgY29udGFpbmluZyB0aGUga2V5IHVzZWQgdG8gZW5jcnlwdCBzZWNyZXRzCnNlY3JldE5hbWU6ICJzZWFsZWQtc2VjcmV0cy1rZXkiCiMjIFJlbmV3IGtleXMgZXZlcnkgd2VlawprZXlyZW5ld3BlcmlvZDogIjE2OGgiCg==" 22 | }, 23 | "actions": [ 24 | { 25 | "action_id": "trivy", 26 | "params": { 27 | "threshold": "CRITICAL", 28 | "vuln_type": ["OS"] 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.vib/vib-platform-verify-openshift.json: -------------------------------------------------------------------------------- 1 | { 2 | "phases": { 3 | "package": { 4 | "context": { 5 | "resources": { 6 | "url": "{SHA_ARCHIVE}", 7 | "path": "/helm/sealed-secrets" 8 | } 9 | }, 10 | "actions": [ 11 | { 12 | "action_id": "helm-package" 13 | } 14 | ] 15 | }, 16 | "verify": { 17 | "context": { 18 | "resources": { 19 | "url": "{SHA_ARCHIVE}", 20 | "path": "/.vib/" 21 | }, 22 | "runtime_parameters": "IyMgQ3JlYXRlIFNlYWxlZCBTZWNyZXRzIGNvbnRyb2xsZXIgc2hvdWxkIGJlIGNyZWF0ZWQKY3JlYXRlQ29udHJvbGxlcjogdHJ1ZQojIyBTZWNyZXQgY29udGFpbmluZyB0aGUga2V5IHVzZWQgdG8gZW5jcnlwdCBzZWNyZXRzCnNlY3JldE5hbWU6ICJzZWFsZWQtc2VjcmV0cy1rZXkiCiMjIFJlbmV3IGtleXMgZXZlcnkgd2VlawprZXlyZW5ld3BlcmlvZDogIjE2OGgiCmNvbnRhaW5lclNlY3VyaXR5Q29udGV4dDoKICBlbmFibGVkOiB0cnVlCiAgcmVhZE9ubHlSb290RmlsZXN5c3RlbTogdHJ1ZQogIHJ1bkFzTm9uUm9vdDogdHJ1ZQogIHJ1bkFzVXNlcjogbnVsbApwb2RTZWN1cml0eUNvbnRleHQ6CiAgZW5hYmxlZDogZmFsc2UKc2VydmljZToKICB0eXBlOiBMb2FkQmFsYW5jZXIKICBwb3J0OiA4MAo=", 23 | "target_platform": { 24 | "target_platform_id": "{TARGET_PLATFORM}" 25 | } 26 | }, 27 | "actions": [ 28 | { 29 | "action_id": "health-check", 30 | "params": { 31 | "endpoint": "lb-sealed-secrets-http" 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.vib/vib-platform-verify-skip-recreate.json: -------------------------------------------------------------------------------- 1 | { 2 | "phases": { 3 | "package": { 4 | "context": { 5 | "resources": { 6 | "url": "{SHA_ARCHIVE}", 7 | "path": "/helm/sealed-secrets" 8 | } 9 | }, 10 | "actions": [ 11 | { 12 | "action_id": "helm-package" 13 | } 14 | ] 15 | }, 16 | "verify": { 17 | "context": { 18 | "resources": { 19 | "url": "{SHA_ARCHIVE}", 20 | "path": "/.vib/" 21 | }, 22 | "runtime_parameters": "IyMgQ3JlYXRlIFNlYWxlZCBTZWNyZXRzIGNvbnRyb2xsZXIgc2hvdWxkIGJlIGNyZWF0ZWQKY3JlYXRlQ29udHJvbGxlcjogdHJ1ZQojIyBTZWNyZXQgY29udGFpbmluZyB0aGUga2V5IHVzZWQgdG8gZW5jcnlwdCBzZWNyZXRzCnNlY3JldE5hbWU6ICJzZWFsZWQtc2VjcmV0cy1rZXkiCiMjIFJlbmV3IGtleXMgZXZlcnkgd2VlawprZXlyZW5ld3BlcmlvZDogIjE2OGgiCiMgU2tpcCBzZWNyZXQgcmVjcmVhdGlvbgpza2lwUmVjcmVhdGU6IHRydWUKc2VydmljZToKICB0eXBlOiBMb2FkQmFsYW5jZXIKICBwb3J0OiA4MAo=", 23 | "target_platform": { 24 | "target_platform_id": "{TARGET_PLATFORM}" 25 | } 26 | }, 27 | "actions": [ 28 | { 29 | "action_id": "health-check", 30 | "params": { 31 | "endpoint": "lb-sealed-secrets-http" 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.vib/vib-platform-verify.json: -------------------------------------------------------------------------------- 1 | { 2 | "phases": { 3 | "package": { 4 | "context": { 5 | "resources": { 6 | "url": "{SHA_ARCHIVE}", 7 | "path": "/helm/sealed-secrets" 8 | } 9 | }, 10 | "actions": [ 11 | { 12 | "action_id": "helm-package" 13 | } 14 | ] 15 | }, 16 | "verify": { 17 | "context": { 18 | "resources": { 19 | "url": "{SHA_ARCHIVE}", 20 | "path": "/.vib/" 21 | }, 22 | "runtime_parameters": "IyMgQ3JlYXRlIFNlYWxlZCBTZWNyZXRzIGNvbnRyb2xsZXIgc2hvdWxkIGJlIGNyZWF0ZWQKY3JlYXRlQ29udHJvbGxlcjogdHJ1ZQojIyBTZWNyZXQgY29udGFpbmluZyB0aGUga2V5IHVzZWQgdG8gZW5jcnlwdCBzZWNyZXRzCnNlY3JldE5hbWU6ICJzZWFsZWQtc2VjcmV0cy1rZXkiCiMjIFJlbmV3IGtleXMgZXZlcnkgd2VlawprZXlyZW5ld3BlcmlvZDogIjE2OGgiCnNlcnZpY2U6CiAgdHlwZTogTG9hZEJhbGFuY2VyCiAgcG9ydDogODAK", 23 | "target_platform": { 24 | "target_platform_id": "{TARGET_PLATFORM}" 25 | } 26 | }, 27 | "actions": [ 28 | { 29 | "action_id": "health-check", 30 | "params": { 31 | "endpoint": "lb-sealed-secrets-http" 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | # Sealed Secrets Maintainers 2 | 3 | ## Maintainers 4 | 5 | | Maintainer | GitHub ID | Affiliation | 6 | | ------------------ | --------------------------------------------------- | ---------------------------------------: | 7 | | Alvaro Neira Ayuso | [alvneiayu](https://github.com/alvneiayu) | [VMware](https://www.github.com/vmware/) | 8 | | Alejandro Moreno | [alemorcuq](https://github.com/alemorcuq) | [VMware](https://www.github.com/vmware/) | 9 | | Alfredo Garcia | [agarcia-oss](https://github.com/agarcia-oss) | [VMware](https://www.github.com/vmware/) | 10 | 11 | ## Emeritus Maintainers 12 | 13 | - Angus Lees ([anguslees](https://github.com/anguslees)) 14 | - Marko Mikulicic ([mkmik](https://github.com/mkmik)) 15 | - Juan Ariza ([juan131](https://github.com/juan131)) 16 | - Jose Vazquez ([josvazg](https://github.com/josvazg)) 17 | 18 | --- 19 | 20 | Full list of [Sealed Secrets contributors](https://github.com/bitnami-labs/sealed-secrets/graphs/contributors). 21 | -------------------------------------------------------------------------------- /cmd/controller/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | goflag "flag" 6 | "testing" 7 | 8 | flag "github.com/spf13/pflag" 9 | ) 10 | 11 | func TestVersion(t *testing.T) { 12 | buf := bytes.NewBufferString("") 13 | testVersionFlags := flag.NewFlagSet("testVersionFlags", flag.ExitOnError) 14 | testNopFlags := goflag.NewFlagSet("nop", goflag.ExitOnError) 15 | err := mainE(buf, testVersionFlags, testNopFlags, []string{"--version"}) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | if got, want := buf.String(), "controller version: UNKNOWN\n"; got != want { 21 | t.Errorf("got: %q, want: %q", got, want) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/.gitignore: -------------------------------------------------------------------------------- 1 | manifests/ 2 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/Makefile: -------------------------------------------------------------------------------- 1 | # Prometheus Mixin Makefile 2 | # Heavily copied from upstream project kubenetes-mixin 3 | 4 | PROMETHEUS_IMAGE := prom/prometheus:v2.21.0 5 | 6 | JSONNET_FMT := jsonnetfmt 7 | 8 | all: fmt prometheus_alerts.yaml prometheus_rules.yaml dashboards_out lint test ## Generate files, lint and test 9 | 10 | fmt: ## Format Jsonnet 11 | find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ 12 | xargs -n 1 -- $(JSONNET_FMT) -i 13 | 14 | prometheus_alerts.yaml: mixin.libsonnet lib/alerts.jsonnet alerts/*.libsonnet ## Generate Alerts YAML 15 | @mkdir -p manifests 16 | jsonnet -S lib/alerts.jsonnet > manifests/$@ 17 | 18 | prometheus_rules.yaml: mixin.libsonnet lib/rules.jsonnet rules/*.libsonnet ## Generate Rules YAML 19 | @mkdir -p manifests 20 | jsonnet -S lib/rules.jsonnet > manifests/$@ 21 | 22 | dashboards_out: mixin.libsonnet lib/dashboards.jsonnet dashboards/*.libsonnet ## Generate Dashboards JSON 23 | jsonnet -J vendor -m manifests lib/dashboards.jsonnet 24 | 25 | lint: prometheus_alerts.yaml prometheus_rules.yaml ## Lint and check YAML 26 | find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ 27 | while read f; do \ 28 | $(JSONNET_FMT) "$$f" | diff -u "$$f" -; \ 29 | done 30 | docker run \ 31 | -v $(PWD)/manifests:/tmp \ 32 | --entrypoint '/bin/promtool' \ 33 | $(PROMETHEUS_IMAGE) \ 34 | check rules /tmp/prometheus_rules.yaml; \ 35 | docker run \ 36 | -v $(PWD)/manifests:/tmp \ 37 | --entrypoint '/bin/promtool' \ 38 | $(PROMETHEUS_IMAGE) \ 39 | check rules /tmp/prometheus_alerts.yaml 40 | 41 | clean: ## Clean up generated files 42 | rm -rf manifests/ 43 | 44 | # TODO: Find out why official prom images segfaults during `test rules` if not root 45 | test: prometheus_alerts.yaml prometheus_rules.yaml ## Test generated files 46 | docker run \ 47 | -v $(PWD):/tmp \ 48 | --user root \ 49 | --entrypoint '/bin/promtool' \ 50 | $(PROMETHEUS_IMAGE) \ 51 | test rules /tmp/tests.yaml 52 | 53 | .PHONY: help 54 | help: 55 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 56 | 57 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/alerts/alerts.libsonnet: -------------------------------------------------------------------------------- 1 | // Sealed Secrets Alertmanager Alerts 2 | 3 | (import 'sealed-secrets-alerts.libsonnet') 4 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/alerts/sealed-secrets-alerts.libsonnet: -------------------------------------------------------------------------------- 1 | { 2 | prometheusAlerts+:: { 3 | groups+: [{ 4 | name: 'sealed-secrets', 5 | rules: [ 6 | // SealedSecretsErrorRateHigh: 7 | // Method: Alert on occurence of errors by looking for a non-zero rate of errors over past 5 minutes 8 | // Pros: 9 | // - An app deploy is likely broken if a secret can't be updated by Controller. 10 | // Caveats: 11 | // - Probably better to leave app deploy breakages to the app or CD systems monitoring. 12 | // - Potentially noisy. Controller attempts to unseal 5 times, so if it exceeds on the 4th attempt then all is fine but this alert will trigger. 13 | // - Usage of an invalid cert.pem with kubeseal will trigger this alert, it would be better to distinguish alerts due to controller or user 14 | // - 'for' clause not used because we are unlikely to have a sustained rate of errors unless there is a LOT of secret churn in cluster. 15 | // Rob Ewaschuk - My Philosophy on Alerting: https://docs.google.com/document/d/199PqyG3UsyXlwieHaqbGiWVa8eMWi8zzAn0YfcApr8Q/edit 16 | { 17 | alert: 'SealedSecretsUnsealErrorHigh', 18 | expr: ||| 19 | sum by (reason, namespace) (rate(sealed_secrets_controller_unseal_errors_total{}[5m])) > 0 20 | ||| % $._config, 21 | // 'for': '5m', // Not used, see caveats above. 22 | labels: { 23 | severity: 'warning', 24 | }, 25 | annotations: { 26 | summary: 'Sealed Secrets Unseal Error High', 27 | description: 'High number of errors during unsealing Sealed Secrets in {{ $labels.namespace }} namespace.', 28 | runbook_url: 'https://github.com/bitnami-labs/sealed-secrets', 29 | }, 30 | }, 31 | ], 32 | }], 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/config.libsonnet: -------------------------------------------------------------------------------- 1 | // Sealed Secrets Prometheus Mixin Config 2 | { 3 | _config+:: {}, 4 | } 5 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/dashboards/dashboards.libsonnet: -------------------------------------------------------------------------------- 1 | // Sealed Secrets Grafana Dashboards 2 | 3 | { 4 | grafanaDashboards+:: { 5 | 'sealed-secrets-controller.json': (import 'sealed-secrets-controller.json'), 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/lib/alerts.jsonnet: -------------------------------------------------------------------------------- 1 | std.manifestYamlDoc((import '../mixin.libsonnet').prometheusAlerts) 2 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/lib/dashboards.jsonnet: -------------------------------------------------------------------------------- 1 | local dashboards = (import '../mixin.libsonnet').grafanaDashboards; 2 | 3 | { 4 | [name]: dashboards[name] 5 | for name in std.objectFields(dashboards) 6 | } 7 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/lib/rules.jsonnet: -------------------------------------------------------------------------------- 1 | std.manifestYamlDoc((import '../mixin.libsonnet').prometheusRules) 2 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/mixin.libsonnet: -------------------------------------------------------------------------------- 1 | // Prometheus Mixin 2 | // Follows the kubernetes-mixin project pattern here: https://github.com/kubernetes-monitoring/kubernetes-mixin 3 | // Mixin design doc: https://docs.google.com/document/d/1A9xvzwqnFVSOZ5fD3blKODXfsat5fg6ZhnKu9LK3lB4/edit 4 | 5 | // This file will be imported during build for all Promethei 6 | 7 | (import 'config.libsonnet') + 8 | (import 'alerts/alerts.libsonnet') + 9 | (import 'dashboards/dashboards.libsonnet') + 10 | (import 'rules/rules.libsonnet') 11 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/rules/rules.libsonnet: -------------------------------------------------------------------------------- 1 | // Sealed Secrets Prometheus Recording Rules 2 | { 3 | prometheusRules+:: { 4 | groups+: [ 5 | // import ('sealed-secrets-rules.libsonnet') 6 | ], 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /contrib/prometheus-mixin/tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | rule_files: 3 | - /tmp/manifests/prometheus_alerts.yaml 4 | - /tmp/manifests/prometheus_rules.yaml 5 | 6 | evaluation_interval: 1m 7 | 8 | tests: 9 | - interval: 1m 10 | input_series: 11 | - series: 'sealed_secrets_controller_unseal_errors_total{reason="update",namespace="test"}' 12 | values: '0+0x5 1+1x5' 13 | - series: 'sealed_secrets_controller_unseal_errors_total{reason="unseal",namespace="test"}' 14 | values: '0+0x10' 15 | alert_rule_test: 16 | - eval_time: 5m 17 | alertname: SealedSecretsUnsealErrorHigh 18 | - eval_time: 10m 19 | alertname: SealedSecretsUnsealErrorHigh 20 | exp_alerts: 21 | - exp_labels: 22 | severity: warning 23 | namespace: test 24 | reason: update 25 | exp_annotations: 26 | summary: 'Sealed Secrets Unseal Error High' 27 | description: 'High number of errors during unsealing Sealed Secrets in test namespace.' 28 | runbook_url: 'https://github.com/bitnami-labs/sealed-secrets' 29 | -------------------------------------------------------------------------------- /controller-podmonitor.jsonnet: -------------------------------------------------------------------------------- 1 | // Prometheus Pod Monitor manifest 2 | // ref: https://github.com/prometheus-operator/prometheus-operator#customresourcedefinitions 3 | 4 | local controller = import 'controller.jsonnet'; 5 | 6 | controller { 7 | podMonitor: { 8 | apiVersion: 'monitoring.coreos.com/v1', 9 | kind: 'PodMonitor', 10 | metadata: { 11 | name: 'sealed-secrets-controller', 12 | namespace: $.namespace.metadata.namespace, 13 | labels: { 14 | name: 'sealed-secrets-controller', 15 | }, 16 | }, 17 | spec: { 18 | jobLabel: 'name', 19 | selector: { 20 | matchLabels: { 21 | name: 'sealed-secrets-controller', 22 | }, 23 | }, 24 | namespaceSelector: { 25 | matchNames: [ 26 | $.namespace.metadata.namespace, 27 | ], 28 | }, 29 | podMetricsEndpoints: [ 30 | { 31 | honorLabels: true, // prefer controller metric namespace 32 | port: 'http', 33 | interval: '30s', 34 | }, 35 | ], 36 | sampleLimit: 1000, 37 | }, 38 | }, 39 | } 40 | -------------------------------------------------------------------------------- /docker/controller.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gcr.io/distroless/static@sha256:d6fa9db9548b5772860fecddb11d84f9ebd7e0321c0cb3c02870402680cc315f 2 | LABEL maintainer "Sealed Secrets " 3 | 4 | USER 1001 5 | 6 | ARG TARGETARCH 7 | COPY dist/controller_linux_${TARGETARCH}*/controller /usr/local/bin/ 8 | 9 | EXPOSE 8080 8081 10 | 11 | ENTRYPOINT ["controller"] 12 | -------------------------------------------------------------------------------- /docker/kubeseal.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gcr.io/distroless/static@sha256:d6fa9db9548b5772860fecddb11d84f9ebd7e0321c0cb3c02870402680cc315f 2 | LABEL maintainer "Sealed Secrets " 3 | 4 | USER 1001 5 | 6 | ARG TARGETARCH 7 | COPY dist/kubeseal_linux_${TARGETARCH}*/kubeseal /usr/local/bin/ 8 | 9 | ENTRYPOINT ["kubeseal"] 10 | -------------------------------------------------------------------------------- /docs/GKE.md: -------------------------------------------------------------------------------- 1 | # GKE 2 | 3 | ## Install 4 | 5 | If installing on a GKE cluster you don't have admin rights for, a ClusterRoleBinding may be needed to successfully deploy the controller in the final command. Replace with a valid email, and then deploy the cluster role binding: 6 | 7 | ```bash 8 | USER_EMAIL= 9 | kubectl create clusterrolebinding $USER-cluster-admin-binding --clusterrole=cluster-admin --user=$USER_EMAIL 10 | ``` 11 | 12 | ## Private GKE clusters 13 | 14 | If you are using a **private GKE cluster**, `kubeseal` won't be able to fetch the public key from the controller 15 | because there is firewall that prevents the control plane to talk directly to the nodes. 16 | 17 | There are currently two workarounds: 18 | 19 | ### Offline sealing 20 | 21 | If you have the public key for your controller, you can seal secrets without talking to the controller. 22 | Normally `kubeseal --fetch-cert` can be used to obtain the certificate for later use, but in this case the firewall prevents us from doing it. 23 | 24 | The controller outputs the certificate to the logs so you can copy paste it from there. 25 | 26 | Once you have the cert this is how you seal secrets: 27 | 28 | ```bash 29 | kubeseal --cert=cert.pem 6 | 7 | 8 | - [Prerequisites](#prerequisites) 9 | - [The Sealed Secrets Components](#the-sealed-secrets-components) 10 | - [Controller](#controller) 11 | - [Kubeseal](#kubeseal) 12 | - [git-hooks](#git-hooks) 13 | 14 | 15 | 16 | ## Prerequisites 17 | 18 | To be able to develop on this project, you need to have the following tools installed: 19 | 20 | - [Git](https://git-scm.com/) 21 | - [Make](https://www.gnu.org/software/make/) 22 | - [Go programming language](https://golang.org/dl/) 23 | - [Docker CE](https://www.docker.com/community-edition) 24 | - [Kubernetes cluster (v1.16+)](https://kubernetes.io/docs/setup/). [Minikube](https://github.com/kubernetes/minikube) is recommended. 25 | - [Kubecfg](https://github.com/bitnami/kubecfg) 26 | - [Ginkgo](https://onsi.github.io/ginkgo/) 27 | - [git-hooks](https://github.com/git-hooks/git-hooks) 28 | - [doctoc](https://github.com/thlorenz/doctoc) 29 | 30 | ## The Sealed Secrets Components 31 | 32 | Sealed Secrets is composed of three parts: 33 | 34 | - A [custom resource](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources) named `SealedSecret` 35 | - A cluster-side controller / operator that manages the `SealedSecret` objects 36 | - A client-side utility: kubeseal 37 | 38 | ### Controller 39 | 40 | The controller is in charge of keeping the current state of `SealedSecret` objects in sync with the declared desired state. 41 | 42 | Please refer to the [Sealed Secrets Controller](controller.md) for the developer setup. 43 | 44 | ### Kubeseal 45 | 46 | The `kubeseal` utility uses asymmetric crypto to encrypt secrets that only the controller can decrypt. 47 | 48 | Please refer to the [Kubeseal Developer Guide](kubeseal.md) for the developer setup. 49 | 50 | ## git-hooks 51 | 52 | To avoid easily detectable issues and prevent them from reaching main, some validations have been implemented via [git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks). To have those hooks committed in the repository you need to install a third party tool `git-hooks` (check [prerequisites](#prerequisites)), because the hooks provided by Git are stored in the `.git` directory that is not included as part of the repositories. 53 | 54 | Currently, there's a single hook at pre-commit level. This hook ensures the Table of Contents (TOC) is updated using `doctoc` (check [prerequisites](#prerequisites)) in every `.md` and `.txt` file that uses this tool. 55 | 56 | Configure git-hooks for this specific repository by running `git hooks install`. You can check with the following command if everything was configured properly: 57 | 58 | ```console 59 | $ git hooks list 60 | Git hooks ARE installed in this repository. 61 | project hooks 62 | pre-commit 63 | - doc-toc 64 | 65 | Contrib hooks 66 | ``` 67 | -------------------------------------------------------------------------------- /docs/developer/kubeseal.md: -------------------------------------------------------------------------------- 1 | # Kubeseal Developer Guide 2 | 3 | Kubeseal component is a CLI tool that uses asymmetric crypto to encrypt secrets that only the controller can decrypt. 4 | 5 | ## Download the Kubeseal source code 6 | 7 | ```bash 8 | git clone https://github.com/bitnami-labs/sealed-secrets.git $SEALED_SECRETS_DIR 9 | ``` 10 | 11 | The kubeseal sources are located under `cmd/kubeseal/` and use packages from the `pkg` directory. 12 | 13 | ### Building the `kubeseal` binary 14 | 15 | ```bash 16 | make kubeseal 17 | ``` 18 | 19 | This builds the `kubeseal` binary in the working directory. 20 | 21 | ### Running tests 22 | 23 | To run the unit tests for `kubeseal` binary: 24 | 25 | ```bash 26 | make test 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/examples/config-template/README.md: -------------------------------------------------------------------------------- 1 | # Injecting secrets into config file templates 2 | 3 | Kubernetes Secrets are very flexible and can be consumed in many ways. 4 | Secret values can be passed to containers as environment variables or appear as regular files when mounting secret volumes. 5 | 6 | Often users end up using the latter method just to wrap full configuration files into k8s secrets, just 7 | because one or more fields in the config file happen to be secrets (e.g. a database password, or a session cookie encryption key). 8 | 9 | Ideally you should avoid configuring your software that way, instead split your configuration from your secrets somehow. Also make sure you know about [12 Factor](https://www.12factor.net/). 10 | 11 | That said, there are circumstances where you just have to provide such a file to your application (perhaps because it's a legacy app) and encrypting the whole configuration file in a single SealedSecrets item is problematic: 12 | 13 | - You cannot easily update individual secret values (e.g. rotate your DB password), without first decrypting the whole configuration file. 14 | - Since the whole configuration file is encrypted, it's hard to view, change (and review) non-secret parts of the config. 15 | 16 | This example shows how to use built in support for templating encrypted secret values into a plaintext key template. 17 | 18 | To update the encrypted data in the included SealedSecret with your own value for `server1` you can run: 19 | 20 | ```bash 21 | echo -n baz | kubectl create secret generic example --dry-run=client --from-file=server1=/dev/stdin -o json \ 22 | | kubeseal -o yaml --merge-into sealedsecret.yaml 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/examples/config-template/deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: example 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: example 10 | template: 11 | metadata: 12 | labels: 13 | app: example 14 | spec: 15 | containers: 16 | # This is an example application that assumes a complex configuration file in /config/myconfig.json. 17 | # The JSON format here is just an example; any textual file format would work. 18 | - name: app 19 | image: bitnami/minideb:buster 20 | volumeMounts: 21 | - name: config-volume 22 | mountPath: /config 23 | command: ["sh", "-c"] 24 | args: 25 | - | 26 | echo Your app will get this config file: 27 | cat /config/myconfig.json 28 | # dummy application 29 | sleep 100000h 30 | volumes: 31 | - name: config-volume 32 | secret: 33 | secretName: example 34 | -------------------------------------------------------------------------------- /docs/examples/config-template/sealedsecret.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | name: example 6 | spec: 7 | encryptedData: 8 | server1: "AgA+dujiBo..." 9 | server2: "AgCC4/FvhZ..." 10 | database1: "AgBtYQzl3T..." 11 | template: 12 | metadata: 13 | creationTimestamp: null 14 | name: example 15 | namespace: default 16 | data: 17 | myconfig.json: | 18 | { 19 | "Server": [{ 20 | "host": "foobar", 21 | "ip": "10.10.10.12", 22 | "port": "22", 23 | "env": "SOME_ENV", 24 | "user": "myuser", 25 | "password": {{ toJson .server1 }}, 26 | "role": "foo" 27 | },{ 28 | "host": "barfoo", 29 | "ip": "10.10.10.11", 30 | "port": "22", 31 | "env": "SOME_OTHER_STUFF", 32 | "user": "otheruser", 33 | "password": {{ toJson .server2 }}, 34 | "role": "foo" 35 | } 36 | ], 37 | "Database": [{ 38 | "host": "somedb", 39 | "ip": "10.10.10.10", 40 | "port": "1521", 41 | "sid": "FOO", 42 | "env": "BAZ", 43 | "user": "abcdefg123", 44 | "password": {{ toJson .database1 }}, 45 | "role": "foo" 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /githooks/pre-commit/doc-toc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | current_branch="$(git rev-parse --abbrev-ref HEAD)" 4 | origin_commit="$(git rev-parse --short "$(git merge-base main "$current_branch")")" 5 | files_to_commit="$(git diff --name-only "$origin_commit")" 6 | 7 | for f in $(uniq <<< "$files_to_commit"); do 8 | if [[ "$(basename $f)" =~ .*\.(md|txt) ]]; then 9 | doctoc "$f" 10 | fi 11 | done 12 | if [[ $(git status --porcelain --untracked-files=no | wc -l) -gt 0 ]]; then 13 | git add --all 14 | git status --short -uno 15 | fi 16 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/hack/boilerplate.go.txt -------------------------------------------------------------------------------- /hack/tools.go: -------------------------------------------------------------------------------- 1 | // This file forces go mod to include dependencies used during build, such as 2 | // code generation tools. 3 | // The build tag below ensures this dep is not pulled during normal builds. 4 | 5 | //go:build tools 6 | // +build tools 7 | 8 | package tools 9 | 10 | import ( 11 | _ "k8s.io/code-generator" 12 | ) 13 | -------------------------------------------------------------------------------- /hack/update-codegen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | set -o pipefail 6 | 7 | SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. 8 | CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)} 9 | 10 | source "${CODEGEN_PKG}/kube_codegen.sh" 11 | 12 | THIS_PKG="github.com/bitnami-labs/sealed-secrets" 13 | 14 | kube::codegen::gen_helpers \ 15 | --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \ 16 | "${SCRIPT_ROOT}/pkg/apis" 17 | 18 | kube::codegen::gen_client \ 19 | --with-watch \ 20 | --output-dir "${SCRIPT_ROOT}/pkg/client" \ 21 | --output-pkg "${THIS_PKG}/pkg/client" \ 22 | --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \ 23 | "${SCRIPT_ROOT}/pkg/apis" 24 | -------------------------------------------------------------------------------- /helm/sealed-secrets/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /helm/sealed-secrets/Chart.yaml: -------------------------------------------------------------------------------- 1 | annotations: 2 | category: DeveloperTools 3 | apiVersion: v2 4 | appVersion: 0.29.0 5 | description: Helm chart for the sealed-secrets controller. 6 | home: https://github.com/bitnami-labs/sealed-secrets 7 | icon: https://bitnami.com/assets/stacks/sealed-secrets/img/sealed-secrets-stack-220x234.png 8 | keywords: 9 | - secrets 10 | - sealed-secrets 11 | kubeVersion: ">=1.16.0-0" 12 | maintainers: 13 | - name: Bitnami 14 | url: https://github.com/bitnami-labs/sealed-secrets 15 | name: sealed-secrets 16 | type: application 17 | version: 2.17.2 18 | sources: 19 | - https://github.com/bitnami-labs/sealed-secrets 20 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | {{ if .Values.createController -}} 2 | 3 | ** Please be patient while the chart is being deployed ** 4 | 5 | You should now be able to create sealed secrets. 6 | 7 | 1. Install the client-side tool (kubeseal) as explained in the docs below: 8 | 9 | https://github.com/bitnami-labs/sealed-secrets#installation-from-source 10 | 11 | 2. Create a sealed secret file running the command below: 12 | 13 | kubectl create secret generic secret-name --dry-run=client --from-literal=foo=bar -o [json|yaml] | \ 14 | kubeseal \ 15 | --controller-name={{ include "sealed-secrets.fullname" . }} \ 16 | --controller-namespace={{ include "sealed-secrets.namespace" . }} \ 17 | --format yaml > mysealedsecret.[json|yaml] 18 | 19 | The file mysealedsecret.[json|yaml] is a commitable file. 20 | 21 | If you would rather not need access to the cluster to generate the sealed secret you can run: 22 | 23 | kubeseal \ 24 | --controller-name={{ include "sealed-secrets.fullname" . }} \ 25 | --controller-namespace={{ include "sealed-secrets.namespace" . }} \ 26 | --fetch-cert > mycert.pem 27 | 28 | to retrieve the public cert used for encryption and store it locally. You can then run 'kubeseal --cert mycert.pem' instead to use the local cert e.g. 29 | 30 | kubectl create secret generic secret-name --dry-run=client --from-literal=foo=bar -o [json|yaml] | \ 31 | kubeseal \ 32 | --controller-name={{ include "sealed-secrets.fullname" . }} \ 33 | --controller-namespace={{ include "sealed-secrets.namespace" . }} \ 34 | --format [json|yaml] --cert mycert.pem > mysealedsecret.[json|yaml] 35 | 36 | 3. Apply the sealed secret 37 | 38 | kubectl create -f mysealedsecret.[json|yaml] 39 | 40 | Running 'kubectl get secret secret-name -o [json|yaml]' will show the decrypted secret that was generated from the sealed secret. 41 | 42 | Both the SealedSecret and generated Secret must have the same name and namespace. 43 | {{- else }} 44 | Sealed Secrets controller not installed, You need to install controller before 45 | sealed secrets can be created. 46 | {{- end }} 47 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/cluster-role-binding.yaml: -------------------------------------------------------------------------------- 1 | {{ if and .Values.rbac.create (not .Values.rbac.namespacedRoles)}} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | name: {{ include "sealed-secrets.fullname" . }} 6 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 7 | {{- if .Values.rbac.labels }} 8 | {{- include "sealed-secrets.render" ( dict "value" .Values.rbac.labels "context" $) | nindent 4 }} 9 | {{- end }} 10 | {{- if .Values.commonLabels }} 11 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 12 | {{- end }} 13 | annotations: 14 | {{- if .Values.commonAnnotations }} 15 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 16 | {{- end }} 17 | roleRef: 18 | apiGroup: rbac.authorization.k8s.io 19 | kind: ClusterRole 20 | name: {{ .Values.rbac.clusterRoleName }} 21 | subjects: 22 | - apiGroup: "" 23 | kind: ServiceAccount 24 | name: {{ include "sealed-secrets.serviceAccountName" . }} 25 | namespace: {{ include "sealed-secrets.namespace" . }} 26 | {{ end }} 27 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/cluster-role.yaml: -------------------------------------------------------------------------------- 1 | {{ if and (and .Values.rbac.create .Values.rbac.clusterRole) (not .Values.rbac.namespacedRoles) }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: {{ .Values.rbac.clusterRoleName }} 6 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 7 | {{- if .Values.rbac.labels }} 8 | {{- include "sealed-secrets.render" ( dict "value" .Values.rbac.labels "context" $) | nindent 4 }} 9 | {{- end }} 10 | {{- if .Values.commonLabels }} 11 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 12 | {{- end }} 13 | annotations: 14 | {{- if .Values.commonAnnotations }} 15 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 16 | {{- end }} 17 | rules: 18 | - apiGroups: 19 | - bitnami.com 20 | resources: 21 | - sealedsecrets 22 | verbs: 23 | - get 24 | - list 25 | - watch 26 | - apiGroups: 27 | - bitnami.com 28 | resources: 29 | - sealedsecrets/status 30 | verbs: 31 | - update 32 | - apiGroups: 33 | - "" 34 | resources: 35 | - secrets 36 | verbs: 37 | - get 38 | - list 39 | - create 40 | - update 41 | - delete 42 | - watch 43 | - apiGroups: 44 | - "" 45 | resources: 46 | - events 47 | verbs: 48 | - create 49 | - patch 50 | {{- if .Values.additionalNamespaces }} 51 | - apiGroups: 52 | - "" 53 | resources: 54 | - namespaces 55 | resourceNames: 56 | {{- include "sealed-secrets.render" (dict "value" .Values.additionalNamespaces "context" $) | nindent 6 }} 57 | verbs: 58 | - get 59 | {{- end }} 60 | {{ end }} 61 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/configmap-dashboards.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.metrics.dashboards.create }} 2 | {{- $namespace := .Values.metrics.dashboards.namespace | default $.Release.Namespace }} 3 | {{- range $path, $_ := .Files.Glob "dashboards/*.json" }} 4 | {{- $filename := trimSuffix (ext $path) (base $path) }} 5 | apiVersion: v1 6 | kind: ConfigMap 7 | metadata: 8 | name: {{ printf "%s-%s" (include "sealed-secrets.fullname" $) $filename }} 9 | namespace: {{ $namespace }} 10 | labels: {{- include "sealed-secrets.labels" $ | nindent 4 }} 11 | {{- if $.Values.metrics.dashboards.labels }} 12 | {{- include "sealed-secrets.render" ( dict "value" $.Values.metrics.dashboards.labels "context" $) | nindent 4 }} 13 | {{- end }} 14 | {{- if $.Values.commonLabels }} 15 | {{- include "sealed-secrets.render" (dict "value" $.Values.commonLabels "context" $) | nindent 4 }} 16 | {{- end }} 17 | annotations: 18 | {{- if $.Values.metrics.dashboards.annotations }} 19 | {{- include "sealed-secrets.render" ( dict "value" $.Values.metrics.dashboards.annotations "context" $) | nindent 4 }} 20 | {{- end }} 21 | {{- if $.Values.commonAnnotations }} 22 | {{- include "sealed-secrets.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }} 23 | {{- end }} 24 | data: 25 | {{ base $path }}: |- 26 | {{ $.Files.Get $path | indent 4 }} 27 | --- 28 | {{- end }} 29 | {{- end }} 30 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/extra-list.yaml: -------------------------------------------------------------------------------- 1 | {{- range .Values.extraDeploy }} 2 | --- 3 | {{ include "sealed-secrets.render" (dict "value" . "context" $) }} 4 | {{- end }} 5 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.createController .Values.ingress.enabled }} 2 | apiVersion: {{ include "sealed-secrets.ingress.apiVersion" . }} 3 | kind: Ingress 4 | metadata: 5 | name: {{ include "sealed-secrets.fullname" . }} 6 | namespace: {{ include "sealed-secrets.namespace" . }} 7 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 8 | {{- if .Values.commonLabels }} 9 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 10 | {{- end }} 11 | annotations: 12 | {{- if .Values.ingress.annotations }} 13 | {{- include "sealed-secrets.render" ( dict "value" .Values.ingress.annotations "context" $) | nindent 4 }} 14 | {{- end }} 15 | {{- if .Values.commonAnnotations }} 16 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 17 | {{- end }} 18 | spec: 19 | {{- if and .Values.ingress.ingressClassName (eq "true" (include "sealed-secrets.supportsIngressClassname" .)) }} 20 | ingressClassName: {{ .Values.ingress.ingressClassName | quote }} 21 | {{- end }} 22 | rules: 23 | {{- if .Values.ingress.hostname }} 24 | - host: {{ .Values.ingress.hostname }} 25 | http: 26 | paths: 27 | {{- if .Values.ingress.extraPaths }} 28 | {{- toYaml .Values.ingress.extraPaths | nindent 10 }} 29 | {{- end }} 30 | - path: {{ .Values.ingress.path }} 31 | {{- if eq "true" (include "sealed-secrets.supportsPathType" .) }} 32 | pathType: {{ .Values.ingress.pathType }} 33 | {{- end }} 34 | backend: {{- include "sealed-secrets.backend" (dict "serviceName" (include "sealed-secrets.fullname" .) "servicePort" "http" "context" $) | nindent 14 }} 35 | {{- end }} 36 | {{- range .Values.ingress.extraHosts }} 37 | - host: {{ .name | quote }} 38 | http: 39 | paths: 40 | - path: {{ default "/" .path }} 41 | {{- if eq "true" (include "sealed-secrets.supportsPathType" $) }} 42 | pathType: {{ default "ImplementationSpecific" .pathType }} 43 | {{- end }} 44 | backend: {{- include "sealed-secrets.backend" (dict "serviceName" (include "sealed-secrets.fullname" $) "servicePort" "http" "context" $) | nindent 14 }} 45 | {{- end }} 46 | {{- if or (and .Values.ingress.tls (or (include "sealed-secrets.ingress.certManagerRequest" .Values.ingress.annotations) .Values.ingress.selfSigned)) .Values.ingress.extraTls }} 47 | tls: 48 | {{- if and .Values.ingress.tls (or (include "sealed-secrets.ingress.certManagerRequest" .Values.ingress.annotations) .Values.ingress.selfSigned) }} 49 | - hosts: 50 | - {{ .Values.ingress.hostname | quote }} 51 | secretName: {{ printf "%s-tls" .Values.ingress.hostname }} 52 | {{- end }} 53 | {{- if .Values.ingress.extraTls }} 54 | {{- include "sealed-secrets.render" (dict "value" .Values.ingress.extraTls "context" $) | nindent 4 }} 55 | {{- end }} 56 | {{- end }} 57 | {{- end }} 58 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/networkpolicy.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.networkPolicy.enabled }} 2 | apiVersion: {{ include "sealed-secrets.networkPolicy.apiVersion" . }} 3 | kind: NetworkPolicy 4 | metadata: 5 | name: {{ include "sealed-secrets.fullname" . }} 6 | namespace: {{ include "sealed-secrets.namespace" . }} 7 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 8 | {{- if .Values.commonLabels }} 9 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 10 | {{- end }} 11 | annotations: 12 | {{- if .Values.commonAnnotations }} 13 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 14 | {{- end }} 15 | spec: 16 | podSelector: 17 | matchLabels: {{- include "sealed-secrets.matchLabels" . | nindent 6 }} 18 | ingress: 19 | - ports: 20 | - port: {{ .Values.service.port }} 21 | - port: {{ .Values.metrics.service.port }} 22 | {{- if .Values.networkPolicy.egress.enabled }} 23 | egress: 24 | - to: 25 | {{- if not .Values.networkPolicy.egress.kubeapiCidr }} 26 | {{- $kubernetesEndpoint := lookup "v1" "Endpoints" "default" "kubernetes" }} 27 | {{- if $kubernetesEndpoint }} 28 | {{- range $kubernetesAddress := (first $kubernetesEndpoint.subsets).addresses }} 29 | - ipBlock: 30 | cidr: {{ $kubernetesAddress.ip }}/32 31 | {{- end}} 32 | ports: 33 | {{- range $kubernetesPort := (first $kubernetesEndpoint.subsets).ports }} 34 | - protocol: {{ $kubernetesPort.protocol }} 35 | port: {{ $kubernetesPort.port }} 36 | {{- end }} 37 | {{- end}} 38 | {{- else }} 39 | - ipBlock: 40 | cidr: {{ .Values.networkPolicy.egress.kubeapiCidr }} 41 | ports: 42 | - protocol: TCP 43 | port: {{ .Values.networkPolicy.egress.kubeapiPort }} 44 | {{- end }} 45 | {{- end }} 46 | {{- end }} 47 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pdb.create }} 2 | kind: PodDisruptionBudget 3 | apiVersion: policy/v1 4 | metadata: 5 | name: {{ include "sealed-secrets.fullname" . }} 6 | namespace: {{ include "sealed-secrets.namespace" . }} 7 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 8 | {{- if .Values.commonLabels }} 9 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 10 | {{- end }} 11 | annotations: 12 | {{- if .Values.commonAnnotations }} 13 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 14 | {{- end }} 15 | spec: 16 | {{- if regexMatch "64$" (typeOf .Values.pdb.minAvailable) }} 17 | minAvailable: {{ .Values.pdb.minAvailable }} 18 | {{- end }} 19 | {{- if regexMatch "64$" (typeOf .Values.pdb.maxUnavailable) }} 20 | maxUnavailable: {{ .Values.pdb.maxUnavailable }} 21 | {{- end }} 22 | selector: 23 | matchLabels: {{- include "sealed-secrets.matchLabels" . | nindent 6 }} 24 | {{- end }} 25 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/psp-clusterrole.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.pspEnabled }} 2 | kind: ClusterRole 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | name: {{ printf "%s-psp" (include "sealed-secrets.fullname" .) }} 6 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 7 | {{- if .Values.rbac.labels }} 8 | {{- include "sealed-secrets.render" ( dict "value" .Values.rbac.labels "context" $) | nindent 4 }} 9 | {{- end }} 10 | {{- if .Values.commonLabels }} 11 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 12 | {{- end }} 13 | annotations: 14 | {{- if .Values.commonAnnotations }} 15 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 16 | {{- end }} 17 | rules: 18 | - apiGroups: ['extensions'] 19 | resources: ['podsecuritypolicies'] 20 | verbs: ['use'] 21 | resourceNames: 22 | - {{ include "sealed-secrets.fullname" . }} 23 | {{- end }} 24 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/psp-clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.pspEnabled }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | name: {{ printf "%s-psp" (include "sealed-secrets.fullname" .) }} 6 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 7 | {{- if .Values.rbac.labels }} 8 | {{- include "sealed-secrets.render" ( dict "value" .Values.rbac.labels "context" $) | nindent 4 }} 9 | {{- end }} 10 | {{- if .Values.commonLabels }} 11 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 12 | {{- end }} 13 | annotations: 14 | {{- if .Values.commonAnnotations }} 15 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 16 | {{- end }} 17 | roleRef: 18 | apiGroup: rbac.authorization.k8s.io 19 | kind: ClusterRole 20 | name: {{ printf "%s-psp" (include "sealed-secrets.fullname" .) }} 21 | subjects: 22 | - kind: ServiceAccount 23 | name: {{ include "sealed-secrets.serviceAccountName" . }} 24 | namespace: {{ include "sealed-secrets.namespace" . }} 25 | {{- end }} 26 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/psp.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.pspEnabled }} 2 | apiVersion: policy/v1beta1 3 | kind: PodSecurityPolicy 4 | metadata: 5 | name: {{ include "sealed-secrets.fullname" . }} 6 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 7 | {{- if .Values.commonLabels }} 8 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 9 | {{- end }} 10 | annotations: 11 | {{- if .Values.commonAnnotations }} 12 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 13 | {{- end }} 14 | spec: 15 | privileged: false 16 | allowPrivilegeEscalation: false 17 | allowedCapabilities: [] 18 | volumes: 19 | - 'configMap' 20 | - 'emptyDir' 21 | - 'projected' 22 | - 'secret' 23 | - 'downwardAPI' 24 | - 'persistentVolumeClaim' 25 | {{- if not .Values.hostNetwork }} 26 | hostNetwork: false 27 | {{- end }} 28 | hostIPC: false 29 | hostPID: false 30 | runAsUser: 31 | rule: 'RunAsAny' 32 | seLinux: 33 | rule: 'RunAsAny' 34 | supplementalGroups: 35 | rule: 'RunAsAny' 36 | fsGroup: 37 | rule: 'RunAsAny' 38 | {{- end }} 39 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/service-account.yaml: -------------------------------------------------------------------------------- 1 | {{ if .Values.serviceAccount.create }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "sealed-secrets.serviceAccountName" . }} 6 | namespace: {{ include "sealed-secrets.namespace" . }} 7 | {{- if or (.Values.commonAnnotations) (.Values.serviceAccount.annotations) }} 8 | annotations: 9 | {{- if .Values.commonAnnotations }} 10 | {{- toYaml .Values.commonAnnotations | nindent 4 }} 11 | {{- end}} 12 | {{- if .Values.serviceAccount.annotations }} 13 | {{- toYaml .Values.serviceAccount.annotations | nindent 4 }} 14 | {{- end}} 15 | {{- end }} 16 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 17 | {{- if .Values.serviceAccount.labels }} 18 | {{- include "sealed-secrets.render" ( dict "value" .Values.serviceAccount.labels "context" $) | nindent 4 }} 19 | {{- end }} 20 | {{- if .Values.commonLabels }} 21 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 22 | {{- end }} 23 | {{ end }} 24 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.metrics.serviceMonitor.enabled }} 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | name: {{ include "sealed-secrets.fullname" . }} 6 | {{- if .Values.metrics.serviceMonitor.namespace }} 7 | namespace: {{ .Values.metrics.serviceMonitor.namespace }} 8 | {{- else }} 9 | namespace: {{ include "sealed-secrets.namespace" . }} 10 | {{- end }} 11 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 12 | {{- if .Values.metrics.serviceMonitor.labels }} 13 | {{- include "sealed-secrets.render" ( dict "value" .Values.metrics.serviceMonitor.labels "context" $) | nindent 4 }} 14 | {{- end }} 15 | {{- if .Values.commonLabels }} 16 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 17 | {{- end }} 18 | annotations: 19 | {{- if .Values.metrics.serviceMonitor.annotations }} 20 | {{- include "sealed-secrets.render" (dict "value" .Values.metrics.serviceMonitor.annotations "context" $) | nindent 4 }} 21 | {{- end }} 22 | {{- if .Values.commonAnnotations }} 23 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 24 | {{- end }} 25 | spec: 26 | endpoints: 27 | - port: metrics 28 | {{- if .Values.metrics.serviceMonitor.honorLabels }} 29 | honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} 30 | {{- end }} 31 | {{- if .Values.metrics.serviceMonitor.interval }} 32 | interval: {{ .Values.metrics.serviceMonitor.interval }} 33 | {{- end }} 34 | {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} 35 | scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} 36 | {{- end }} 37 | {{- if .Values.metrics.serviceMonitor.metricRelabelings }} 38 | metricRelabelings: {{ toYaml .Values.metrics.serviceMonitor.metricRelabelings | nindent 8 }} 39 | {{- end }} 40 | {{- if .Values.metrics.serviceMonitor.relabelings }} 41 | relabelings: {{ toYaml .Values.metrics.serviceMonitor.relabelings | nindent 8 }} 42 | {{- end }} 43 | namespaceSelector: 44 | matchNames: 45 | - {{ include "sealed-secrets.namespace" . }} 46 | selector: 47 | matchLabels: 48 | {{- include "sealed-secrets.matchLabels" . | nindent 6 }} 49 | app.kubernetes.io/component: metrics 50 | {{- end }} 51 | -------------------------------------------------------------------------------- /helm/sealed-secrets/templates/tls-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.createController .Values.ingress.enabled }} 2 | {{- if .Values.ingress.secrets }} 3 | {{- range .Values.ingress.secrets }} 4 | apiVersion: v1 5 | kind: Secret 6 | metadata: 7 | name: {{ .name }} 8 | namespace: {{ include "sealed-secrets.namespace" $ | quote }} 9 | labels: {{- include "sealed-secrets.labels" $ | nindent 4 }} 10 | {{- if .Values.commonLabels }} 11 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 12 | {{- end }} 13 | annotations: 14 | {{- if .Values.commonAnnotations }} 15 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 16 | {{- end }} 17 | type: kubernetes.io/tls 18 | data: 19 | tls.crt: {{ .certificate | b64enc }} 20 | tls.key: {{ .key | b64enc }} 21 | --- 22 | {{- end }} 23 | {{- end }} 24 | {{- if and .Values.ingress.tls .Values.ingress.selfSigned }} 25 | {{- $ca := genCA "sealed-secrets-ca" 365 }} 26 | {{- $cert := genSignedCert .Values.ingress.hostname nil (list .Values.ingress.hostname) 365 $ca }} 27 | apiVersion: v1 28 | kind: Secret 29 | metadata: 30 | name: {{ printf "%s-tls" .Values.ingress.hostname }} 31 | namespace: {{ include "sealed-secrets.namespace" . }} 32 | labels: {{- include "sealed-secrets.labels" . | nindent 4 }} 33 | {{- if .Values.commonLabels }} 34 | {{- include "sealed-secrets.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} 35 | {{- end }} 36 | annotations: 37 | {{- if .Values.commonAnnotations }} 38 | {{- include "sealed-secrets.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 39 | {{- end }} 40 | type: kubernetes.io/tls 41 | data: 42 | tls.crt: {{ $cert.Cert | b64enc | quote }} 43 | tls.key: {{ $cert.Key | b64enc | quote }} 44 | ca.crt: {{ $ca.Cert | b64enc | quote }} 45 | {{- end }} 46 | {{- end }} 47 | -------------------------------------------------------------------------------- /jsonnetfile.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "name": "kube-libsonnet", 5 | "source": { 6 | "git": { 7 | "remote": "https://github.com/bitnami-labs/kube-libsonnet", 8 | "subdir": "" 9 | } 10 | }, 11 | "version": "master" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /jsonnetfile.lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "name": "kube-libsonnet", 5 | "source": { 6 | "git": { 7 | "remote": "https://github.com/bitnami-labs/kube-libsonnet", 8 | "subdir": "" 9 | } 10 | }, 11 | "version": "7df1459e6d890d54eb96ea3df70d7c84b8b3fb0e" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /kube-fixes.libsonnet: -------------------------------------------------------------------------------- 1 | { 2 | CustomResourceDefinition(group, version, kind): { 3 | local this = self, 4 | apiVersion: 'apiextensions.k8s.io/v1', 5 | kind: 'CustomResourceDefinition', 6 | metadata+: { 7 | name: this.spec.names.plural + '.' + this.spec.group, 8 | }, 9 | spec: { 10 | scope: 'Namespaced', 11 | group: group, 12 | versions_:: { 13 | [version]: { 14 | served: true, 15 | storage: true, 16 | }, 17 | }, 18 | versions: $.mapToNamedList(self.versions_), 19 | names: { 20 | kind: kind, 21 | singular: $.toLower(self.kind), 22 | plural: self.singular + 's', 23 | listKind: self.kind + 'List', 24 | }, 25 | }, 26 | }, 27 | } 28 | -------------------------------------------------------------------------------- /pkg/apis/sealedsecrets/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | // +k8s:deepcopy-gen=package,register 2 | 3 | // +groupName=bitnami.com 4 | 5 | // Package v1alpha1 contains the definition of the sealed-secrets v1alpha1 API. Some of the code in this package is generated. 6 | package v1alpha1 7 | -------------------------------------------------------------------------------- /pkg/apis/sealedsecrets/v1alpha1/register.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | import ( 4 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 5 | "k8s.io/apimachinery/pkg/runtime" 6 | "k8s.io/apimachinery/pkg/runtime/schema" 7 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 8 | "k8s.io/client-go/kubernetes/scheme" 9 | ) 10 | 11 | // GroupName is the group name used in this package. 12 | const GroupName = "bitnami.com" 13 | 14 | var ( 15 | // SchemeGroupVersion is the group version used to register these objects. 16 | SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} 17 | 18 | // SchemeBuilder adds this group to scheme. 19 | SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) 20 | // AddToScheme is a global function that registers this API group & version to a scheme. 21 | AddToScheme = SchemeBuilder.AddToScheme 22 | ) 23 | 24 | func init() { 25 | utilruntime.Must(SchemeBuilder.AddToScheme(scheme.Scheme)) 26 | } 27 | 28 | // Resource takes an unqualified resource and returns a Group qualified GroupResource. 29 | func Resource(resource string) schema.GroupResource { 30 | return SchemeGroupVersion.WithResource(resource).GroupResource() 31 | } 32 | 33 | func addKnownTypes(scheme *runtime.Scheme) error { 34 | scheme.AddKnownTypes(SchemeGroupVersion, 35 | &SealedSecret{}, 36 | &SealedSecretList{}, 37 | ) 38 | metav1.AddToGroupVersion(scheme, SchemeGroupVersion) 39 | return nil 40 | } 41 | -------------------------------------------------------------------------------- /pkg/buildinfo/version.go: -------------------------------------------------------------------------------- 1 | package buildinfo 2 | 3 | import "runtime/debug" 4 | 5 | // DefaultVersion is the default version string if it's unset. 6 | const DefaultVersion = "UNKNOWN" 7 | 8 | // FallbackVersion initializes the automatic version detection. 9 | func FallbackVersion(v *string, unchanged string) { 10 | if *v != unchanged { 11 | return 12 | } 13 | b, ok := debug.ReadBuildInfo() 14 | if !ok { 15 | return 16 | } 17 | if modv := b.Main.Version; modv != "(devel)" { 18 | *v = modv 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/fake/clientset_generated.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | package fake 4 | 5 | import ( 6 | clientset "github.com/bitnami-labs/sealed-secrets/pkg/client/clientset/versioned" 7 | bitnamiv1alpha1 "github.com/bitnami-labs/sealed-secrets/pkg/client/clientset/versioned/typed/sealedsecrets/v1alpha1" 8 | fakebitnamiv1alpha1 "github.com/bitnami-labs/sealed-secrets/pkg/client/clientset/versioned/typed/sealedsecrets/v1alpha1/fake" 9 | "k8s.io/apimachinery/pkg/runtime" 10 | "k8s.io/apimachinery/pkg/watch" 11 | "k8s.io/client-go/discovery" 12 | fakediscovery "k8s.io/client-go/discovery/fake" 13 | "k8s.io/client-go/testing" 14 | ) 15 | 16 | // NewSimpleClientset returns a clientset that will respond with the provided objects. 17 | // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, 18 | // without applying any validations and/or defaults. It shouldn't be considered a replacement 19 | // for a real clientset and is mostly useful in simple unit tests. 20 | func NewSimpleClientset(objects ...runtime.Object) *Clientset { 21 | o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) 22 | for _, obj := range objects { 23 | if err := o.Add(obj); err != nil { 24 | panic(err) 25 | } 26 | } 27 | 28 | cs := &Clientset{tracker: o} 29 | cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} 30 | cs.AddReactor("*", "*", testing.ObjectReaction(o)) 31 | cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { 32 | gvr := action.GetResource() 33 | ns := action.GetNamespace() 34 | watch, err := o.Watch(gvr, ns) 35 | if err != nil { 36 | return false, nil, err 37 | } 38 | return true, watch, nil 39 | }) 40 | 41 | return cs 42 | } 43 | 44 | // Clientset implements clientset.Interface. Meant to be embedded into a 45 | // struct to get a default implementation. This makes faking out just the method 46 | // you want to test easier. 47 | type Clientset struct { 48 | testing.Fake 49 | discovery *fakediscovery.FakeDiscovery 50 | tracker testing.ObjectTracker 51 | } 52 | 53 | func (c *Clientset) Discovery() discovery.DiscoveryInterface { 54 | return c.discovery 55 | } 56 | 57 | func (c *Clientset) Tracker() testing.ObjectTracker { 58 | return c.tracker 59 | } 60 | 61 | var ( 62 | _ clientset.Interface = &Clientset{} 63 | _ testing.FakeClient = &Clientset{} 64 | ) 65 | 66 | // BitnamiV1alpha1 retrieves the BitnamiV1alpha1Client 67 | func (c *Clientset) BitnamiV1alpha1() bitnamiv1alpha1.BitnamiV1alpha1Interface { 68 | return &fakebitnamiv1alpha1.FakeBitnamiV1alpha1{Fake: &c.Fake} 69 | } 70 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/fake/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | // This package has the automatically generated fake clientset. 4 | package fake 5 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/fake/register.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | package fake 4 | 5 | import ( 6 | bitnamiv1alpha1 "github.com/bitnami-labs/sealed-secrets/pkg/apis/sealedsecrets/v1alpha1" 7 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | runtime "k8s.io/apimachinery/pkg/runtime" 9 | schema "k8s.io/apimachinery/pkg/runtime/schema" 10 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 11 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 12 | ) 13 | 14 | var scheme = runtime.NewScheme() 15 | var codecs = serializer.NewCodecFactory(scheme) 16 | 17 | var localSchemeBuilder = runtime.SchemeBuilder{ 18 | bitnamiv1alpha1.AddToScheme, 19 | } 20 | 21 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 22 | // of clientsets, like in: 23 | // 24 | // import ( 25 | // "k8s.io/client-go/kubernetes" 26 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 27 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 28 | // ) 29 | // 30 | // kclientset, _ := kubernetes.NewForConfig(c) 31 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 32 | // 33 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 34 | // correctly. 35 | var AddToScheme = localSchemeBuilder.AddToScheme 36 | 37 | func init() { 38 | v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) 39 | utilruntime.Must(AddToScheme(scheme)) 40 | } 41 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/scheme/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | // This package contains the scheme of the automatically generated clientset. 4 | package scheme 5 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/scheme/register.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | package scheme 4 | 5 | import ( 6 | bitnamiv1alpha1 "github.com/bitnami-labs/sealed-secrets/pkg/apis/sealedsecrets/v1alpha1" 7 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | runtime "k8s.io/apimachinery/pkg/runtime" 9 | schema "k8s.io/apimachinery/pkg/runtime/schema" 10 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 11 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 12 | ) 13 | 14 | var Scheme = runtime.NewScheme() 15 | var Codecs = serializer.NewCodecFactory(Scheme) 16 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 17 | var localSchemeBuilder = runtime.SchemeBuilder{ 18 | bitnamiv1alpha1.AddToScheme, 19 | } 20 | 21 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 22 | // of clientsets, like in: 23 | // 24 | // import ( 25 | // "k8s.io/client-go/kubernetes" 26 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 27 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 28 | // ) 29 | // 30 | // kclientset, _ := kubernetes.NewForConfig(c) 31 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 32 | // 33 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 34 | // correctly. 35 | var AddToScheme = localSchemeBuilder.AddToScheme 36 | 37 | func init() { 38 | v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) 39 | utilruntime.Must(AddToScheme(Scheme)) 40 | } 41 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/sealedsecrets/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | // This package has the automatically generated typed clients. 4 | package v1alpha1 5 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/sealedsecrets/v1alpha1/fake/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | // Package fake has the automatically generated clients. 4 | package fake 5 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/sealedsecrets/v1alpha1/fake/fake_sealedsecrets_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | package fake 4 | 5 | import ( 6 | v1alpha1 "github.com/bitnami-labs/sealed-secrets/pkg/client/clientset/versioned/typed/sealedsecrets/v1alpha1" 7 | rest "k8s.io/client-go/rest" 8 | testing "k8s.io/client-go/testing" 9 | ) 10 | 11 | type FakeBitnamiV1alpha1 struct { 12 | *testing.Fake 13 | } 14 | 15 | func (c *FakeBitnamiV1alpha1) SealedSecrets(namespace string) v1alpha1.SealedSecretInterface { 16 | return &FakeSealedSecrets{c, namespace} 17 | } 18 | 19 | // RESTClient returns a RESTClient that is used to communicate 20 | // with API server by this client implementation. 21 | func (c *FakeBitnamiV1alpha1) RESTClient() rest.Interface { 22 | var ret *rest.RESTClient 23 | return ret 24 | } 25 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/sealedsecrets/v1alpha1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | package v1alpha1 4 | 5 | type SealedSecretExpansion interface{} 6 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/sealedsecrets/v1alpha1/sealedsecrets_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | package v1alpha1 4 | 5 | import ( 6 | "net/http" 7 | 8 | v1alpha1 "github.com/bitnami-labs/sealed-secrets/pkg/apis/sealedsecrets/v1alpha1" 9 | "github.com/bitnami-labs/sealed-secrets/pkg/client/clientset/versioned/scheme" 10 | rest "k8s.io/client-go/rest" 11 | ) 12 | 13 | type BitnamiV1alpha1Interface interface { 14 | RESTClient() rest.Interface 15 | SealedSecretsGetter 16 | } 17 | 18 | // BitnamiV1alpha1Client is used to interact with features provided by the bitnami.com group. 19 | type BitnamiV1alpha1Client struct { 20 | restClient rest.Interface 21 | } 22 | 23 | func (c *BitnamiV1alpha1Client) SealedSecrets(namespace string) SealedSecretInterface { 24 | return newSealedSecrets(c, namespace) 25 | } 26 | 27 | // NewForConfig creates a new BitnamiV1alpha1Client for the given config. 28 | // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), 29 | // where httpClient was generated with rest.HTTPClientFor(c). 30 | func NewForConfig(c *rest.Config) (*BitnamiV1alpha1Client, error) { 31 | config := *c 32 | if err := setConfigDefaults(&config); err != nil { 33 | return nil, err 34 | } 35 | httpClient, err := rest.HTTPClientFor(&config) 36 | if err != nil { 37 | return nil, err 38 | } 39 | return NewForConfigAndClient(&config, httpClient) 40 | } 41 | 42 | // NewForConfigAndClient creates a new BitnamiV1alpha1Client for the given config and http client. 43 | // Note the http client provided takes precedence over the configured transport values. 44 | func NewForConfigAndClient(c *rest.Config, h *http.Client) (*BitnamiV1alpha1Client, error) { 45 | config := *c 46 | if err := setConfigDefaults(&config); err != nil { 47 | return nil, err 48 | } 49 | client, err := rest.RESTClientForConfigAndClient(&config, h) 50 | if err != nil { 51 | return nil, err 52 | } 53 | return &BitnamiV1alpha1Client{client}, nil 54 | } 55 | 56 | // NewForConfigOrDie creates a new BitnamiV1alpha1Client for the given config and 57 | // panics if there is an error in the config. 58 | func NewForConfigOrDie(c *rest.Config) *BitnamiV1alpha1Client { 59 | client, err := NewForConfig(c) 60 | if err != nil { 61 | panic(err) 62 | } 63 | return client 64 | } 65 | 66 | // New creates a new BitnamiV1alpha1Client for the given RESTClient. 67 | func New(c rest.Interface) *BitnamiV1alpha1Client { 68 | return &BitnamiV1alpha1Client{c} 69 | } 70 | 71 | func setConfigDefaults(config *rest.Config) error { 72 | gv := v1alpha1.SchemeGroupVersion 73 | config.GroupVersion = &gv 74 | config.APIPath = "/apis" 75 | config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() 76 | 77 | if config.UserAgent == "" { 78 | config.UserAgent = rest.DefaultKubernetesUserAgent() 79 | } 80 | 81 | return nil 82 | } 83 | 84 | // RESTClient returns a RESTClient that is used to communicate 85 | // with API server by this client implementation. 86 | func (c *BitnamiV1alpha1Client) RESTClient() rest.Interface { 87 | if c == nil { 88 | return nil 89 | } 90 | return c.restClient 91 | } 92 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/generic.go: -------------------------------------------------------------------------------- 1 | // Code generated by informer-gen. DO NOT EDIT. 2 | 3 | package externalversions 4 | 5 | import ( 6 | "fmt" 7 | 8 | v1alpha1 "github.com/bitnami-labs/sealed-secrets/pkg/apis/sealedsecrets/v1alpha1" 9 | schema "k8s.io/apimachinery/pkg/runtime/schema" 10 | cache "k8s.io/client-go/tools/cache" 11 | ) 12 | 13 | // GenericInformer is type of SharedIndexInformer which will locate and delegate to other 14 | // sharedInformers based on type 15 | type GenericInformer interface { 16 | Informer() cache.SharedIndexInformer 17 | Lister() cache.GenericLister 18 | } 19 | 20 | type genericInformer struct { 21 | informer cache.SharedIndexInformer 22 | resource schema.GroupResource 23 | } 24 | 25 | // Informer returns the SharedIndexInformer. 26 | func (f *genericInformer) Informer() cache.SharedIndexInformer { 27 | return f.informer 28 | } 29 | 30 | // Lister returns the GenericLister. 31 | func (f *genericInformer) Lister() cache.GenericLister { 32 | return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) 33 | } 34 | 35 | // ForResource gives generic access to a shared informer of the matching type 36 | // TODO extend this to unknown resources with a client pool 37 | func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { 38 | switch resource { 39 | // Group=bitnami.com, Version=v1alpha1 40 | case v1alpha1.SchemeGroupVersion.WithResource("sealedsecrets"): 41 | return &genericInformer{resource: resource.GroupResource(), informer: f.Bitnami().V1alpha1().SealedSecrets().Informer()}, nil 42 | 43 | } 44 | 45 | return nil, fmt.Errorf("no informer found for %v", resource) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go: -------------------------------------------------------------------------------- 1 | // Code generated by informer-gen. DO NOT EDIT. 2 | 3 | package internalinterfaces 4 | 5 | import ( 6 | time "time" 7 | 8 | versioned "github.com/bitnami-labs/sealed-secrets/pkg/client/clientset/versioned" 9 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 | runtime "k8s.io/apimachinery/pkg/runtime" 11 | cache "k8s.io/client-go/tools/cache" 12 | ) 13 | 14 | // NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. 15 | type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer 16 | 17 | // SharedInformerFactory a small interface to allow for adding an informer without an import cycle 18 | type SharedInformerFactory interface { 19 | Start(stopCh <-chan struct{}) 20 | InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer 21 | } 22 | 23 | // TweakListOptionsFunc is a function that transforms a v1.ListOptions. 24 | type TweakListOptionsFunc func(*v1.ListOptions) 25 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/sealedsecrets/interface.go: -------------------------------------------------------------------------------- 1 | // Code generated by informer-gen. DO NOT EDIT. 2 | 3 | package sealedsecrets 4 | 5 | import ( 6 | internalinterfaces "github.com/bitnami-labs/sealed-secrets/pkg/client/informers/externalversions/internalinterfaces" 7 | v1alpha1 "github.com/bitnami-labs/sealed-secrets/pkg/client/informers/externalversions/sealedsecrets/v1alpha1" 8 | ) 9 | 10 | // Interface provides access to each of this group's versions. 11 | type Interface interface { 12 | // V1alpha1 provides access to shared informers for resources in V1alpha1. 13 | V1alpha1() v1alpha1.Interface 14 | } 15 | 16 | type group struct { 17 | factory internalinterfaces.SharedInformerFactory 18 | namespace string 19 | tweakListOptions internalinterfaces.TweakListOptionsFunc 20 | } 21 | 22 | // New returns a new Interface. 23 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 24 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 25 | } 26 | 27 | // V1alpha1 returns a new v1alpha1.Interface. 28 | func (g *group) V1alpha1() v1alpha1.Interface { 29 | return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) 30 | } 31 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/sealedsecrets/v1alpha1/interface.go: -------------------------------------------------------------------------------- 1 | // Code generated by informer-gen. DO NOT EDIT. 2 | 3 | package v1alpha1 4 | 5 | import ( 6 | internalinterfaces "github.com/bitnami-labs/sealed-secrets/pkg/client/informers/externalversions/internalinterfaces" 7 | ) 8 | 9 | // Interface provides access to all the informers in this group version. 10 | type Interface interface { 11 | // SealedSecrets returns a SealedSecretInformer. 12 | SealedSecrets() SealedSecretInformer 13 | } 14 | 15 | type version struct { 16 | factory internalinterfaces.SharedInformerFactory 17 | namespace string 18 | tweakListOptions internalinterfaces.TweakListOptionsFunc 19 | } 20 | 21 | // New returns a new Interface. 22 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 23 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 24 | } 25 | 26 | // SealedSecrets returns a SealedSecretInformer. 27 | func (v *version) SealedSecrets() SealedSecretInformer { 28 | return &sealedSecretInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 29 | } 30 | -------------------------------------------------------------------------------- /pkg/client/listers/sealedsecrets/v1alpha1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | // Code generated by lister-gen. DO NOT EDIT. 2 | 3 | package v1alpha1 4 | 5 | // SealedSecretListerExpansion allows custom methods to be added to 6 | // SealedSecretLister. 7 | type SealedSecretListerExpansion interface{} 8 | 9 | // SealedSecretNamespaceListerExpansion allows custom methods to be added to 10 | // SealedSecretNamespaceLister. 11 | type SealedSecretNamespaceListerExpansion interface{} 12 | -------------------------------------------------------------------------------- /pkg/controller/funcs.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "time" 7 | ) 8 | 9 | // ScheduleJobWithTrigger creates a long-running loop that runs a job after an initialDelay 10 | // and then after each period duration. 11 | // It returns a trigger function that runs the job early when called. 12 | func ScheduleJobWithTrigger(initialDelay, period time.Duration, job func()) func() { 13 | trigger := make(chan struct{}) 14 | go func() { 15 | for { 16 | <-trigger 17 | job() 18 | } 19 | }() 20 | go func() { 21 | time.Sleep(initialDelay) 22 | for { 23 | trigger <- struct{}{} 24 | time.Sleep(period) 25 | } 26 | }() 27 | return func() { 28 | trigger <- struct{}{} 29 | } 30 | } 31 | 32 | const ( 33 | kubeChars = "abcdefghijklmnopqrstuvwxyz0123456789-" // Acceptable characters in k8s resource name 34 | maxNameLength = 245 // Max resource name length is 253, leave some room for a suffix 35 | ) 36 | 37 | func validateKeyPrefix(name string) (string, error) { 38 | if len(name) > maxNameLength { 39 | return "", fmt.Errorf("name is too long, must be shorter than %d, got %d", maxNameLength, len(name)) 40 | } 41 | for _, char := range name { 42 | if !strings.ContainsRune(kubeChars, char) { 43 | return "", fmt.Errorf("name contains illegal character %c", char) 44 | } 45 | } 46 | return name, nil 47 | } 48 | 49 | func removeDuplicates(strSlice []string) []string { 50 | allKeys := make(map[string]bool) 51 | list := []string{} 52 | for _, item := range strSlice { 53 | if _, value := allKeys[item]; !value { 54 | allKeys[item] = true 55 | list = append(list, item) 56 | } 57 | } 58 | return list 59 | } 60 | -------------------------------------------------------------------------------- /pkg/controller/keyregistry_test.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestRegisterNewKey(t *testing.T) { 9 | const keySize = 2048 10 | validFor := time.Hour 11 | cn := "my-cn" 12 | kr := NewKeyRegistry(nil, "namespace", "prefix", "label", keySize) 13 | 14 | if kr.mostRecentKey != nil { 15 | t.Fatal("this test assumes a new key registry has no keys") 16 | } 17 | 18 | key1, cert1, err := generatePrivateKeyAndCert(keySize, validFor, cn) 19 | if err != nil { 20 | t.Fatal(err) 21 | } 22 | t1 := time.Now() 23 | 24 | key2, cert2, err := generatePrivateKeyAndCert(keySize, validFor, cn) 25 | if err != nil { 26 | t.Fatal(err) 27 | } 28 | t2 := time.Now() 29 | 30 | if err := kr.registerNewKey("k2", key2, cert2, t2); err != nil { 31 | t.Fatal(err) 32 | } 33 | if got, want := kr.mostRecentKey.private, key2; got != want { 34 | t.Errorf("got: %v, want: %v", got, want) 35 | } 36 | 37 | // key1 is older, so it shouldn't replace key2 as the mostRecentKey 38 | if err := kr.registerNewKey("k1", key1, cert1, t1); err != nil { 39 | t.Fatal(err) 40 | } 41 | if got, want := kr.mostRecentKey.private, key2; got != want { 42 | t.Errorf("got: %v, want: %v", got, want) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /pkg/controller/server_test.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "crypto/x509" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "strings" 10 | "sync" 11 | "testing" 12 | "time" 13 | 14 | certUtil "k8s.io/client-go/util/cert" 15 | ) 16 | 17 | type testCertStore struct { 18 | sync.Mutex 19 | cert *x509.Certificate 20 | } 21 | 22 | func (c *testCertStore) getCert() ([]*x509.Certificate, error) { 23 | c.Lock() 24 | defer c.Unlock() 25 | return []*x509.Certificate{c.cert}, nil 26 | } 27 | 28 | func (c *testCertStore) setCert(cert *x509.Certificate) { 29 | c.Lock() 30 | defer c.Unlock() 31 | c.cert = cert 32 | } 33 | 34 | func shutdownServer(server *http.Server, t *testing.T) { 35 | err := server.Shutdown(context.Background()) 36 | if err != nil { 37 | t.Fatal(err) 38 | } 39 | } 40 | 41 | func TestHttpCert(t *testing.T) { 42 | validFor := time.Hour 43 | cn := "my-cn" 44 | _, certBefore, err := generatePrivateKeyAndCert(2048, validFor, cn) 45 | if err != nil { 46 | t.Fatal(err) 47 | } 48 | 49 | _, certAfter, err := generatePrivateKeyAndCert(2048, validFor, cn) 50 | if err != nil { 51 | t.Fatal(err) 52 | } 53 | 54 | cs := &testCertStore{} 55 | server := httpserver(cs.getCert, nil, nil, 2, 2) 56 | defer shutdownServer(server, t) 57 | hp := *listenAddr 58 | if strings.HasPrefix(hp, ":") { 59 | hp = fmt.Sprintf("localhost%s", hp) 60 | } 61 | 62 | time.Sleep(1 * time.Second) // TODO(mkm) find a better way, e.g. retries 63 | 64 | check := func(cert *x509.Certificate) { 65 | resp, err := http.Get(fmt.Sprintf("http://%s/v1/cert.pem", hp)) 66 | if err != nil { 67 | t.Fatal(err) 68 | } 69 | 70 | if got, want := resp.StatusCode, http.StatusOK; got != want { 71 | t.Fatalf("got: %v, want: %v", got, want) 72 | } 73 | defer resp.Body.Close() 74 | 75 | b, err := io.ReadAll(resp.Body) 76 | if err != nil { 77 | t.Fatal(err) 78 | } 79 | certs, err := certUtil.ParseCertsPEM(b) 80 | if err != nil { 81 | t.Fatal(err) 82 | } 83 | if got, want := len(certs), 1; got != want { 84 | t.Fatalf("got: %v, want: %v", got, want) 85 | } 86 | if got, want := certs[0], cert; !got.Equal(want) { 87 | t.Fatalf("got: %v, want: %v", got, want) 88 | } 89 | } 90 | 91 | cs.setCert(certBefore) 92 | check(certBefore) 93 | 94 | cs.setCert(certAfter) 95 | check(certAfter) 96 | } 97 | -------------------------------------------------------------------------------- /pkg/controller/signal_notwin.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package controller 5 | 6 | import ( 7 | "os" 8 | "os/signal" 9 | "syscall" 10 | ) 11 | 12 | func initKeyGenSignalListener(trigger func()) { 13 | sigChannel := make(chan os.Signal, 1) 14 | signal.Notify(sigChannel, syscall.SIGUSR1) 15 | go func() { 16 | for { 17 | <-sigChannel 18 | trigger() 19 | } 20 | }() 21 | } 22 | -------------------------------------------------------------------------------- /pkg/controller/signal_windows.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | func initKeyGenSignalListener(trigger func()) {} 4 | -------------------------------------------------------------------------------- /pkg/crypto/keys.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "crypto/rand" 5 | "crypto/rsa" 6 | "crypto/x509" 7 | "crypto/x509/pkix" 8 | "io" 9 | "math/big" 10 | "time" 11 | ) 12 | 13 | // GeneratePrivateKeyAndCert generates a keypair and signed certificate. 14 | func GeneratePrivateKeyAndCert(keySize int, validFor time.Duration, cn string) (*rsa.PrivateKey, *x509.Certificate, error) { 15 | r := rand.Reader 16 | privKey, err := rsa.GenerateKey(r, keySize) 17 | if err != nil { 18 | return nil, nil, err 19 | } 20 | cert, err := SignKey(r, privKey, validFor, cn) 21 | if err != nil { 22 | return nil, nil, err 23 | } 24 | return privKey, cert, nil 25 | } 26 | 27 | // SignKey returns a signed certificate. 28 | func SignKey(r io.Reader, key *rsa.PrivateKey, validFor time.Duration, cn string) (*x509.Certificate, error) { 29 | // TODO: use certificates API to get this signed by the cluster root CA 30 | // See https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/ 31 | 32 | return SignKeyWithNotBefore(r, key, time.Now(), validFor, cn) 33 | } 34 | 35 | // SignKeyWithNotBefore returns a signed certificate with custom notBefore. 36 | func SignKeyWithNotBefore(r io.Reader, key *rsa.PrivateKey, notBefore time.Time, validFor time.Duration, cn string) (*x509.Certificate, error) { 37 | // TODO: use certificates API to get this signed by the cluster root CA 38 | // See https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/ 39 | 40 | serialNo, err := rand.Int(r, new(big.Int).Lsh(big.NewInt(1), 128)) 41 | if err != nil { 42 | return nil, err 43 | } 44 | 45 | cert := x509.Certificate{ 46 | SerialNumber: serialNo, 47 | KeyUsage: x509.KeyUsageEncipherOnly, 48 | NotBefore: notBefore.UTC(), 49 | NotAfter: notBefore.Add(validFor).UTC(), 50 | Issuer: pkix.Name{ 51 | CommonName: cn, 52 | }, 53 | Subject: pkix.Name{ 54 | CommonName: cn, 55 | }, 56 | BasicConstraintsValid: true, 57 | IsCA: true, 58 | } 59 | 60 | data, err := x509.CreateCertificate(r, &cert, &cert, &key.PublicKey, key) 61 | if err != nil { 62 | return nil, err 63 | } 64 | 65 | return x509.ParseCertificate(data) 66 | } 67 | -------------------------------------------------------------------------------- /pkg/crypto/keys_test.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "crypto/rsa" 5 | "io" 6 | mathrand "math/rand" 7 | "reflect" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | // This is omg-not safe for real crypto use! 13 | func testRand() io.Reader { 14 | return mathrand.New(mathrand.NewSource(42)) 15 | } 16 | 17 | func TestSignKey(t *testing.T) { 18 | rand := testRand() 19 | 20 | key, err := rsa.GenerateKey(rand, 2048) 21 | if err != nil { 22 | t.Fatalf("Failed to generate test key: %v", err) 23 | } 24 | 25 | cert, err := SignKey(rand, key, time.Hour, "mycn") 26 | if err != nil { 27 | t.Errorf("signKey() returned error: %v", err) 28 | } 29 | 30 | if !reflect.DeepEqual(cert.PublicKey, &key.PublicKey) { 31 | t.Errorf("cert pubkey != original pubkey") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pkg/flagenv/flagenv.go: -------------------------------------------------------------------------------- 1 | // Package flagenv implements a simple way to expose all your flags as environmental variables. 2 | // 3 | // Commandline flags have more precedence over environment variables. 4 | // In order to use it just call flagenv.SetFlagsFromEnv from an init function or from your main. 5 | // 6 | // You can call it either before or after your your flag.Parse invocation. 7 | // 8 | // This example will make it possible to set the default of --my_flag also via the MY_PROG_MY_FLAG 9 | // env var: 10 | // 11 | // var myflag = flag.String("my_flag", "", "some flag") 12 | // 13 | // func init() { 14 | // flagenv.SetFlagsFromEnv("MY_PROG", flag.CommandLine) 15 | // } 16 | // 17 | // func main() { 18 | // flags.Parse() 19 | // ... 20 | // } 21 | package flagenv 22 | 23 | import ( 24 | "flag" 25 | "fmt" 26 | "os" 27 | "strings" 28 | ) 29 | 30 | // SetFlagsFromEnv sets flag values from environment, e.g. PREFIX_FOO_BAR set -foo_bar. 31 | // It sets only flags that haven't been set explicitly. The defaults are preserved and -help 32 | // will still show the defaults provided in the code. 33 | func SetFlagsFromEnv(prefix string, fs *flag.FlagSet) { 34 | set := map[string]bool{} 35 | fs.Visit(func(f *flag.Flag) { 36 | set[f.Name] = true 37 | }) 38 | fs.VisitAll(func(f *flag.Flag) { 39 | // ignore flags set from the commandline 40 | if set[f.Name] { 41 | return 42 | } 43 | // remove trailing _ to reduce common errors with the prefix, i.e. people setting it to MY_PROG_ 44 | cleanPrefix := strings.TrimSuffix(prefix, "_") 45 | name := fmt.Sprintf("%s_%s", cleanPrefix, strings.Replace(strings.ToUpper(f.Name), "-", "_", -1)) 46 | if e, ok := os.LookupEnv(name); ok { 47 | _ = f.Value.Set(e) 48 | } 49 | }) 50 | } 51 | -------------------------------------------------------------------------------- /pkg/flagenv/flagenv_test.go: -------------------------------------------------------------------------------- 1 | package flagenv_test 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "testing" 8 | 9 | "github.com/bitnami-labs/sealed-secrets/pkg/flagenv" 10 | ) 11 | 12 | func TestFlagenv(t *testing.T) { 13 | testCases := []struct { 14 | set bool 15 | val string 16 | want string 17 | }{ 18 | {false, "", "default"}, 19 | {true, "bar", "bar"}, 20 | {true, "", ""}, 21 | } 22 | for i, tc := range testCases { 23 | t.Run(fmt.Sprint(i), func(t *testing.T) { 24 | defer os.Unsetenv("MY_TEST_FOO") 25 | 26 | if tc.set { 27 | os.Setenv("MY_TEST_FOO", tc.val) 28 | } 29 | 30 | fs := flag.NewFlagSet("test", flag.PanicOnError) 31 | s := fs.String("foo", "default", "help") 32 | flagenv.SetFlagsFromEnv("MY_TEST", fs) 33 | 34 | _ = fs.Parse(nil) 35 | 36 | if got, want := *s, tc.want; got != want { 37 | t.Errorf("got %q, want %q", got, want) 38 | } 39 | }) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pkg/log/log.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log/slog" 7 | ) 8 | 9 | // MultiStreamHandler slog handler for directing different 10 | type MultiStreamHandler struct { 11 | level slog.Level 12 | lowHandler slog.Handler 13 | highHandler slog.Handler 14 | } 15 | 16 | // New returns new MultiStreamHandler 17 | func New(outLow, outHigh io.Writer, format string, opts *slog.HandlerOptions) *MultiStreamHandler { 18 | if format == "json" { 19 | return &MultiStreamHandler{ 20 | level: opts.Level.Level(), 21 | lowHandler: slog.NewJSONHandler(outLow, opts), 22 | highHandler: slog.NewJSONHandler(outHigh, opts), 23 | } 24 | } 25 | return &MultiStreamHandler{ 26 | level: opts.Level.Level(), 27 | lowHandler: slog.NewTextHandler(outLow, opts), 28 | highHandler: slog.NewTextHandler(outHigh, opts), 29 | } 30 | } 31 | 32 | // Enabled check if log level is enabled 33 | func (m *MultiStreamHandler) Enabled(ctx context.Context, level slog.Level) bool { 34 | return level >= m.level.Level() 35 | } 36 | 37 | // Handle pass to Low or High handlers based on log level 38 | func (m *MultiStreamHandler) Handle(ctx context.Context, r slog.Record) error { 39 | if r.Level <= slog.LevelInfo.Level() { 40 | return m.lowHandler.Handle(ctx, r) 41 | } 42 | return m.highHandler.Handle(ctx, r) 43 | } 44 | 45 | func (m *MultiStreamHandler) WithAttrs(attrs []slog.Attr) slog.Handler { 46 | // Not used within the code 47 | panic("Not implemented") 48 | } 49 | 50 | func (m *MultiStreamHandler) WithGroup(string) slog.Handler { 51 | // Not used within the code 52 | panic("Not implemented") 53 | } 54 | -------------------------------------------------------------------------------- /pkg/multidocyaml/multidocyaml.go: -------------------------------------------------------------------------------- 1 | package multidocyaml 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | 7 | "gopkg.in/yaml.v2" 8 | ) 9 | 10 | func isMultiDocumentYAML(src []byte) bool { 11 | dec := yaml.NewDecoder(bytes.NewReader(src)) 12 | var dummy struct{} 13 | _ = dec.Decode(&dummy) 14 | return dec.Decode(&dummy) == nil 15 | } 16 | 17 | // EnsureNotMultiDoc returns an error if the yaml. 18 | func EnsureNotMultiDoc(src []byte) error { 19 | if isMultiDocumentYAML(src) { 20 | return fmt.Errorf("Multistream YAML not supported yet (see https://github.com/bitnami-labs/sealed-secrets/issues/114)") 21 | } 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /pkg/multidocyaml/multidocyaml_test.go: -------------------------------------------------------------------------------- 1 | package multidocyaml 2 | 3 | import "testing" 4 | 5 | func TestIsMultiDocumentYAML(t *testing.T) { 6 | testCases := []struct { 7 | src string 8 | ok bool 9 | }{ 10 | {"foo", false}, 11 | {"foo\nbar\n", false}, 12 | {"---\nfoo", false}, 13 | {"foo\n---\n", true}, 14 | {"foo\n ---\n", false}, 15 | {"---\nfoo\n---\n", true}, 16 | } 17 | 18 | for _, tc := range testCases { 19 | if got, want := isMultiDocumentYAML([]byte(tc.src)), tc.ok; got != want { 20 | t.Errorf("got: %v, want: %v (src: %q)", got, want, tc.src) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /pkg/pflagenv/flagenv.go: -------------------------------------------------------------------------------- 1 | // Package pflagenv implements a simple way to expose all your pflag flags as environmental variables. 2 | // 3 | // Commandline flags have more precedence over environment variables. 4 | // In order to use it just call pflagenv.SetFlagsFromEnv from an init function or from your main. 5 | // 6 | // You can call it either before or after your your flag.Parse invocation. 7 | // 8 | // This example will make it possible to set the default of --my_flag also via the MY_PROG_MY_FLAG 9 | // env var: 10 | // 11 | // var myflag = pflag.String("my_flag", "", "some flag") 12 | // 13 | // func init() { 14 | // pflagenv.SetFlagsFromEnv("MY_PROG", pflag.CommandLine) 15 | // } 16 | // 17 | // func main() { 18 | // pflag.Parse() 19 | // ... 20 | // } 21 | package pflagenv 22 | 23 | import ( 24 | "fmt" 25 | "os" 26 | "strings" 27 | 28 | flag "github.com/spf13/pflag" 29 | ) 30 | 31 | // SetFlagsFromEnv sets flag values from environment, e.g. PREFIX_FOO_BAR set -foo_bar. 32 | // It sets only flags that haven't been set explicitly. The defaults are preserved and -help 33 | // will still show the defaults provided in the code. 34 | func SetFlagsFromEnv(prefix string, fs *flag.FlagSet) { 35 | set := map[string]bool{} 36 | fs.Visit(func(f *flag.Flag) { 37 | set[f.Name] = true 38 | }) 39 | fs.VisitAll(func(f *flag.Flag) { 40 | // ignore flags set from the commandline 41 | if set[f.Name] { 42 | return 43 | } 44 | // remove trailing _ to reduce common errors with the prefix, i.e. people setting it to MY_PROG_ 45 | cleanPrefix := strings.TrimSuffix(prefix, "_") 46 | name := fmt.Sprintf("%s_%s", cleanPrefix, strings.Replace(strings.ToUpper(f.Name), "-", "_", -1)) 47 | if e, ok := os.LookupEnv(name); ok { 48 | _ = f.Value.Set(e) 49 | } 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /pkg/pflagenv/flagenv_test.go: -------------------------------------------------------------------------------- 1 | package pflagenv_test 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | 8 | "github.com/bitnami-labs/sealed-secrets/pkg/pflagenv" 9 | flag "github.com/spf13/pflag" 10 | ) 11 | 12 | func TestPflagenv(t *testing.T) { 13 | testCases := []struct { 14 | set bool 15 | val string 16 | want string 17 | }{ 18 | {false, "", "default"}, 19 | {true, "bar", "bar"}, 20 | {true, "", ""}, 21 | } 22 | for i, tc := range testCases { 23 | t.Run(fmt.Sprint(i), func(t *testing.T) { 24 | defer os.Unsetenv("MY_TEST_FOO") 25 | 26 | if tc.set { 27 | os.Setenv("MY_TEST_FOO", tc.val) 28 | } 29 | 30 | fs := flag.NewFlagSet("test", flag.PanicOnError) 31 | s := fs.String("foo", "default", "help") 32 | pflagenv.SetFlagsFromEnv("MY_TEST", fs) 33 | 34 | _ = fs.Parse(nil) 35 | 36 | if got, want := *s, tc.want; got != want { 37 | t.Errorf("got %q, want %q", got, want) 38 | } 39 | }) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /scripts/check-k8s: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | export K8S_CONTEXT="${K8S_CONTEXT}" 6 | 7 | if kubectl config current-context > /dev/null ;then 8 | k8s_current_context=$(kubectl config current-context); 9 | if [ "${k8s_current_context}" != "${K8S_CONTEXT}" ]; then \ 10 | echo "Expected k8s context '${K8S_CONTEXT}' but got '${k8s_current_context}'"; 11 | exit 1; 12 | fi 13 | else 14 | echo "Set up your k8s config for '${K8S_CONTEXT}' (using minikube or kind for example)"; 15 | exit 1; 16 | fi 17 | 18 | echo "'${K8S_CONTEXT}' is configured as kubectl's current context" 19 | 20 | -------------------------------------------------------------------------------- /scripts/release-check: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o nounset 4 | 5 | function docker_tag_exists() { 6 | docker pull $1:$2 > /dev/null 7 | } 8 | 9 | function find_release() { 10 | curl -v --silent https://github.com/bitnami-labs/sealed-secrets/releases 2>&1 | grep -w kubeseal-$1 > /dev/null 11 | echo $? 12 | } 13 | 14 | 15 | RELEASE=$(find_release $2) 16 | if [ $RELEASE -ne 0 ] ; then 17 | if docker_tag_exists $1 $2; then 18 | echo 1 19 | else 20 | echo 0 21 | fi 22 | else 23 | echo 0 24 | fi 25 | -------------------------------------------------------------------------------- /site/.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | .DS_Store 3 | .sass-cache 4 | _ignore 5 | node_modules 6 | _site 7 | .jekyll 8 | .jekyll-metadata 9 | .bundle 10 | .vscode 11 | 12 | *.log 13 | *.js.map 14 | *.css.map 15 | .ruby-version 16 | public -------------------------------------------------------------------------------- /site/.hugo_build.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/.hugo_build.lock -------------------------------------------------------------------------------- /site/README.md: -------------------------------------------------------------------------------- 1 | # Website for [Sealed Secrets](https://sealed-secrets.netlify.app/) 2 | 3 | ## Deployment 4 | 5 | The website will be deployed to production each time a new commit gets merged into the main branch. It is deployed using Netlify. 6 | 7 | ## Requirements 8 | 9 | This site uses [Hugo](https://github.com/gohugoio/hugo) for rendering. It is recommended you run `hugo` locally to validate your changes render properly. 10 | 11 | ### Local Hugo Rendering 12 | 13 | Hugo is available for many platforms. It can be installed using: 14 | 15 | - Linux: Most native package managers 16 | - macOS: `brew install hugo` 17 | - Windows: `choco install hugo-extended -confirm` 18 | 19 | Once installed, you may run the following from the `/site` directory to access a rendered view of the documentation: 20 | 21 | ```bash 22 | cd site 23 | hugo server --disableFastRender 24 | ``` 25 | 26 | Access the site at [http://localhost:1313](http://localhost:1313). Press `Ctrl-C` when done viewing. 27 | -------------------------------------------------------------------------------- /site/archetypes/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ replace .Name "-" " " | title }}" 3 | date: {{ .Date }} 4 | draft: true 5 | --- 6 | 7 | -------------------------------------------------------------------------------- /site/config.yaml: -------------------------------------------------------------------------------- 1 | baseURL: "https://sealed-secrets.netlify.app" 2 | languageCode: "en-us" 3 | title: "Sealed Secrets" 4 | theme: "template" 5 | outputs: 6 | home: [ "HTML", "REDIRECTS" ] 7 | disableKinds: 8 | - taxonomy 9 | - term 10 | pygmentsCodefences: true 11 | pygmentsStyle: "pygments" 12 | markup: 13 | highlight: 14 | anchorLineNos: false 15 | codeFences: true 16 | guessSyntax: false 17 | hl_Lines: "" 18 | lineAnchors: "" 19 | lineNoStart: 1 20 | lineNos: false 21 | lineNumbersInTable: true 22 | noClasses: true 23 | style: native 24 | tabWidth: 4 25 | menu: 26 | docs: 27 | - name: Overview 28 | url: /docs/ 29 | weight: 100 30 | - name: Architecture 31 | url: /docs/architecture/ 32 | name: Demo 33 | url: /docs/demo/ 34 | - name: Scope 35 | url: /docs/scope/ 36 | - name: Update Images 37 | url: /docs/contributing/ 38 | params: 39 | twitter_url: "https://twitter.com/bitnami" 40 | github_url: "https://github.com/bitnami-labs/sealed-secrets" 41 | slack_url: "https://kubernetes.slack.com/messages/sealed-secrets" 42 | github_base_url: "https://github.com/bitnami-labs/sealed-secrets" 43 | use_advanced_docs: true 44 | docs_right_sidebar: true 45 | docs_search: false 46 | docs_search_index_name: index_name 47 | docs_search_api_key: api_key 48 | docs_versioning: true 49 | docs_latest: latest 50 | docs_versions: 51 | - latest 52 | mediaTypes: 53 | "text/netlify": 54 | delimiter: "" 55 | outputFormats: 56 | REDIRECTS: 57 | mediaType: "text/netlify" 58 | baseName: "_redirects" 59 | -------------------------------------------------------------------------------- /site/content/contributors/agarcia-oss.md: -------------------------------------------------------------------------------- 1 | --- 2 | first_name: Alfredo 3 | last_name: García 4 | image: /img/team/agarcia-oss.png 5 | github_handle: agarcia-oss 6 | --- 7 | Maintainer -------------------------------------------------------------------------------- /site/content/contributors/alvneiayu.md: -------------------------------------------------------------------------------- 1 | --- 2 | first_name: Alvaro 3 | last_name: Neira 4 | image: /img/team/alvneiayu.png 5 | github_handle: alvneiayu 6 | --- 7 | Maintainer -------------------------------------------------------------------------------- /site/content/contributors/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | headless: true 3 | --- -------------------------------------------------------------------------------- /site/content/docs/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Leo urna molestie at elementum eu facilisis sed odio. Non nisi est sit amet facilisis. 4 | 5 | ## Magna etiam tempor orci 6 | 7 | Congue eu consequat [scope](../scope/) ac felis donec et odio. 8 | 9 | Elit eget gravida cum sociis. Tempus quam pellentesque nec nam aliquam. 10 | Dolor purus non enim praesent elementum facilisis leo. 11 | 12 | ## Cras semper auctor neque vitae tempus 13 | 14 | Quis eleifend quam adipiscing vitae proin. Mauris pellentesque pulvinar 15 | pellentesque habitant morbi tristique senectus et. 16 | 17 | ## Ultrices vitae auctor eu augue ut lectus arcu bibendum. 18 | 19 | Ut aliquam purus sit amet. Id ornare arcu odio ut sem nulla pharetra. 20 | Justo nec ultrices dui sapien eget mi proin sed. 21 | Nulla malesuada pellentesque elit eget gravida. 22 | 23 | ### Imperdiet sed euismod 24 | 25 | ```bash 26 | nisi porta 27 | ``` 28 | 29 | ### Egestas pretium aenean 30 | 31 | ```bash 32 | pharetr/magna/ac/placerat/vestibulum 33 | ``` 34 | 35 | ### Vitae proin sagittis nisl 36 | 37 | 1. Rhoncus mattis rhoncus: 38 | 39 | - Ante in nibh mauris cursus mattis. 40 | - Elementum eu facilisis sed odio morbi quis commodo odio. 41 | - Id faucibus nisl tincidunt eget nullam non nisi est sit. 42 | - In fermentum posuere urna nec. 43 | - Interdum velit laoreet id donec ultrices tincidunt arcu non sodales. 44 | 45 | 46 | ```bash 47 | At urna condimentum mattis pellentesque id. Amet venenatis urna cursus eget. 48 | ``` 49 | 50 | 1. Ut tortor pretium viverra suspendisse `potenti`: 51 | 52 | ```bash 53 | Ut tortor pretium viverra suspendisse potenti. 54 | ``` 55 | 56 | 1. Arcu dui vivamus arcu felis bibendum ut `tristique et`: 57 | 58 | ```bash 59 | Ut tellus elementum sagittis vitae et leo duis ut. Urna nunc id cursus metus aliquam. 60 | ``` 61 | 62 | In metus vulputate eu scelerisque felis imperdiet proin fermentum leo. 63 | 64 | Suscipit adipiscing bibendum est ultricies `integer quis`. 65 | Cras pulvinar mattis nunc sed blandit nisl pretium `fusce id velit`. 66 | 67 | 68 | 1. Porta non pulvinar neque laoreet suspendisse interdum consectetur.: 69 | 70 | ```bash 71 | Senectus et netus et malesuada fames ac turpis egestas. 72 | ``` 73 | 74 | Leo urna molestie at elementum eu facilisis sed odio. Non nisi est sit amet facilisis magna etiam tempor orci. -------------------------------------------------------------------------------- /site/content/docs/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | version: latest 3 | cascade: 4 | layout: docs 5 | --- 6 | 7 | # Sealed Secrets documentation 8 | 9 | Explore the [latest version docs](./latest/) to get started. 10 | -------------------------------------------------------------------------------- /site/content/docs/img/_index.md: -------------------------------------------------------------------------------- 1 | # Update Images 2 | 3 | ## Imperdiet sed euismod nisi porta 4 | 5 | - [Image](placeholder-750x250.png) gestas pretium aenean `plantuml`. 6 | 7 | - [Image](placeholder-750x250.png) gestas pretium aenean `vestibulum`. 8 | 9 | - Vitae proin sagittis nisl rhoncus mattis rhoncus. Ante in nibh mauris cursus mattis. 10 | Elementum eu facilisis sed odio morbi quis commodo odio. Id faucibus nisl tincidunt eget nullam non nisi est sit. 11 | In fermentum posuere urna nec. Interdum velit laoreet id donec ultrices tincidunt arcu non sodales. 12 | At urna condimentum mattis pellentesque id. Amet venenatis urna cursus eget. -------------------------------------------------------------------------------- /site/content/docs/img/placeholder-750x250.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/content/docs/img/placeholder-750x250.png -------------------------------------------------------------------------------- /site/content/docs/latest/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Sealed Secrets documentation 3 | 4 | Everything you need to know about Sealed Secrets. 5 | 6 | > NOTE: we are currently moving our docs to a new website and reviewing our documentation files. During the process, eventual broken links and minor inconsistences may appear. Please, feel free to contact us if you have any questions: file an [issue](https://github.com/bitnami-labs/sealed-secrets/issues), or talk to us on the [#Sealed Secrets slack channel](https://kubernetes.slack.com/messages/sealed-secrets). 7 | 8 | ## Documentation overview 9 | 10 | A high-level overview of how it's organized will help Sealed Secrets contributors and users know where to look for certain things. 11 | 12 | | Section | Description | 13 | | --------------------------- | ----------------------------------------------------------------------------------------------------| 14 | | [Tutorials](./tutorials/) | Start here if you're new to Sealed Secrets. A hands-on introduction to Seled Secrets for new users. | 15 | | [How-to guides](./howto/) | They guide you through the steps involved in addressing key problems and use-cases. | 16 | | [Background](./background/) | Dive into the overall architecture and implementation details of Sealed Secrets. | 17 | | [Reference](./reference/) | Technical information - developer guides, design proposals, examples, translations, etc. | 18 | -------------------------------------------------------------------------------- /site/content/docs/latest/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | version: latest 3 | cascade: 4 | layout: docs 5 | --- 6 | 7 | {{% readfile file="/content/docs/latest/README.md" %}} 8 | -------------------------------------------------------------------------------- /site/content/docs/latest/background/README.md: -------------------------------------------------------------------------------- 1 | # Sealed Secrets Background 2 | 3 | Big-picture explanations of higher-level Sealed Secrets concepts. Most useful for building understanding of a particular topic. 4 | 5 | | Background | Description | 6 | | -------------------------------------------------- | ------------------------------------------------------------------------------------------------ | 7 | | [Cryptography](./cryptography.md) | Dive into the overall Sealed Secrets Cryptography. | 8 | 9 | Alternatively, if you have a specific goal, but are already familiar with Sealed Secrets, take a look at our [How-to guides](../howto/README.md). These have more in-depth detail and can be applied to a broader set of features. 10 | 11 | Take a look at our [Reference section](../reference/README.md) when you need to know design decisions, detailed developer guides, etc. 12 | 13 | Finally, our [Tutorials section](../tutorials/README.md) contains step-by-step tutorials to help outline what Sealed Secrets is capable of. 14 | -------------------------------------------------------------------------------- /site/content/docs/latest/background/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | version: latest 3 | cascade: 4 | layout: docs 5 | --- 6 | 7 | {{% readfile file="/content/docs/latest/background/README.md" %}} 8 | -------------------------------------------------------------------------------- /site/content/docs/latest/howto/README.md: -------------------------------------------------------------------------------- 1 | # How-to guides 2 | 3 | How-to guides can be thought of as directions that guide the reader through the steps to achieve a specific end. They'll help you achieve a result but may require you to understand and adapt the steps to fit your specific requirements. Here you'll find short answers to "How do I...?" types of questions. 4 | 5 | | How-to-guides | Get stuff done | 6 | | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | 7 | | [Validate Sealed Secrets](./validate-sealed-secrets.md) | Understand how to validate an existing Sealed Secret. | 8 | | 9 | 10 | Alternatively, our [Tutorials section](../tutorials/README.md) contains step-by-step tutorials to help outline what Sealed Secrets is capable of. 11 | 12 | Take a look at our [Reference section](../reference/README.md) when you need to know design decisions, detailed developer guides, etc. 13 | 14 | Finally, for a better understanding of Sealed Secrets architecture, our [Background section](../background/README.md) enables you to expand your knowledge. 15 | -------------------------------------------------------------------------------- /site/content/docs/latest/howto/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | version: latest 3 | cascade: 4 | layout: docs 5 | --- 6 | 7 | {{% readfile file="/content/docs/latest/howto/README.md" %}} 8 | -------------------------------------------------------------------------------- /site/content/docs/latest/howto/validate-sealed-secrets.md: -------------------------------------------------------------------------------- 1 | # How-to Validate existing Sealed Secrets 2 | 3 | The `validate` Sealed Secrets feature is useful for ensuring the correctness of Sealed Secrets, especially when they need to be shared or used in various Kubernetes environments. By validating Sealed Secrets, you can verify that the encryption and decryption processes are functioning as expected and that the secrets are protected properly. 4 | 5 | If you want to validate an existing sealed secret, `kubeseal` has the flag `--validate` to help you. 6 | 7 | Giving a file named `sealed-secrets.yaml` containing the following sealed secret: 8 | 9 | ```yaml 10 | apiVersion: bitnami.com/v1alpha1 11 | kind: SealedSecret 12 | metadata: 13 | name: mysecret 14 | namespace: mynamespace 15 | spec: 16 | encryptedData: 17 | foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq..... 18 | ``` 19 | 20 | You can validate if the sealed secret was properly created or not: 21 | 22 | ```console 23 | $ cat sealed-secrets.yaml | kubeseal --validate 24 | ``` 25 | 26 | In case of an invalid sealed secret, `kubeseal` will show: 27 | 28 | ```console 29 | $ cat sealed-secrets.yaml | kubeseal --validate 30 | error: unable to decrypt sealed secret 31 | ``` 32 | -------------------------------------------------------------------------------- /site/content/docs/latest/project/.placeholder: -------------------------------------------------------------------------------- 1 | This directory is expected to contain symlinks to certain files of the root project directory. This way, these files will be rendered in Hugo. 2 | 3 | mklink readme.md ..\..\..\..\..\README.md 4 | mklink code-of-conduct.md ..\..\..\..\..\CODE_OF_CONDUCT.md 5 | mklink contributing.md ..\..\..\..\..\CONTRIBUTING.md 6 | mklink maintainers.md ..\..\..\..\..\MAINTAINERS.md 7 | mklink security.md ..\..\..\..\..\SECURITY.md 8 | mklink chart-readme.md ..\..\..\..\..\chart\sealed-secrets\README.md -------------------------------------------------------------------------------- /site/content/docs/latest/project/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | version: latest 3 | cascade: 4 | layout: docs 5 | --- 6 | 7 | {{% readfile file="/content/docs/latest/project/readme.md" %}} 8 | -------------------------------------------------------------------------------- /site/content/docs/latest/project/chart-readme.md: -------------------------------------------------------------------------------- 1 | ../../../../../helm/sealed-secrets/README.md -------------------------------------------------------------------------------- /site/content/docs/latest/project/readme.md: -------------------------------------------------------------------------------- 1 | ../../../../../README.md -------------------------------------------------------------------------------- /site/content/docs/latest/reference/README.md: -------------------------------------------------------------------------------- 1 | # Sealed Secrets Reference 2 | 3 | This section contains technical reference and developer guides for Sealed Secrets. 4 | 5 | | Reference | Description | 6 | | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | 7 | | [FAQ](./faq.md) | Frequently Asked Questions. 8 | 9 | Alternatively, our [Tutorials section](../tutorials/README.md) contains step-by-step tutorials to help outline what Sealed Secrets is capable of while helping you achieve specific aims. 10 | 11 | If you have a specific goal but are already familiar with Sealed Secrets, take a look at our [How-to guides](../howto/README.md). These have more in-depth detail and can be applied to a broader set of features. 12 | 13 | Finally, for a better understanding of Sealed Secrets architecture, our [Background section](../background/README.md) enables you to expand your knowledge. 14 | -------------------------------------------------------------------------------- /site/content/docs/latest/reference/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | version: latest 3 | cascade: 4 | layout: docs 5 | --- 6 | 7 | {{% readfile file="/content/docs/latest/reference/README.md" %}} 8 | -------------------------------------------------------------------------------- /site/content/docs/latest/tutorials/README.md: -------------------------------------------------------------------------------- 1 | # Sealed Secrets tutorials 2 | 3 | This section of our documentation contains step-by-step tutorials to help outline what Sealed Secrets is capable of. 4 | 5 | We hope our tutorials make as few assumptions as possible and are broadly accessible to anyone with an interest in Sealed Secrets. They should also be a good place to start learning about Sealed Secrets, how it works and what it's capable of. 6 | 7 | | Tutorial | Description | 8 | |-----------------------------------------|------------------------------------------------------------------------------------------------------------------------------| 9 | | [Getting started](./getting-started.md) | This guide walks you through the process of deploying Sealed Secrets for your cluster and installing an example Sealed Secrets. | 10 | | [Sealed Secrets controller installation](./install-sealed-secrets.md) | Here we cover the different alternatives to install the Sealed Secrets controller, with special notes for environments with restricted permissions. | 11 | 12 | Alternatively, if you have a specific goal, but are already familiar with Sealed Secrets, take a look at our [How-to guides](../howto/README.md). These have more in-depth detail and can be applied to a broader set of features. 13 | 14 | Take a look at our [Reference section](../reference/README.md) when you need to know design decisions, detailed developer guides, etc. 15 | 16 | Finally, for a better understanding of Sealed Secrets architecture, our [Background section](../background/README.md) enables you to expand your knowledge. 17 | -------------------------------------------------------------------------------- /site/content/docs/latest/tutorials/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | version: latest 3 | cascade: 4 | layout: docs 5 | --- 6 | 7 | {{% readfile file="/content/docs/latest/tutorials/README.md" %}} 8 | -------------------------------------------------------------------------------- /site/content/posts/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Blog" 3 | id: blog 4 | url: /blog 5 | outputs: ["HTML", "RSS"] 6 | layout: listß 7 | _build: 8 | render: never 9 | list: never 10 | --- 11 | 12 | -------------------------------------------------------------------------------- /site/content/resources/_index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Resources 4 | description: Sealed Secrets Resources 5 | id: resources 6 | --- 7 | 8 |
9 |
10 |

Resources

11 |
12 |
13 |
14 |

Some useful external resources about Sealed Secrets, such as videos, workshops, and community articles.

15 |
16 |
17 |
18 | 19 |
20 | 24 |
25 |
26 |
27 | 28 |
29 | 32 |
33 |
34 |
35 | 36 |
37 | 40 |
41 |
42 |
43 | 44 |
45 |
46 |

Sealed Secrets: Protecting your passwords before they reach Kubernetes

47 |

https://docs.bitnami.com/tutorials/sealed-secrets 49 |

50 |
51 |
52 |
53 |
54 | 55 |
56 |
57 |

Tanzu Development Center: Secret Management

58 |

https://tanzu.vmware.com/developer/ 60 |

61 |
62 |
63 |
64 |
65 | 66 |
67 |
68 |

FluxCd configuration with Sealed Secrets

69 |

https://fluxcd.io/docs/guides/sealed-secrets/ 71 |

72 |
73 |
74 |
75 |
76 | -------------------------------------------------------------------------------- /site/data/docs/latest-toc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | toc: 3 | - title: About Sealed Secrets 4 | subfolderitems: 5 | - page: What is Sealed Secrets 6 | url: /project/readme 7 | - page: Sealed Secrets helm chart 8 | url: /project/chart-readme 9 | 10 | - title: Tutorials 11 | subfolderitems: 12 | - url: /tutorials/getting-started 13 | page: Get Started with Sealed Secrets 14 | - url: /tutorials/install-sealed-secrets 15 | page: Sealed Secrets controller installation 16 | - title: How-to guides 17 | subfolderitems: 18 | - url: /howto/validate-sealed-secrets 19 | page: Validate an existing Sealed Secret 20 | 21 | - title: Background 22 | subfolderitems: 23 | - url: /background/cryptography 24 | page: Cryptography details 25 | 26 | - title: Reference 27 | subfolderitems: 28 | - url: /reference/faq 29 | page: FAQ 30 | -------------------------------------------------------------------------------- /site/data/docs/toc-mapping.yml: -------------------------------------------------------------------------------- 1 | # This file can be used to explicitly map a release to a specific table-of-contents 2 | # (TOC). You'll want to use this after any revamps to information architecture, to ensure 3 | # that the navigation for older versions still work. 4 | 5 | latest: latest-toc -------------------------------------------------------------------------------- /site/resources/_gen/assets/scss/scss/site.scss_8967e03afb92eb0cac064520bf021ba2.json: -------------------------------------------------------------------------------- 1 | {"Target":"css/style.css","MediaType":"text/css","Data":{}} -------------------------------------------------------------------------------- /site/themes/template/archetypes/default.md: -------------------------------------------------------------------------------- 1 | +++ 2 | title = "{{ replace .Name "-" " " | title }}" 3 | date = {{ .Date }} 4 | +++ 5 | -------------------------------------------------------------------------------- /site/themes/template/assets/scss/_footer.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | @import 'mixins'; 3 | @import 'base'; 4 | 5 | footer { 6 | .top-links { 7 | min-height: 52px; 8 | display: flex; 9 | align-items: center; 10 | justify-content: space-between; 11 | } 12 | .left-links { 13 | padding: 0px; 14 | li { 15 | img { 16 | vertical-align: bottom; 17 | margin-right: 10px; 18 | } 19 | a { 20 | color: $darkgrey; 21 | font-weight: 300; 22 | font-size: 12px; 23 | font-family: $metropolis-light; 24 | } 25 | } 26 | .mobile { 27 | display: none; 28 | } 29 | } 30 | .right-links { 31 | p { 32 | margin: 0px; 33 | } 34 | .copywrite { 35 | font-size: 12px; 36 | padding-right: 10px; 37 | a { 38 | font-size: 12px; 39 | color: $darkgrey; 40 | font-family: $metropolis-light; 41 | } 42 | } 43 | a { 44 | vertical-align: middle; 45 | } 46 | } 47 | .bottom-links { 48 | margin: 10px 0px 30px 0px; 49 | p { 50 | display: flex; 51 | flex-wrap: wrap; 52 | justify-content: space-between; 53 | font-size: 12px; 54 | 55 | .ot-sdk-show-settings { 56 | cursor: pointer; 57 | } 58 | } 59 | a { 60 | font-size: 12px; 61 | font-family: $metropolis-light; 62 | text-decoration: underline; 63 | } 64 | img { 65 | max-width: 75px; 66 | vertical-align: middle; 67 | margin-left: 30px; 68 | } 69 | .footer-logo { 70 | height: 3em; 71 | } 72 | } 73 | @include breakpoint(small) { 74 | .footer-links { 75 | display: block; 76 | .right-links { 77 | display: none; 78 | } 79 | .left-links { 80 | float: none; 81 | margin: 10px 0px; 82 | .desktop { 83 | display: none; 84 | } 85 | .mobile { 86 | display: inline; 87 | } 88 | .copywrite { 89 | display: block; 90 | margin-top:20px; 91 | } 92 | } 93 | } 94 | .bottom-links { 95 | margin: 10px 0px 20px 0px; 96 | float: none; 97 | img { 98 | margin-left: 0px; 99 | display: block; 100 | margin-top: 10px; 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /site/themes/template/assets/scss/_header.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | @import 'mixins'; 3 | @import 'base'; 4 | 5 | header { 6 | .wrapper { 7 | padding: 10px 20px; 8 | min-height: 52px; 9 | display: flex; 10 | align-items: center; 11 | justify-content: space-between; 12 | } 13 | .desktop-links { 14 | padding-left: 0px; 15 | } 16 | a { 17 | color: $darkgrey; 18 | font-family: $metropolis-light; 19 | &.active { 20 | font-family: $metropolis-medium; 21 | } 22 | } 23 | li img { 24 | vertical-align: bottom; 25 | margin-right: 10px; 26 | } 27 | .mobile { 28 | display: none; 29 | } 30 | @include breakpoint(medium) { 31 | .desktop-links li { 32 | padding-right: 10px; 33 | } 34 | } 35 | @include breakpoint(small) { 36 | .expanded-icon { 37 | display: none; 38 | padding: 11px 3px 0px 0px; 39 | } 40 | .collapsed-icon { 41 | padding-top: 12px; 42 | } 43 | .mobile-menu-visible { 44 | .mobile { 45 | display: block; 46 | .collapsed-icon { 47 | display: none; 48 | } 49 | .expanded-icon { 50 | display: block; 51 | } 52 | } 53 | } 54 | position: relative; 55 | .desktop-links { 56 | display: none; 57 | } 58 | .mobile { 59 | display: block; 60 | } 61 | button { 62 | float: right; 63 | &:focus { 64 | outline: none; 65 | } 66 | } 67 | ul { 68 | padding-left: 0px; 69 | li { 70 | display: block; 71 | margin: 20px 0px; 72 | } 73 | } 74 | .mobile-menu { 75 | position: absolute; 76 | background-color: #fff; 77 | width: 100%; 78 | top: 70px; 79 | left: 0px; 80 | padding-bottom: 20px; 81 | display: none; 82 | z-index: 10; 83 | .header-links { 84 | margin: 0px 20px; 85 | } 86 | .social { 87 | margin: 0px 20px; 88 | padding-top: 20px; 89 | img { 90 | vertical-align: middle; 91 | padding-right: 10px; 92 | } 93 | a { 94 | font-size: 14px; 95 | padding-right: 35px; 96 | &:last-of-type { 97 | padding-right: 0px; 98 | } 99 | } 100 | } 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /site/themes/template/assets/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin breakpoint($point) { 2 | $small: 767px; // Up to 767px 3 | $medium: 1279px; // Up to 1279px 4 | $large: 1439px; // Up to 1439px 5 | $extra-large: 1800px; // Up to 1800px 6 | @if $point == extra-large { 7 | @media only screen and (min-width : $large+1) { @content; } 8 | } 9 | @else if $point == large { 10 | @media only screen and (min-width : $medium+1) and (max-width: $large) { @content; } 11 | } 12 | @else if $point == medium-large { 13 | @media only screen and (min-width: $medium+1) { @content; } 14 | } 15 | @else if $point == medium { 16 | @media only screen and (min-width: $small+1) and (max-width: $medium) { @content; } 17 | } 18 | @else if $point == small-medium { 19 | @media only screen and (max-width: $medium) { @content; } 20 | } 21 | @else if $point == small { 22 | @media only screen and (max-width: $small) { @content; } 23 | } 24 | } 25 | 26 | @mixin clearfix { 27 | *zoom: 1; 28 | &:before, &:after { 29 | display: table; 30 | content: ""; 31 | line-height: 0; 32 | } 33 | &:after { 34 | clear: both; 35 | } 36 | } -------------------------------------------------------------------------------- /site/themes/template/assets/scss/_variables.scss: -------------------------------------------------------------------------------- 1 | $white: #ffffff; 2 | $blue: #0095D3; 3 | $darkgrey: #333333; 4 | $grey: #777777; 5 | $lightgrey: #F2F2F2; 6 | $darkblue: #002538; 7 | $purple: #7F35B2; 8 | $black: #111111; 9 | $mainblue: #0091DA; 10 | $navyblue: #1D428A; -------------------------------------------------------------------------------- /site/themes/template/assets/scss/site.scss: -------------------------------------------------------------------------------- 1 | @import 'header'; 2 | @import 'footer'; 3 | @import 'base'; 4 | @import 'variables'; 5 | @import 'components'; 6 | @import 'mixins'; -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/_markup/render-image.html: -------------------------------------------------------------------------------- 1 | {{ $link := .Destination }} 2 | {{ if not (strings.HasPrefix $link "http") }} 3 | {{ if strings.HasSuffix .Page.Parent.RelPermalink "docs/" }} 4 | {{ $link = printf "%s%s" .Page.RelPermalink .Destination }} 5 | {{ else }} 6 | {{ $link = printf "%s%s" .Page.Parent.RelPermalink .Destination }} 7 | {{ end }} 8 | {{ end }} 9 |

10 | {{ .Text }} 11 |

-------------------------------------------------------------------------------- /site/themes/template/layouts/_default/_markup/render-link.html: -------------------------------------------------------------------------------- 1 | {{ $link := .Destination }} 2 | {{ $isRemote := strings.HasPrefix $link "http" }} 3 | {{- if not $isRemote -}} 4 | {{ $url := urls.Parse .Destination }} 5 | {{- if $url.Path -}} 6 | {{ $fragment := "" }} 7 | {{- with $url.Fragment }}{{ $fragment = printf "#%s" . }}{{ end -}} 8 | {{- with .Page.GetPage $url.Path }}{{ $link = printf "%s%s" .RelPermalink $fragment }}{{ end }}{{ end -}} 9 | {{- end -}} 10 | {{ .Text | safeHTML }} -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/baseof.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/docs.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |
4 |
5 |

Documentation

6 |
7 |
8 |
9 | {{ partial "docs-sidebar.html" . }} 10 |
11 | {{ .Content }} 12 |
13 | {{ partial "docs-right-bar.html" . }} 14 |
15 |
16 | {{ end }} -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/list.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 | {{ if or .Title .Content }} 4 |
5 | {{ with .Title }}

{{ . }}

{{ end }} 6 | {{ with .Content }}
{{ . }}
{{ end }} 7 |
8 | {{ end }} 9 | 10 | {{ range .Paginator.Pages }} 11 | {{ .Render "summary" }} 12 | {{ end }} 13 |
14 | {{ end }} 15 | -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/posts.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |
4 |
5 |

Blog

6 |
7 |
8 |
9 |
10 | {{ range (.Paginator 9).Pages.ByDate }} 11 | {{ partial "blog-post-card.html" . }} 12 | {{ end }} 13 |
14 | {{ partial "pagination.html" . }} 15 |
16 |
17 | {{ end }} 18 | -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/search.html: -------------------------------------------------------------------------------- 1 | {{ if .Site.Params.docs_search }} 2 |
3 | 4 | 8 | 9 |
10 | {{ end }} -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/section.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 | {{ .Content }} 4 |
5 | {{ end }} 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/single.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |
4 |
5 |
6 |

Blog

7 |
8 |
9 |
10 |
11 |

{{ .Title }}

12 |

13 | {{ .Params.author }} 14 |

15 |

{{ dateFormat "Jan 2, 2006" .Date }}

16 | {{ .Content }} 17 |
18 |

Related Content

19 |
20 | {{ $related := (where (.Site.RegularPages.Related .) "Type" "posts") | first 3 }} 21 | {{ with $related }} 22 | {{ range . }} 23 | {{ partial "blog-post-card.html" . }} 24 | {{ end }} 25 | {{ end }} 26 |
27 |
28 |
29 |
30 | {{ end }} 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/summary.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ .Title }}

3 | 4 | {{ range .Params.tags }} 5 | {{ . }} 6 | {{ end }} 7 |
8 | {{ .Summary }} 9 | {{ if .Truncated }} 10 | Read more... 11 | {{ end }} 12 |
13 |
14 | -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/tag.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |
4 |
5 |

Blog Posts by {{ .Title }}

6 |
7 |
8 |
9 |
10 | {{ range .Pages.ByDate }} 11 | {{ partial "blog-post-card.html" . }} 12 | {{ end }} 13 |
14 |
15 |
16 | {{ end }} -------------------------------------------------------------------------------- /site/themes/template/layouts/_default/versions.html: -------------------------------------------------------------------------------- 1 | {{ if .Site.Params.Use_advanced_docs }} 2 | 22 | {{ end }} -------------------------------------------------------------------------------- /site/themes/template/layouts/index.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 | {{ partial "hero.html" . }} 4 | {{ partial "homepage-grid.html" . }} 5 |
6 |
7 |
8 |

Learn More About Sealed Secrets

9 |

Learn more about Sealed Secrets and how to create secure Secrets in Kubernetes

10 |
11 |
12 |

Advanced Cryptography with Sealed Secrets

13 |

How to apply the best possible encryption to your Sealed Secrets, from using customized Certificates to post-quantum recomendations.

14 |
15 |
16 |
17 | {{ partial "use-cases.html" . }} 18 | {{ partial "contributors.html" . }} 19 |
20 | {{ end }} 21 | -------------------------------------------------------------------------------- /site/themes/template/layouts/index.redirects: -------------------------------------------------------------------------------- 1 | {{ $latest := (cond (.Site.Params.docs_versioning) .Site.Params.docs_latest "") }} 2 | /docs /docs/{{ $latest }} 301! 3 | /docs/latest /docs/{{ $latest }} 4 | /docs/latest/* /docs/{{ $latest }}/:splat -------------------------------------------------------------------------------- /site/themes/template/layouts/partials/blog-post-card.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{ .Title }} 4 |
5 |
6 |

{{ .Title }}

7 |

{{ .Params.Excerpt }}

8 |
9 |
-------------------------------------------------------------------------------- /site/themes/template/layouts/partials/contributors.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Meet the Sealed Secrets team:

4 |
5 | {{ $contributors := .Site.GetPage "/contributors" }} 6 | {{ range $contributors.Resources }} 7 |
8 |
{{ .Params.first_name }} {{ .Params.last_name }}
9 |
10 |

{{ .Params.first_name }} {{ .Params.last_name }}

11 |

{{ .Content }}

12 |
13 |
14 | {{ end }} 15 |
16 |

Contributing

17 |

18 | Sealed Secrets is released as open-source software and provides community 19 | support through our GitHub project page. If you encounter an issue or have 20 | a question, feel free to reach out on the 21 | GitHub issues page for Sealed Secrets. 25 |

26 |

27 | The Sealed Secrets project team welcomes contributions from the community — 28 | please have a look at our 29 | contributing documentation. 30 |

31 |
32 |
-------------------------------------------------------------------------------- /site/themes/template/layouts/partials/docs-right-bar.html: -------------------------------------------------------------------------------- 1 | {{ if .Site.Params.docs_right_sidebar }} 2 |
3 |
4 |
    5 | {{ if (or .IsNode .IsPage) }} 6 | {{ $issueBody := printf "**On Page:** [%s](%s)" .Title .Permalink | htmlEscape }} 7 | {{ $issueQuery := (querify "body" $issueBody) }} 8 |
  • Report Issues
  • 9 | {{ $editQuery := (querify "description" "Signed-off-by: NAME \n\n") }} 10 |
  • Edit
  • 11 | {{ end }} 12 |
13 | {{ if ne .TableOfContents "" }} 14 |

On this page:

15 | {{ .TableOfContents }} 16 | {{ end }} 17 |
18 |
19 | {{ end }} 20 | -------------------------------------------------------------------------------- /site/themes/template/layouts/partials/docs-sidebar.html: -------------------------------------------------------------------------------- 1 |
2 | {{ if .Site.Params.use_advanced_docs }} 3 | 4 | {{ $version := .CurrentSection.Params.version }} 5 | {{ .Render "versions" }} 6 | {{ .Render "search" }} 7 | {{ if $version }} 8 | {{ $tocTemplateName := index (index $.Site.Data.docs "toc-mapping") $version }} 9 | {{ if not $tocTemplateName }} 10 | {{ $tocTemplateName = "default" }} 11 | {{ end }} 12 | {{ $toc := (index $.Site.Data "docs" $tocTemplateName).toc }} 13 | {{ range $toc }} 14 |

{{ .title }}

15 |
    16 | {{ range .subfolderitems }} 17 |
  • 18 | {{ $url := (index (print "/docs/" $version .url "/")) }} 19 | {{ .page }} 20 |
  • 21 | {{ end }} 22 |
23 | {{ end }} 24 | {{ end }} 25 | {{ else }} 26 |
    27 | {{ $currentPage := . }} 28 | {{ range .Site.Menus.docs }} 29 |
  • {{ .Name }}
  • 30 | {{ end }} 31 |
32 | {{ end }} 33 |
-------------------------------------------------------------------------------- /site/themes/template/layouts/partials/footer.html: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /site/themes/template/layouts/partials/getting-started.html: -------------------------------------------------------------------------------- 1 | {{ $latest := (cond (.Site.Params.docs_versioning) .Site.Params.docs_latest "") }} 2 |
3 |
4 |
5 |

Getting started

6 |

7 | Discover how to deploy Sealed Secrets in your cluster, and start managing your Kubernetes Secrets in a secure way! 8 |

9 |
10 |
11 | Read the docs 12 |
13 | 14 |
15 |
-------------------------------------------------------------------------------- /site/themes/template/layouts/partials/header.html: -------------------------------------------------------------------------------- 1 | {{ $latest := (cond (.Site.Params.docs_versioning) .Site.Params.docs_latest "") }} 2 |
3 |
4 | Logo 5 | 12 | 16 |
17 | 24 | 29 |
30 |
31 |
-------------------------------------------------------------------------------- /site/themes/template/layouts/partials/hero.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

"Sealed Secrets" for Kubernetes

5 |

Sealed Secrets provides declarative Kubernetes Secret Management in a secure way. Since the Sealed Secrets are encrypted, they can be safely stored in a code repository. This enables an easy to implement GitOps flow that is very popular among the OSS community. 6 |

7 | 11 |
12 |
13 |
-------------------------------------------------------------------------------- /site/themes/template/layouts/partials/homepage-grid.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 |

On your command line

7 |

Sealed Secrets offers a powerful CLI tool (kubeseal) to one-way encrypt your Kubernetes Secret easily.

8 |
9 |
10 | 11 |

On your K8S cluster

12 |

The Sealed Secrets controller will decrypt any Sealed Secret into its equivalent Kubernetes Secret

13 |
14 |
15 | 16 |

On your code repository

17 |

Sealed Secrets are safe to store in your local code repository, along with the rest of your configuration.

18 |
19 |
20 |
21 |
-------------------------------------------------------------------------------- /site/themes/template/layouts/partials/pagination.html: -------------------------------------------------------------------------------- 1 | {{ $paginator := .Paginator }} 2 | {{ if gt $paginator.TotalPages 1 }} 3 | 16 | {{ end }} -------------------------------------------------------------------------------- /site/themes/template/layouts/partials/use-cases.html: -------------------------------------------------------------------------------- 1 |
2 |

Features

3 |
4 |
5 | 6 |
7 |
8 |

One-way Encryption

9 |

SealedSecrets are a "write only" device. The idea is that the SealedSecret can be decrypted only by the controller running in the target cluster and nobody else (not even the original author) is able to obtain the original Secret from the SealedSecret.

10 |

Learn more

11 |
12 |
13 |
14 |
15 |

Sealing key renewal

16 |

Sealing keys are automatically renewed every 30 days. Which means a new sealing key is created and appended to the set of active sealing keys the controller can use to unseal Sealed Secret resources.

17 |

Learn more

18 |
19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 |
27 |
28 |

Sealed Secrets Metrics

29 |

The Sealed Secrets Controller running in Kubernetes exposes Prometheus metrics. These metrics enable operators to observe how it is performing. For example how many SealedSecret unseals have been attempted and how many errors may have occured due to RBAC permissions, wrong key, corrupted data, etc.

30 |

Learn more

31 |
32 |
33 |
-------------------------------------------------------------------------------- /site/themes/template/layouts/shortcodes/readfile.html: -------------------------------------------------------------------------------- 1 | {{ .Get "file" | readFile | safeHTML }} 2 | -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Bold.eot -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Bold.woff -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Bold.woff2 -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-BoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-BoldItalic.eot -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-BoldItalic.woff -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-BoldItalic.woff2 -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Light.eot -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Light.woff -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Light.woff2 -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-LightItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-LightItalic.eot -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-LightItalic.woff -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-LightItalic.woff2 -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Medium.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Medium.eot -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Medium.woff -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Medium.woff2 -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-MediumItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-MediumItalic.eot -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-MediumItalic.woff -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-MediumItalic.woff2 -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Regular.eot -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Regular.woff -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-Regular.woff2 -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-RegularItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-RegularItalic.eot -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-RegularItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-RegularItalic.woff -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-RegularItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-RegularItalic.woff2 -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-SemiBold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-SemiBold.eot -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-SemiBold.woff -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-SemiBold.woff2 -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-SemiBoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-SemiBoldItalic.eot -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-SemiBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-SemiBoldItalic.woff -------------------------------------------------------------------------------- /site/themes/template/static/fonts/Metropolis-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/fonts/Metropolis-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /site/themes/template/static/fonts/README.md: -------------------------------------------------------------------------------- 1 | # The Metropolis Typeface 2 | 3 | The Vision 4 | --- 5 | To create a modern, geometric typeface. Open sourced, and openly available. Influenced by other popular geometric, minimalist sans-serif typefaces of the new millenium. Designed for optimal readability at small point sizes while beautiful at large point sizes. 6 | 7 | December 2017 update 8 | --- 9 | Currently working on greatly improving spacing and kerning of the base typeface. Once this is done, work on other variations (e.g. rounded or slab) can begin in earnest. 10 | 11 | The License 12 | --- 13 | Licensed under Open Font License (OFL). Available to anyone and everyone. Contributions welcome. 14 | 15 | Contact 16 | --- 17 | Contact me via chris.m.simpson@icloud.com or http://twitter.com/ChrisMSimpson for any questions, requests or improvements (or just submit a pull request). 18 | 19 | Support 20 | --- 21 | You can now support work on Metropolis via Patreon at https://www.patreon.com/metropolis. 22 | 23 | -------------------------------------------------------------------------------- /site/themes/template/static/img/administration.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /site/themes/template/static/img/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Combined Shape 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /site/themes/template/static/img/blog-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/img/blog-placeholder.png -------------------------------------------------------------------------------- /site/themes/template/static/img/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /site/themes/template/static/img/docs-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/img/docs-placeholder.png -------------------------------------------------------------------------------- /site/themes/template/static/img/down-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Shape Copy 4 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /site/themes/template/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/img/favicon.png -------------------------------------------------------------------------------- /site/themes/template/static/img/github-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | github icon 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /site/themes/template/static/img/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Clip 2 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /site/themes/template/static/img/hamburger.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /site/themes/template/static/img/left-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | arrow copy 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /site/themes/template/static/img/right-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | arrow copy 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /site/themes/template/static/img/search-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Fill 1 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /site/themes/template/static/img/simple.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /site/themes/template/static/img/slack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/img/slack.png -------------------------------------------------------------------------------- /site/themes/template/static/img/storagesecure.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /site/themes/template/static/img/team-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/img/team-placeholder.png -------------------------------------------------------------------------------- /site/themes/template/static/img/team/agarcia-oss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/img/team/agarcia-oss.png -------------------------------------------------------------------------------- /site/themes/template/static/img/team/alemorcuq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/img/team/alemorcuq.png -------------------------------------------------------------------------------- /site/themes/template/static/img/team/alvneiayu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/img/team/alvneiayu.png -------------------------------------------------------------------------------- /site/themes/template/static/img/team/josvazg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/img/team/josvazg.png -------------------------------------------------------------------------------- /site/themes/template/static/img/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/c480b8e0719711b113547f118da677350e303b35/site/themes/template/static/img/twitter.png -------------------------------------------------------------------------------- /site/themes/template/static/js/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | function mobileNavToggle() { 4 | var menu = document.getElementById('mobile-menu').parentElement; 5 | menu.classList.toggle('mobile-menu-visible'); 6 | } 7 | 8 | function docsVersionToggle() { 9 | var menu = document.getElementById('dropdown-menu'); 10 | menu.classList.toggle('dropdown-menu-visible'); 11 | } 12 | 13 | window.onclick = function(event) { 14 | var 15 | target = event.target, 16 | menu = document.getElementById('dropdown-menu') 17 | ; 18 | 19 | if(!target.classList.contains('dropdown-toggle')) { 20 | menu.classList.remove('dropdown-menu-visible'); 21 | } 22 | } -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/.travis.yml: -------------------------------------------------------------------------------- 1 | language: bash 2 | 3 | os: 4 | - linux 5 | 6 | services: 7 | - docker 8 | 9 | before_install: # update to docker-ce 10 | - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 11 | - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) edge" 12 | - sudo apt-get update 13 | - sudo apt-get -y install docker-ce 14 | 15 | script: 16 | - make tests 17 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @dbarranco @jbianquetti-nami @jjo 2 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/Makefile: -------------------------------------------------------------------------------- 1 | # Originally taken from https://github.com/bitnami-labs/kube-manifests/, 2 | # trimmed down to only run lib testing. 3 | # 4 | # Provides 'test' target. Uses docker. 5 | all: 6 | @echo make tests 7 | 8 | tests: 9 | make -C tests 10 | 11 | .PHONY: all tests 12 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/README.md: -------------------------------------------------------------------------------- 1 | # kube-libsonnet 2 | 3 | This repo has been originally populated by the `lib/` folder contents 4 | from `https://github.com/bitnami-labs/kube-manifests` as of Mar/2018, 5 | aiming to provide a library of `jsonnet` manifests for common 6 | Kubernetes objects (such as `Deployment`, `Service`, `Ingress`, etc). 7 | 8 | Accordingly, above `kube-manifests` has been changed to use this repo as 9 | a git submodule, i.e.: 10 | 11 | $ git submodule add https://github.com/bitnami-labs/kube-libsonnet 12 | $ cat .gitmodules 13 | [submodule "lib"] 14 | path = lib 15 | url = https://github.com/bitnami-labs/kube-libsonnet 16 | 17 | ## Testing 18 | 19 | Unit and e2e-ish testing at tests/, needs usable `docker-compose` 20 | at node, will run a `k3s` "dummy" container to serve Kube API, enough 21 | to for `kubecfg validate` against it: 22 | 23 | make tests 24 | 25 | If you don't want that full kube-api stack (will then use your "local" 26 | kubernetes configured environment), you can run: 27 | 28 | make -C tests test-srcs test-kube 29 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/examples/guestbook/lib: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/examples/wordpress/frontend.jsonnet: -------------------------------------------------------------------------------- 1 | local kube = import "lib/kube.libsonnet"; 2 | local be = import "backend.jsonnet"; 3 | 4 | local labels = { 5 | tier: "frontend", 6 | }; 7 | 8 | { 9 | frontend: { 10 | pvc: kube.PersistentVolumeClaim("wordpress") { 11 | metadata+: { 12 | labels+: labels, 13 | }, 14 | storage:: "10Gi", 15 | }, 16 | 17 | configmap: kube.ConfigMap("wordpress") { 18 | metadata+: { 19 | labels+: labels, 20 | }, 21 | data: { 22 | "admin_first_name": "Admin", 23 | "admin_last_name": "User", 24 | "blog_name": "Kubernetes blog!", 25 | }}, 26 | 27 | secret: kube.Secret("wordpress") { 28 | metadata+: { 29 | labels+: labels, 30 | }, 31 | data_+: { 32 | "user": "user", 33 | "password": "bitnami", 34 | "mail": "user@example.com", 35 | }}, 36 | 37 | deployment: kube.Deployment("wordpress") { 38 | metadata+: { 39 | labels+: labels, 40 | }, 41 | spec+: { 42 | template+: { 43 | spec+: { 44 | containers_+: { 45 | default: kube.Container("wordpress") { 46 | image: "bitnami/wordpress", 47 | ports_+: { http: { containerPort: 80 } }, 48 | env_+: { 49 | MARIADB_HOST: be.backend.master.service.metadata.name, 50 | WORDPRESS_DATABASE_USER: kube.SecretKeyRef(be.backend.secret, "database_user"), 51 | WORDPRESS_DATABASE_NAME: kube.SecretKeyRef(be.backend.secret, "database_name"), 52 | WORDPRESS_DATABASE_PASSWORD: kube.SecretKeyRef(be.backend.secret, "database_password"), 53 | WORDPRESS_USERNAME: kube.SecretKeyRef($.frontend.secret, "user"), 54 | WORDPRESS_EMAIL: kube.SecretKeyRef($.frontend.secret, "mail"), 55 | WORDPRESS_PASSWORD: kube.SecretKeyRef($.frontend.secret, "password"), 56 | WORDPRESS_BLOG_NAME: kube.ConfigMapRef($.frontend.configmap, "blog_name"), 57 | WORDPRESS_FIRST_NAME: kube.ConfigMapRef($.frontend.configmap, "admin_first_name"), 58 | WORDPRESS_LAST_NAME: kube.ConfigMapRef($.frontend.configmap, "admin_last_name"), 59 | }, 60 | livenessProbe: { 61 | initialDelaySeconds: 120, 62 | httpGet: { 63 | path: "/wp-login.php", 64 | port: 80 65 | }}, 66 | readinessProbe: self.livenessProbe { 67 | initialDelaySeconds: 60, 68 | }, 69 | volumeMounts_+: { 70 | "wordpress-data": { 71 | "mountPath": "/bitnami", 72 | }}}}, 73 | volumes_+: { 74 | "wordpress-data": { 75 | "persistentVolumeClaim": { 76 | "claimName": "wordpress", 77 | }}}}}}}, 78 | 79 | service: kube.Service("wordpress") { 80 | metadata+: { 81 | labels+: labels, 82 | }, 83 | target_pod: $.frontend.deployment.spec.template, 84 | }}} 85 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/examples/wordpress/lib: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/examples/wordpress/wordpress.jsonnet: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Bitnami 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // ``` 16 | // kubecfg update wordpress.jsonnet 17 | // 18 | // kubecfg delete wordpress.jsonnet 19 | // ``` 20 | 21 | local kube = import "lib/kube.libsonnet"; 22 | local fe = import "frontend.jsonnet"; 23 | local be = import "backend.jsonnet"; 24 | 25 | local findObjs(top) = std.flattenArrays([ 26 | if (std.objectHas(v, "apiVersion") && std.objectHas(v, "kind")) then [v] else findObjs(v) 27 | for v in kube.objectValues(top) 28 | ]); 29 | 30 | kube.List() { 31 | items_+: { 32 | frontend: fe, 33 | backend: be, 34 | }, 35 | items: findObjs(self.items_), 36 | } 37 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/.env: -------------------------------------------------------------------------------- 1 | # As of Sept/2019, kube-api: k3s-release 2 | # - v1.13: v0.3.x 3 | # - v1.14: v0.4.x to v0.8.x 4 | # - v1.15: v0.9.x 5 | # 6 | # You can override with e.g. 7 | # K3S_VERSION=v0.9.1 make tests 8 | K3S_VERSION=v0.3.0 9 | USERID=1000 10 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bitnami/minideb:buster 2 | LABEL org.opencontainers.image.authors="sre@bitnami.com" 3 | 4 | ARG jsonnet_version=0.14.0 5 | ARG kubectl_version=v1.13.0 6 | ARG kubecfg_version=v0.12.0 7 | 8 | RUN install_packages jq make curl ca-certificates 9 | RUN adduser --home /home/user --disabled-password --gecos User user 10 | 11 | RUN curl -sLo /tmp/jsonnet-v${jsonnet_version}.tar.gz https://github.com/google/jsonnet/releases/download/v${jsonnet_version}/jsonnet-bin-v${jsonnet_version}-linux.tar.gz 12 | RUN tar -zxf /tmp/jsonnet-v${jsonnet_version}.tar.gz -C /tmp && mv /tmp/jsonnet /tmp/jsonnetfmt /usr/local/bin 13 | 14 | RUN curl -sLo /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/${kubectl_version}/bin/linux/amd64/kubectl 15 | RUN chmod +x /usr/local/bin/kubectl 16 | 17 | RUN curl -sLo /usr/local/bin/kubecfg https://github.com/bitnami/kubecfg/releases/download/${kubecfg_version}/kubecfg-linux-amd64 18 | RUN chmod +x /usr/local/bin/kubecfg 19 | 20 | USER user 21 | WORKDIR /home/user 22 | CMD ["/bin/bash", "-l"] 23 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/Makefile: -------------------------------------------------------------------------------- 1 | SHELL=/bin/bash 2 | JSONNET_FMT=--indent 2 --string-style d --comment-style s --no-pad-arrays --pad-objects --pretty-field-names 3 | 4 | ALL_JSONNET=$(wildcard *.jsonnet) 5 | UNITTEST_JSONNET=$(wildcard unittest*.jsonnet) 6 | LIB_JSONNET=$(wildcard ../*.libsonnet) 7 | ALL_K8S_VALIDATE_JSONNET=$(wildcard *-validate.jsonnet) 8 | 9 | PHONY_GOLDEN=$(patsubst %.jsonnet,golden/%.json,$(ALL_JSONNET)) 10 | PHONY_DIFF=$(patsubst %.jsonnet,%.diff,$(ALL_JSONNET)) 11 | PHONY_PARSE=$(patsubst %.jsonnet,%.parse,$(ALL_JSONNET)) 12 | 13 | ## These need to be in-sync with docker-compose.yaml 14 | DOCKER_E2E=e2e-test 15 | TMP_RANCHER=./tmp-rancher 16 | PROJECT=kubelibsonnet 17 | 18 | tests: docker-compose-tests 19 | 20 | docker-compose-tests: 21 | install -d $(TMP_RANCHER) $(TMP_RANCHER)/etc && touch $(TMP_RANCHER)/etc/k3s.yaml 22 | USERID=$$(id -u) docker-compose -p $(PROJECT) up -d 23 | rc=$$(timeout 60s docker wait $(DOCKER_E2E)) || rc=255 ;\ 24 | test $$rc -ne 0 && docker logs k3s-api;\ 25 | docker logs $(DOCKER_E2E);\ 26 | docker-compose -p $(PROJECT) down;\ 27 | exit $$rc 28 | rm -rf ./$(TMP_RANCHER) 29 | 30 | test-srcs: unittests lint parse diff 31 | test-kube: validate 32 | 33 | # NB: unittest jsonnet files are also covered by parse and diff targets, 34 | # called out here for convenience 35 | unittests: 36 | jsonnet $(UNITTEST_JSONNET) 37 | 38 | lint: 39 | @set -e; errs=0; \ 40 | for f in $(ALL_JSONNET) $(LIB_JSONNET); do \ 41 | if ! jsonnetfmt --test $(JSONNET_FMT) -- $$f; then \ 42 | echo "FAILED lint: $$f" >&2; \ 43 | errs=$$(( $$errs + 1 )); \ 44 | fi; \ 45 | done; \ 46 | if [ $$errs -gt 0 ]; then \ 47 | echo "NOTE: if the 'lint' target fails, run:"; \ 48 | echo " $(MAKE) fix-lint lint"; \ 49 | exit 1; \ 50 | fi 51 | 52 | parse: $(PHONY_PARSE) 53 | 54 | diff: diff-help $(PHONY_DIFF) 55 | 56 | validate: 57 | timeout 10 kubectl api-versions > /dev/null \ 58 | || { echo "WARNING: no usable runtime kube context, skipping."; exit 0 ;} \ 59 | && kubectl version --short && kubecfg version && kubecfg validate --ignore-unknown=false $(ALL_K8S_VALIDATE_JSONNET) 60 | 61 | %.diff: %.jsonnet 62 | diff -u golden/$(*).json <(jsonnet $(<)) 63 | 64 | %.parse: %.jsonnet 65 | jsonnet $(<) > /dev/null 66 | 67 | golden/%.json: %.jsonnet 68 | jsonnet $(<) > $(@) 69 | 70 | diff-help: 71 | @echo "NOTE: if the 'diff' target fails, review output and run:" 72 | @echo " $(MAKE) gen-golden diff" 73 | @echo 74 | 75 | fix-lint: 76 | @set -e; \ 77 | for f in $(ALL_JSONNET) $(LIB_JSONNET); do \ 78 | echo jsonnetfmt -i $(JSONNET_FMT) -- $$f; \ 79 | jsonnetfmt -i $(JSONNET_FMT) -- $$f; \ 80 | done 81 | 82 | gen-golden: $(PHONY_GOLDEN) 83 | 84 | .PHONY: unittests lint parse validate diff %.parse %.diff golden/%.json diff-help fix-lint gen-golden 85 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | kube-api: 4 | image: rancher/k3s:${K3S_VERSION} 5 | command: server --disable-agent 6 | container_name: k3s-api 7 | volumes: 8 | - ./tmp-rancher:/.kube 9 | - ./tmp-rancher:/.rancher 10 | - ./tmp-rancher/etc:/etc/rancher/k3s 11 | expose: 12 | - 6443 13 | user: "${USERID}" 14 | environment: 15 | - USER=nobody 16 | - HOME=/ 17 | e2e-test: 18 | build: . 19 | container_name: e2e-test 20 | links: 21 | - "kube-api:kube-api" 22 | depends_on: 23 | - kube-api 24 | volumes: 25 | - ./tmp-rancher:/tmp/rancher 26 | - ..:/work 27 | working_dir: /work 28 | environment: 29 | - HOME=/ 30 | user: "${USERID}" 31 | command: 32 | - bash 33 | - -c 34 | - | 35 | echo "INFO: Starting tests: unit, lint ..." 36 | make -C tests test-srcs 37 | export KUBECONFIG=/tmp/kubeconfig 38 | echo "INFO: Waiting for kube-api to be available ..." 39 | until kubectl get nodes; do 40 | sleep 1 41 | # Found that k3s releases create k3s.yaml under diff paths, 42 | # redirecting stderr just to avoid red-herrings errors 43 | sed -e s/localhost/kube-api/ -e s/127.0.0.1/kube-api/ \ 44 | /tmp/rancher/k3s.yaml /tmp/rancher/etc/k3s.yaml \ 45 | > $$KUBECONFIG 2>/dev/null 46 | done 47 | echo "INFO: Starting tests: validate ..." 48 | set -x 49 | make -C tests test-kube 50 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/golden/test-sealedsecrets-datalines.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "items": [ 4 | { 5 | "apiVersion": "bitnami.com/v1alpha1", 6 | "kind": "SealedSecret", 7 | "metadata": { 8 | "annotations": { }, 9 | "labels": { 10 | "name": "foo" 11 | }, 12 | "name": "foo" 13 | }, 14 | "spec": { 15 | "data": "AgCz+HLrnNCZoDCOcCbMgKp//+Tfz5ecNcVGZOnLT/M/RP5E7u6ifHtm3GfG8qJKcRK9v6ZBYOIeDqenlSNMpRmigXH0p2ThMfmBcPIYfLvqOcwfwssfOS4jp02qsAjSfaAXuL2Mze15OnXImiPHsoi9BIrJnyhRObBeRMnJ4xMUAFPih1CfqY3nl7FQhH6+4t3Wh52JY3VmDWYYGH5Kc5JyS40PodCUEgId1kJKtChUPQ0JsTgj6W8ymyJ0bC8jyzrZHD0gLo26T+7mNiJyUEU9qj7p8YhZj3v6VcEv4DKQVVvkGk94svTAdnSQrh5cNOaZrp6eTJqIs+PcrelTVitoZzZsnIc+ze6aPjGhft752xa9CDmuCkQ9XkWfWpGcGrEv1jmIPkJYIjPIKgP6CS5eU+eBZNIkNpIof2jiYdqqP59BhoBwVkC/Rm1GfgOdLxO55sicTwSmRA+/pkE6hopK327uwxWmtGZ5/kUuW6nZ4shTNTsr1n1skZJvw6UfwkAgIYuDctHqw+y7eSdDM2gggLM72TgBEf5111LnIj2rroQu5bR6XVVpMy6QFhE9LLAC3kcs/BqPh5A7qq/ffZrFhWpSIS7voavtdqn6XhdJ8TsJ7Wbkhjxf1S/l/YqS6B1ZlJFlrdcNA6BHqzyjncmrD030YfwNqYUl2Itxok7S6DaImzBkxV5Uqd18EiuVcbVL3Ic1I3B4pviBAo0eG5nn4/uZCjuBKu6muLtR5GFMblbqV23MiB8Q3jtODvVw6SbFfNQx836RsJAFSmE+axSGvZPq4zDXGUYekOHZ+ov6Gd2Czv99Cf67r3ogJIzDR1uVRZH78bYrjEAkRGpKETUfLFfRyRZzWW/K5cKEAoDttzHI5grlgm44k5RQeaoargmyVjuEgjEZ2yZnl5Z7BX3YSazcLfK2t/wwGNHMMgedf3SeGETIx552CehRw7+A1+0q4iKQ9z13dPpjAYNzmLd1bGY4ORQeEf4Duk6NTXXHfpyRSq/CNK5BPhKnTn1OEnUQ+ttD/ZjNkx2OMFsX7zfMfk0RRRnKlWpanYOtTinx5WbpIYOKZ4Labb7+CnuHMgTZoNTXZe2DnNFqWIgm47U=" 16 | } 17 | } 18 | ], 19 | "kind": "List" 20 | } 21 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/golden/test-sealedsecrets.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "items": [ 4 | { 5 | "apiVersion": "bitnami.com/v1alpha1", 6 | "kind": "SealedSecret", 7 | "metadata": { 8 | "annotations": { }, 9 | "labels": { 10 | "name": "foo" 11 | }, 12 | "name": "foo" 13 | }, 14 | "spec": { 15 | "data": "dGVzdAo=" 16 | } 17 | } 18 | ], 19 | "kind": "List" 20 | } 21 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/golden/unittests.json: -------------------------------------------------------------------------------- 1 | true 2 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/test-sealedsecrets-datalines.jsonnet: -------------------------------------------------------------------------------- 1 | local kube = import "../kube.libsonnet"; 2 | local stack = { 3 | sealedsecret: kube.SealedSecret("foo") { 4 | spec+: { 5 | datalines_: importstr "test-sealedsecrets-datalines.txt", 6 | }, 7 | }, 8 | }; 9 | 10 | kube.List() { 11 | items_+: stack, 12 | } 13 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/test-sealedsecrets-datalines.txt: -------------------------------------------------------------------------------- 1 | AgCz+HLrnNCZoDCOcCbMgKp//+Tfz5ecNcVGZOnLT/M/RP5E7u6ifHtm3GfG8qJKcRK9v6ZBYOIeDqenlSNMpRmigXH0p2ThMfmBcPIYfLvqOcwfwssfOS4jp02qsAjSfaAXuL2Mze15OnXImiPHsoi9BIrJnyhRObBeRMnJ4xMUAFPih1CfqY3nl7FQhH6+4t3Wh52JY3VmDWYYGH5Kc5JyS40PodCUEgId1kJKtChUPQ0JsTgj6W8ymyJ0bC8jyzrZHD0gLo26T+7mNiJyUEU9qj7p8YhZj3v6VcEv4DKQVVvkGk94svTAdnSQrh5cNOaZrp6eTJqIs+PcrelTVitoZzZsnIc+ze6aPjGhft752xa9CDmuCkQ9XkWfWpGcGrEv1jmIPkJYIjPIKgP6CS5eU+eBZNIkNpIof2jiYdqqP59BhoBwVkC/Rm1GfgOdLxO55sicTwSmRA+/pkE6hopK327uwxWmtGZ5/kUuW6nZ4shTNTsr1n1skZJvw6UfwkAgIYuDctHqw+y7eSdDM2gggLM72TgBEf5111LnIj2rroQu5bR6XVVpMy6QFhE9LLAC3kcs/BqPh5A7qq/ffZrFhWpSIS7voavtdqn6XhdJ8TsJ7Wbkhjxf1S/l/YqS6B1ZlJFlrdcNA6BHqzyjncmrD030YfwNqYUl2Itxok7S6DaImzBkxV5Uqd18EiuVcbVL3Ic1I3B4pviBAo0eG5nn4/uZCjuBKu6muLtR5GFMblbqV23MiB8Q3jtODvVw6SbFfNQx836RsJAFSmE+axSGvZPq4zDXGUYekOHZ+ov6Gd2Czv99Cf67r3ogJIzDR1uVRZH78bYrjEAkRGpKETUfLFfRyRZzWW/K5cKEAoDttzHI5grlgm44k5RQeaoargmyVjuEgjEZ2yZnl5Z7BX3YSazcLfK2t/wwGNHMMgedf3SeGETIx552CehRw7+A1+0q4iKQ9z13dPpjAYNzmLd1bGY4ORQeEf4Duk6NTXXHfpyRSq/CNK5BPhKnTn1OEnUQ+ttD/ZjNkx2OMFsX7zfMfk0RRRnKlWpanYOtTinx5WbpIYOKZ4Labb7+CnuHMgTZoNTXZe2DnNFqWIgm47U= 2 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/test-sealedsecrets.jsonnet: -------------------------------------------------------------------------------- 1 | local kube = import "../kube.libsonnet"; 2 | local stack = { 3 | sealedsecret: kube.SealedSecret("foo") { 4 | spec+: { 5 | data: "dGVzdAo=", 6 | }, 7 | }, 8 | }; 9 | 10 | kube.List() { 11 | items_+: stack, 12 | } 13 | -------------------------------------------------------------------------------- /vendor_jsonnet/kube-libsonnet/tests/unittests.jsonnet: -------------------------------------------------------------------------------- 1 | local kube = import "../kube.libsonnet"; 2 | 3 | local an_obj = kube._Object("v1", "Gentle", "foo"); 4 | local a_pod = kube.Pod("foo") { 5 | metadata+: { labels+: { foo: "bar", bar: "qxx" } }, 6 | spec+: { 7 | containers_+: { 8 | foo: kube.Container("foo") { 9 | image: "nginx", 10 | ports_: { 11 | http: { containerPort: 8080 }, 12 | https: { containerPort: 8443 }, 13 | udp: { containerPort: 5353, protocol: "UDP" }, 14 | }, 15 | }, 16 | }, 17 | }, 18 | }; 19 | local a_deploy = kube.Deployment("foo") { 20 | spec+: { template+: { metadata+: a_pod.metadata, spec+: a_pod.spec } }, 21 | }; 22 | // Basic unittesting for methods that are not exercised by the other e2e-ish tests 23 | std.assertEqual(kube.objectValues({ a: 1, b: 2 }), [1, 2]) && 24 | std.assertEqual(kube.objectItems({ a: 1, b: 2 }), [["a", 1], ["b", 2]]) && 25 | std.assertEqual(kube.hyphenate("foo_bar_baz"), ("foo-bar-baz")) && 26 | std.assertEqual(kube.mapToNamedList({ foo: { a: "b" } }), [{ name: "foo", a: "b" }]) && 27 | std.assertEqual(kube.filterMapByFields({ a: 1, b: 2, c: 3 }, ["a", "c", "d"]), { a: 1, c: 3 }) && 28 | std.assertEqual(kube.parseOctal("755"), 493) && 29 | std.assertEqual(kube.siToNum("42G"), 42 * 1e9) && 30 | std.assertEqual(kube.siToNum("42Gi"), 42 * std.pow(2, 30)) && 31 | std.assertEqual(kube.toUpper("ForTy 2"), "FORTY 2") && 32 | std.assertEqual(kube.toLower("ForTy 2"), "forty 2") && 33 | std.assertEqual(an_obj, { 34 | apiVersion: "v1", 35 | kind: "Gentle", 36 | metadata: { name: "foo", labels: { name: "foo" }, annotations: {} }, 37 | }) && 38 | std.assertEqual( 39 | [kube.podRef(a_deploy).spec.ports("TCP"), kube.podRef(a_deploy).spec.ports("UDP")], 40 | [[8080, 8443], [5353]] 41 | ) && 42 | std.assertEqual( 43 | // latest kubecfg produces stable output from maps hashes, so below shouldn't be flaky 44 | kube.podsPorts([a_deploy]), 45 | [ 46 | { port: 8080, protocol: "TCP" }, 47 | { port: 8443, protocol: "TCP" }, 48 | { port: 5353, protocol: "UDP" }, 49 | ] 50 | ) && 51 | std.assertEqual( 52 | kube.podLabelsSelector(a_deploy), 53 | { podSelector: { matchLabels: { name: "foo", foo: "bar", bar: "qxx" } } } 54 | ) 55 | -------------------------------------------------------------------------------- /versions.env: -------------------------------------------------------------------------------- 1 | GO_VERSION=1.24.1 2 | GO_VERSION_LIST="[\"$GO_VERSION\"]" 3 | --------------------------------------------------------------------------------