├── .github └── workflows │ ├── ci.yaml │ ├── release-gatekeeper-function.yaml │ ├── release-ts-create-kpt-functions.yaml │ ├── release-ts-demo-functions.yaml │ ├── release-ts-kpt-functions.yaml │ └── release-typegen.yaml ├── .gitignore ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── LICENSE ├── LICENSE-documentation ├── MAINTAINERS ├── Makefile ├── README.md ├── docs ├── .nojekyll ├── api │ ├── .nojekyll │ ├── assets │ │ ├── highlight.css │ │ ├── icons.css │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── main.js │ │ ├── search.js │ │ ├── style.css │ │ ├── widgets.png │ │ └── widgets@2x.png │ ├── classes │ │ ├── Configs.html │ │ ├── FunctionConfigError.html │ │ ├── ResourceList.html │ │ └── TestRunner.html │ ├── index.html │ └── interfaces │ │ ├── FieldInfo.html │ │ ├── JsonArray.html │ │ ├── JsonMap.html │ │ ├── KptFunc.html │ │ ├── KubernetesObject.html │ │ └── Result.html └── index.html ├── example-configs ├── README.md ├── audit │ ├── namespace.yaml │ └── rolebinding_viewers.yaml ├── clusterrole_namespace-reader.yaml ├── clusterrole_pod-creator.yaml ├── clusterrolebinding_namespace-readers.yaml ├── customresourcedefinition_fulfillmentcenters.foo-corp.com.yaml ├── gatekeeper.yaml ├── payments-team.yaml ├── podsecuritypolicy_psp.yaml ├── shipping-dev │ ├── namespace.yaml │ ├── resourcequota_config-management-resource-quota.yaml │ ├── rolebinding_job-creators.yaml │ ├── rolebinding_pod-creators.yaml │ └── rolebinding_viewers.yaml ├── shipping-prod │ ├── fulfillmentcenter_production.yaml │ ├── namespace.yaml │ ├── rolebinding_pod-creators.yaml │ ├── rolebinding_sre-admin.yaml │ └── rolebinding_viewers.yaml └── shipping-staging │ ├── fulfillmentcenter_staging.yaml │ ├── namespace.yaml │ ├── rolebinding_pod-creators.yaml │ └── rolebinding_viewers.yaml ├── go ├── Makefile ├── api │ ├── go.mod │ ├── go.sum │ ├── kptfile │ │ └── v1 │ │ │ └── types.go │ └── util │ │ ├── kptfileutil.go │ │ └── kptfileutil_test.go ├── fn │ ├── .golangci.yml │ ├── const.go │ ├── context.go │ ├── doc.go │ ├── errors.go │ ├── examples │ │ ├── const.go │ │ ├── data │ │ │ └── setlabels-resourcelist.yaml │ │ ├── example_asmain_runner_test.go │ │ ├── example_builtin_function_test.go │ │ ├── example_filter_GVK_test.go │ │ ├── example_generator_test.go │ │ ├── example_kubeobject_test.go │ │ ├── example_logger_injector_test.go │ │ ├── example_mutate_comments_test.go │ │ ├── example_read_field_test.go │ │ ├── example_read_functionConfig_test.go │ │ ├── example_select_exclude_test.go │ │ ├── example_set_field_test.go │ │ ├── example_validator_test.go │ │ ├── go.mod │ │ └── go.sum │ ├── functionrunner.go │ ├── go.mod │ ├── go.sum │ ├── internal │ │ ├── document.go │ │ ├── map.go │ │ ├── maphelpers.go │ │ ├── namespace.go │ │ ├── scalar.go │ │ ├── slice.go │ │ ├── test │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ ├── maphelper_test.go │ │ │ └── variant_test.go │ │ └── variant.go │ ├── io.go │ ├── log.go │ ├── object.go │ ├── object_test.go │ ├── origin.go │ ├── origin_test.go │ ├── resourcelist.go │ ├── resourcelist_test.go │ ├── result.go │ ├── run.go │ ├── runnerProcessor.go │ ├── runnerprocessor_test.go │ └── testhelpers │ │ └── golden.go ├── get-started │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── golden_test.go │ ├── main.go │ └── testdata │ │ └── test1 │ │ ├── _expected.yaml │ │ ├── _fnconfig.yaml │ │ └── resources.yaml ├── hack │ └── update-license.sh └── kfn │ ├── commands │ ├── build.go │ ├── build_test.go │ ├── embed │ │ └── Dockerfile │ └── init.go │ ├── go.mod │ ├── go.sum │ └── main.go ├── hack └── ci-validate-go.sh ├── openapi └── kptfile.yaml ├── starlark └── get-started │ ├── data │ └── resources.yaml │ └── starlark-fn-config.yaml └── ts ├── CONTRIBUTING.md ├── create-kpt-functions ├── .prettierrc.json ├── LICENSE ├── README.md ├── jasmine.json ├── package-lock.json ├── package.json ├── src │ ├── cli.ts │ ├── cmd │ │ ├── docker_build.ts │ │ ├── docker_create.ts │ │ ├── docker_push.ts │ │ ├── function_create.ts │ │ ├── package_create.ts │ │ └── type_create.ts │ ├── paths.ts │ └── utils │ │ ├── format.ts │ │ ├── log.ts │ │ ├── templates.ts │ │ ├── validator.ts │ │ └── validator_test.ts ├── templates │ ├── Dockerfile.mustache │ ├── dockerignore │ ├── func.mustache │ ├── jasmine.json │ ├── package.json.mustache │ ├── run.mustache │ ├── test.mustache │ └── tsconfig.json ├── tsconfig.json └── tslint.json ├── demo-functions ├── .dockerignore ├── .prettierrc.json ├── build │ ├── annotate_config.Dockerfile │ ├── expand_team_cr.Dockerfile │ ├── label_namespace.Dockerfile │ ├── mutate_psp.Dockerfile │ ├── no_op.Dockerfile │ ├── read_yaml.Dockerfile │ ├── suggest_psp.Dockerfile │ ├── validate_rolebinding.Dockerfile │ └── write_yaml.Dockerfile ├── jasmine.json ├── package-lock.json ├── package.json ├── src │ ├── annotate_config.ts │ ├── annotate_config_run.ts │ ├── annotate_config_test.ts │ ├── expand_team_cr.ts │ ├── expand_team_cr_run.ts │ ├── expand_team_test.ts │ ├── gen │ │ ├── dev.cft.anthos.v1alpha1.ts │ │ ├── io.k8s.api.admissionregistration.v1beta1.ts │ │ ├── io.k8s.api.apps.v1.ts │ │ ├── io.k8s.api.apps.v1beta1.ts │ │ ├── io.k8s.api.apps.v1beta2.ts │ │ ├── io.k8s.api.authentication.v1.ts │ │ ├── io.k8s.api.authentication.v1beta1.ts │ │ ├── io.k8s.api.authorization.v1.ts │ │ ├── io.k8s.api.authorization.v1beta1.ts │ │ ├── io.k8s.api.autoscaling.v1.ts │ │ ├── io.k8s.api.autoscaling.v2beta1.ts │ │ ├── io.k8s.api.autoscaling.v2beta2.ts │ │ ├── io.k8s.api.batch.v1.ts │ │ ├── io.k8s.api.batch.v1beta1.ts │ │ ├── io.k8s.api.certificates.v1beta1.ts │ │ ├── io.k8s.api.coordination.v1.ts │ │ ├── io.k8s.api.coordination.v1beta1.ts │ │ ├── io.k8s.api.core.v1.ts │ │ ├── io.k8s.api.events.v1beta1.ts │ │ ├── io.k8s.api.extensions.v1beta1.ts │ │ ├── io.k8s.api.networking.v1.ts │ │ ├── io.k8s.api.networking.v1beta1.ts │ │ ├── io.k8s.api.node.v1beta1.ts │ │ ├── io.k8s.api.policy.v1beta1.ts │ │ ├── io.k8s.api.rbac.v1.ts │ │ ├── io.k8s.api.rbac.v1beta1.ts │ │ ├── io.k8s.api.scheduling.v1.ts │ │ ├── io.k8s.api.scheduling.v1beta1.ts │ │ ├── io.k8s.api.storage.v1.ts │ │ ├── io.k8s.api.storage.v1beta1.ts │ │ ├── io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.ts │ │ ├── io.k8s.apimachinery.pkg.api.resource.ts │ │ ├── io.k8s.apimachinery.pkg.apis.meta.v1.ts │ │ ├── io.k8s.apimachinery.pkg.runtime.ts │ │ ├── io.k8s.apimachinery.pkg.util.intstr.ts │ │ ├── io.k8s.apimachinery.pkg.version.ts │ │ ├── io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.ts │ │ └── io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.ts │ ├── label_namespace.ts │ ├── label_namespace_run.ts │ ├── label_namespace_test.ts │ ├── mutate_psp.ts │ ├── mutate_psp_run.ts │ ├── mutate_psp_test.ts │ ├── no_op.ts │ ├── no_op_run.ts │ ├── no_op_test.ts │ ├── read_yaml.ts │ ├── read_yaml_run.ts │ ├── read_yaml_test.ts │ ├── suggest_psp.ts │ ├── suggest_psp_run.ts │ ├── suggest_psp_test.ts │ ├── validate_rolebinding.ts │ ├── validate_rolebinding_run.ts │ ├── validate_rolebinding_test.ts │ ├── write_yaml.ts │ ├── write_yaml_run.ts │ └── write_yaml_test.ts ├── test-data │ ├── intermediate │ │ └── foo.yaml │ ├── sink │ │ └── foo-yaml │ │ │ └── foo-corp-1.0.0 │ │ │ ├── audit │ │ │ └── rolebinding_viewers.yaml │ │ │ ├── clusterrole_namespace-reader.yaml │ │ │ ├── clusterrole_pod-creator.yaml │ │ │ ├── clusterrolebinding_namespace-readers.yaml │ │ │ ├── customresourcedefinition_fulfillmentcenters.foo-corp.com.yaml │ │ │ ├── podsecuritypolicy_psp.yaml │ │ │ ├── shipping-dev │ │ │ ├── resourcequota_config-management-resource-quota.yaml │ │ │ ├── rolebinding_job-creators.yaml │ │ │ ├── rolebinding_pod-creators.yaml │ │ │ └── rolebinding_viewers.yaml │ │ │ ├── shipping-prod │ │ │ ├── fulfillmentcenter_production.yaml │ │ │ ├── rolebinding_pod-creators.yaml │ │ │ ├── rolebinding_sre-admin.yaml │ │ │ └── rolebinding_viewers.yaml │ │ │ └── shipping-staging │ │ │ ├── fulfillmentcenter_staging.yaml │ │ │ ├── rolebinding_pod-creators.yaml │ │ │ └── rolebinding_viewers.yaml │ └── source │ │ ├── empty │ │ └── .empty │ │ ├── foo-yaml │ │ └── foo-corp-1.0.0 │ │ │ ├── audit │ │ │ └── rolebinding_viewers.yaml │ │ │ ├── clusterrole_namespace-reader.yaml │ │ │ ├── clusterrole_pod-creator.yaml │ │ │ ├── clusterrolebinding_namespace-readers.yaml │ │ │ ├── customresourcedefinition_fulfillmentcenters.foo-corp.com.yaml │ │ │ ├── podsecuritypolicy_psp.yaml │ │ │ ├── shipping-dev │ │ │ ├── resourcequota_config-management-resource-quota.yaml │ │ │ ├── rolebinding_job-creators.yaml │ │ │ ├── rolebinding_pod-creators.yaml │ │ │ └── rolebinding_viewers.yaml │ │ │ ├── shipping-prod │ │ │ ├── fulfillmentcenter_production.yaml │ │ │ ├── rolebinding_pod-creators.yaml │ │ │ ├── rolebinding_sre-admin.yaml │ │ │ └── rolebinding_viewers.yaml │ │ │ └── shipping-staging │ │ │ ├── fulfillmentcenter_staging.yaml │ │ │ ├── rolebinding_pod-creators.yaml │ │ │ └── rolebinding_viewers.yaml │ │ └── invalid │ │ └── invalid.yaml ├── tsconfig.json └── tslint.json ├── hello-world ├── .dockerignore ├── build │ └── label_namespace.Dockerfile ├── jasmine.json ├── package-lock.json ├── package.json ├── src │ ├── gen │ │ ├── io.k8s.api.admissionregistration.v1beta1.ts │ │ ├── io.k8s.api.apps.v1.ts │ │ ├── io.k8s.api.apps.v1beta1.ts │ │ ├── io.k8s.api.apps.v1beta2.ts │ │ ├── io.k8s.api.authentication.v1.ts │ │ ├── io.k8s.api.authentication.v1beta1.ts │ │ ├── io.k8s.api.authorization.v1.ts │ │ ├── io.k8s.api.authorization.v1beta1.ts │ │ ├── io.k8s.api.autoscaling.v1.ts │ │ ├── io.k8s.api.autoscaling.v2beta1.ts │ │ ├── io.k8s.api.autoscaling.v2beta2.ts │ │ ├── io.k8s.api.batch.v1.ts │ │ ├── io.k8s.api.batch.v1beta1.ts │ │ ├── io.k8s.api.certificates.v1beta1.ts │ │ ├── io.k8s.api.coordination.v1.ts │ │ ├── io.k8s.api.coordination.v1beta1.ts │ │ ├── io.k8s.api.core.v1.ts │ │ ├── io.k8s.api.events.v1beta1.ts │ │ ├── io.k8s.api.extensions.v1beta1.ts │ │ ├── io.k8s.api.networking.v1.ts │ │ ├── io.k8s.api.networking.v1beta1.ts │ │ ├── io.k8s.api.node.v1beta1.ts │ │ ├── io.k8s.api.policy.v1beta1.ts │ │ ├── io.k8s.api.rbac.v1.ts │ │ ├── io.k8s.api.rbac.v1beta1.ts │ │ ├── io.k8s.api.scheduling.v1.ts │ │ ├── io.k8s.api.scheduling.v1beta1.ts │ │ ├── io.k8s.api.storage.v1.ts │ │ ├── io.k8s.api.storage.v1beta1.ts │ │ ├── io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.ts │ │ ├── io.k8s.apimachinery.pkg.api.resource.ts │ │ ├── io.k8s.apimachinery.pkg.apis.meta.v1.ts │ │ ├── io.k8s.apimachinery.pkg.runtime.ts │ │ ├── io.k8s.apimachinery.pkg.util.intstr.ts │ │ ├── io.k8s.apimachinery.pkg.version.ts │ │ ├── io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.ts │ │ └── io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.ts │ ├── label_namespace.ts │ ├── label_namespace_run.ts │ └── label_namespace_test.ts └── tsconfig.json ├── init-package ├── .dockerignore ├── build │ └── my_func.Dockerfile ├── jasmine.json ├── package-lock.json ├── package.json ├── src │ ├── gen │ │ ├── io.k8s.api.admissionregistration.v1.ts │ │ ├── io.k8s.api.admissionregistration.v1beta1.ts │ │ ├── io.k8s.api.apiserverinternal.v1alpha1.ts │ │ ├── io.k8s.api.apps.v1.ts │ │ ├── io.k8s.api.authentication.v1.ts │ │ ├── io.k8s.api.authentication.v1beta1.ts │ │ ├── io.k8s.api.authorization.v1.ts │ │ ├── io.k8s.api.authorization.v1beta1.ts │ │ ├── io.k8s.api.autoscaling.v1.ts │ │ ├── io.k8s.api.autoscaling.v2beta1.ts │ │ ├── io.k8s.api.autoscaling.v2beta2.ts │ │ ├── io.k8s.api.batch.v1.ts │ │ ├── io.k8s.api.batch.v1beta1.ts │ │ ├── io.k8s.api.certificates.v1.ts │ │ ├── io.k8s.api.certificates.v1beta1.ts │ │ ├── io.k8s.api.coordination.v1.ts │ │ ├── io.k8s.api.coordination.v1beta1.ts │ │ ├── io.k8s.api.core.v1.ts │ │ ├── io.k8s.api.discovery.v1.ts │ │ ├── io.k8s.api.discovery.v1beta1.ts │ │ ├── io.k8s.api.events.v1.ts │ │ ├── io.k8s.api.events.v1beta1.ts │ │ ├── io.k8s.api.extensions.v1beta1.ts │ │ ├── io.k8s.api.flowcontrol.v1beta1.ts │ │ ├── io.k8s.api.networking.v1.ts │ │ ├── io.k8s.api.networking.v1beta1.ts │ │ ├── io.k8s.api.node.v1.ts │ │ ├── io.k8s.api.node.v1alpha1.ts │ │ ├── io.k8s.api.node.v1beta1.ts │ │ ├── io.k8s.api.policy.v1.ts │ │ ├── io.k8s.api.policy.v1beta1.ts │ │ ├── io.k8s.api.rbac.v1.ts │ │ ├── io.k8s.api.rbac.v1alpha1.ts │ │ ├── io.k8s.api.rbac.v1beta1.ts │ │ ├── io.k8s.api.scheduling.v1.ts │ │ ├── io.k8s.api.scheduling.v1alpha1.ts │ │ ├── io.k8s.api.scheduling.v1beta1.ts │ │ ├── io.k8s.api.storage.v1.ts │ │ ├── io.k8s.api.storage.v1alpha1.ts │ │ ├── io.k8s.api.storage.v1beta1.ts │ │ ├── io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.ts │ │ ├── io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.ts │ │ ├── io.k8s.apimachinery.pkg.api.resource.ts │ │ ├── io.k8s.apimachinery.pkg.apis.meta.v1.ts │ │ ├── io.k8s.apimachinery.pkg.runtime.ts │ │ ├── io.k8s.apimachinery.pkg.util.intstr.ts │ │ ├── io.k8s.apimachinery.pkg.version.ts │ │ ├── io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.ts │ │ └── io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.ts │ ├── my_func.ts │ ├── my_func_run.ts │ └── my_func_test.ts └── tsconfig.json ├── kpt-functions ├── .prettierrc.json ├── @types │ └── rw │ │ ├── index.d.ts │ │ └── package.json ├── LICENSE ├── README.md ├── index.ts ├── jasmine.json ├── package-lock.json ├── package.json ├── src │ ├── errors.ts │ ├── gen │ │ ├── io.k8s.api.core.v1.ts │ │ ├── io.k8s.apimachinery.pkg.api.resource.ts │ │ ├── io.k8s.apimachinery.pkg.apis.meta.v1.ts │ │ ├── io.k8s.apimachinery.pkg.runtime.ts │ │ ├── io.k8s.apimachinery.pkg.util.intstr.ts │ │ └── io.k8s.apimachinery.pkg.version.ts │ ├── io.ts │ ├── io_test.ts │ ├── metadata.ts │ ├── metadata_test.ts │ ├── result.ts │ ├── result_test.ts │ ├── run.ts │ ├── run_test.ts │ ├── testing.ts │ ├── testing_test.ts │ ├── types.ts │ └── types_test.ts ├── tsconfig.json ├── tslint.json └── typedoc.json ├── scripts ├── demo │ ├── demo-magic │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── README.md │ │ ├── demo-magic.sh │ │ ├── license.txt │ │ └── samples │ │ │ └── demo-template.sh │ └── run.sh ├── gen-api-docs.sh ├── init-package.sh ├── mirrorImages.sh ├── publish-bins.sh ├── publish-npm.sh ├── version-kpt-functions-sdk-deps.sh └── version-kpt-functions-sdk.sh └── typegen ├── Makefile ├── cmd └── main.go ├── go.mod ├── go.sum └── swagger ├── alias.go ├── arrays.go ├── definition.go ├── empty.go ├── fields.go ├── imports.go ├── language ├── languages.go ├── ts.go └── ts_test.go ├── map.go ├── objects.go ├── objects_test.go ├── parser.go ├── parser_test.go ├── primitives.go ├── properties.go ├── properties_test.go ├── refs.go ├── swagger.go ├── swagger_test.go └── testdata ├── swagger-v1.13.0.json ├── swagger-v1.14.3.json └── two-arrays-swagger.json /.github/workflows/release-gatekeeper-function.yaml: -------------------------------------------------------------------------------- 1 | name: release-gatekeeper-function 2 | 3 | on: 4 | push: 5 | tags: 6 | - release-gatekeeper-function-* 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | env: 12 | GOPATH: /home/runner/work/kpt-functions-sdk/go 13 | GO111MODULE: on 14 | steps: 15 | - name: Set up gcloud 16 | uses: GoogleCloudPlatform/github-actions/setup-gcloud@master 17 | with: 18 | version: '275.0.0' 19 | service_account_email: ${{ secrets.GCP_SA_EMAIL }} 20 | service_account_key: ${{ secrets.GCP_SA_KEY }} 21 | - run: gcloud auth configure-docker 22 | - name: Set up Go 1.13 23 | uses: actions/setup-go@v1 24 | with: 25 | go-version: 1.13 26 | id: go 27 | - name: Check out code into GOPATH 28 | uses: actions/checkout@v1 29 | with: 30 | path: go/src/github.com/${{ github.repository }} 31 | - name: Build, Test, Lint 32 | run: | 33 | cd go 34 | make all 35 | - name: Push to container registry 36 | run: | 37 | cd go 38 | TAG=latest ./scripts/publish-functions.sh 39 | -------------------------------------------------------------------------------- /.github/workflows/release-ts-create-kpt-functions.yaml: -------------------------------------------------------------------------------- 1 | name: release-ts-create-kpt-functions 2 | 3 | on: 4 | push: 5 | tags: 6 | - release-ts-create-kpt-functions-* 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v1 13 | - name: Use Node.js 14.x 14 | uses: actions/setup-node@v1 15 | with: 16 | node-version: 14.x 17 | registry-url: 'https://wombat-dressing-room.appspot.com' 18 | - name: Install, test 19 | run: | 20 | cd ts/create-kpt-functions 21 | npm ci 22 | npm test 23 | - name: Publish 24 | run: | 25 | cd ts/create-kpt-functions 26 | ../scripts/publish-npm.sh $GITHUB_REF 27 | env: 28 | NODE_AUTH_TOKEN: ${{ secrets.WOMBAT_CREATE_KPT_FUNCTIONS }} 29 | -------------------------------------------------------------------------------- /.github/workflows/release-ts-demo-functions.yaml: -------------------------------------------------------------------------------- 1 | name: release-ts-demo-functions 2 | 3 | on: 4 | push: 5 | tags: 6 | - release-ts-demo-functions-* 7 | 8 | jobs: 9 | e2e-ci: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | node-version: [14.x] 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Set up gcloud 17 | uses: GoogleCloudPlatform/github-actions/setup-gcloud@master 18 | with: 19 | version: "275.0.0" 20 | service_account_email: ${{ secrets.GCP_SA_EMAIL }} 21 | service_account_key: ${{ secrets.GCP_SA_KEY }} 22 | - run: gcloud auth configure-docker 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v1 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | - name: Install NPM packages 28 | run: | 29 | cd ts/demo-functions 30 | npm ci 31 | npm test 32 | - name: Build docker images 33 | run: | 34 | cd ts/demo-functions 35 | npm run kpt:docker-build -- --tag=latest 36 | - name: Run all e2e tests 37 | run: | 38 | sudo curl https://storage.googleapis.com/kpt-dev/latest/linux_amd64/kpt -o /usr/local/bin/kpt 39 | sudo chmod +x /usr/local/bin/kpt 40 | TAG=latest tests/e2e.sh 41 | - name: Push docker images 42 | run: | 43 | cd ts/demo-functions 44 | npm run kpt:docker-push -- --tag=latest 45 | -------------------------------------------------------------------------------- /.github/workflows/release-ts-kpt-functions.yaml: -------------------------------------------------------------------------------- 1 | name: release-ts-kpt-functions 2 | 3 | on: 4 | push: 5 | tags: 6 | - release-ts-kpt-functions-* 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v1 13 | - name: Use Node.js 14.x 14 | uses: actions/setup-node@v1 15 | with: 16 | node-version: 14.x 17 | registry-url: 'https://wombat-dressing-room.appspot.com' 18 | - name: Install, test 19 | run: | 20 | cd ts/kpt-functions 21 | npm ci 22 | npm test 23 | - name: Publish 24 | run: | 25 | cd ts/kpt-functions 26 | ../scripts/publish-npm.sh $GITHUB_REF 27 | env: 28 | NODE_AUTH_TOKEN: ${{ secrets.WOMBAT_KPT_FUNCTIONS }} 29 | -------------------------------------------------------------------------------- /.github/workflows/release-typegen.yaml: -------------------------------------------------------------------------------- 1 | name: release-typegen 2 | 3 | on: 4 | push: 5 | tags: 6 | - release-typegen-* 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Set up Go 1.19 13 | uses: actions/setup-go@v3 14 | with: 15 | go-version: 1.19 16 | - name: Check out code 17 | uses: actions/checkout@v3 18 | - name: Build, Test, Lint 19 | run: | 20 | cd ts/typegen 21 | make package-typegen 22 | - id: 'auth' 23 | uses: 'google-github-actions/auth@v1' 24 | with: 25 | credentials_json: '${{ secrets.GCP_SA_KEY }}' 26 | - name: 'Set up Cloud SDK' 27 | uses: 'google-github-actions/setup-gcloud@v1' 28 | - name: Upload binaries 29 | run: ./ts/scripts/publish-bins.sh $GITHUB_REF 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | dist 3 | node_modules 4 | *.iml 5 | .npmrc 6 | ts/go/.out 7 | ts/create-kpt-functions/bin 8 | .DS_Store 9 | *.swo 10 | *.swp 11 | 12 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Default 2 | * @liamfallon @kispaljr 3 | -------------------------------------------------------------------------------- /MAINTAINERS: -------------------------------------------------------------------------------- 1 | Maintainers of this repo are listed in https://github.com/kptdev/governance/blob/main/maintainers.yaml -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: go 2 | go: ## Run all e2e tests 3 | cd go && $(MAKE) all 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KRM Functions SDK 2 | 3 | An opinionated Typescript SDK for implementing KRM functions. 4 | 5 | ## Documentation 6 | 7 | [Documentation](https://kpt.dev/book/05-developing-functions/03-developing-in-Typescript) 8 | 9 | ## Issues 10 | 11 | Please [Open Issues](https://github.com/kptdev/kpt/issues) for this repo at [kptdev/kpt](https://github.com/kptdev/kpt/). 12 | 13 | ## Pull requests 14 | 15 | Open pull requests [here](https://github.com/kptdev/krm-functions-sdk/pulls). 16 | 17 | ## Discussions 18 | 19 | Discussions are [here](https://github.com/kptdev/kpt/discussions). 20 | 21 | ## License 22 | 23 | Code is under the [Apache License 2.0](LICENSE), documentation is [CC BY 4.0](LICENSE-documentation). 24 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /docs/api/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/api/assets/highlight.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --light-hl-0: #0000FF; 3 | --dark-hl-0: #569CD6; 4 | --light-hl-1: #000000; 5 | --dark-hl-1: #D4D4D4; 6 | --light-hl-2: #0070C1; 7 | --dark-hl-2: #4FC1FF; 8 | --light-hl-3: #001080; 9 | --dark-hl-3: #9CDCFE; 10 | --light-hl-4: #795E26; 11 | --dark-hl-4: #DCDCAA; 12 | --light-hl-5: #A31515; 13 | --dark-hl-5: #CE9178; 14 | --light-hl-6: #AF00DB; 15 | --dark-hl-6: #C586C0; 16 | --light-code-background: #FFFFFF; 17 | --dark-code-background: #1E1E1E; 18 | } 19 | 20 | @media (prefers-color-scheme: light) { :root { 21 | --hl-0: var(--light-hl-0); 22 | --hl-1: var(--light-hl-1); 23 | --hl-2: var(--light-hl-2); 24 | --hl-3: var(--light-hl-3); 25 | --hl-4: var(--light-hl-4); 26 | --hl-5: var(--light-hl-5); 27 | --hl-6: var(--light-hl-6); 28 | --code-background: var(--light-code-background); 29 | } } 30 | 31 | @media (prefers-color-scheme: dark) { :root { 32 | --hl-0: var(--dark-hl-0); 33 | --hl-1: var(--dark-hl-1); 34 | --hl-2: var(--dark-hl-2); 35 | --hl-3: var(--dark-hl-3); 36 | --hl-4: var(--dark-hl-4); 37 | --hl-5: var(--dark-hl-5); 38 | --hl-6: var(--dark-hl-6); 39 | --code-background: var(--dark-code-background); 40 | } } 41 | 42 | body.light { 43 | --hl-0: var(--light-hl-0); 44 | --hl-1: var(--light-hl-1); 45 | --hl-2: var(--light-hl-2); 46 | --hl-3: var(--light-hl-3); 47 | --hl-4: var(--light-hl-4); 48 | --hl-5: var(--light-hl-5); 49 | --hl-6: var(--light-hl-6); 50 | --code-background: var(--light-code-background); 51 | } 52 | 53 | body.dark { 54 | --hl-0: var(--dark-hl-0); 55 | --hl-1: var(--dark-hl-1); 56 | --hl-2: var(--dark-hl-2); 57 | --hl-3: var(--dark-hl-3); 58 | --hl-4: var(--dark-hl-4); 59 | --hl-5: var(--dark-hl-5); 60 | --hl-6: var(--dark-hl-6); 61 | --code-background: var(--dark-code-background); 62 | } 63 | 64 | .hl-0 { color: var(--hl-0); } 65 | .hl-1 { color: var(--hl-1); } 66 | .hl-2 { color: var(--hl-2); } 67 | .hl-3 { color: var(--hl-3); } 68 | .hl-4 { color: var(--hl-4); } 69 | .hl-5 { color: var(--hl-5); } 70 | .hl-6 { color: var(--hl-6); } 71 | pre, code { background: var(--code-background); } 72 | -------------------------------------------------------------------------------- /docs/api/assets/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/krm-functions-sdk/1126697ce2d12abd3e85d651ab178c9c5ca30847/docs/api/assets/icons.png -------------------------------------------------------------------------------- /docs/api/assets/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/krm-functions-sdk/1126697ce2d12abd3e85d651ab178c9c5ca30847/docs/api/assets/icons@2x.png -------------------------------------------------------------------------------- /docs/api/assets/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/krm-functions-sdk/1126697ce2d12abd3e85d651ab178c9c5ca30847/docs/api/assets/widgets.png -------------------------------------------------------------------------------- /docs/api/assets/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/krm-functions-sdk/1126697ce2d12abd3e85d651ab178c9c5ca30847/docs/api/assets/widgets@2x.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Redirecting to https://googlecontainertools.github.io/kpt 4 | 5 | -------------------------------------------------------------------------------- /example-configs/README.md: -------------------------------------------------------------------------------- 1 | Example k8s configs. 2 | -------------------------------------------------------------------------------- /example-configs/audit/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: audit 5 | -------------------------------------------------------------------------------- /example-configs/audit/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: viewers 5 | namespace: audit 6 | roleRef: 7 | name: view 8 | kind: ClusterRole 9 | apiGroup: rbac.authorization.k8s.io 10 | subjects: 11 | - name: 'system:serviceaccounts:audit' 12 | kind: Group 13 | apiGroup: rbac.authorization.k8s.io 14 | -------------------------------------------------------------------------------- /example-configs/clusterrole_namespace-reader.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: namespace-reader 5 | rules: 6 | - resources: 7 | - namespaces 8 | apiGroups: 9 | - '' 10 | verbs: 11 | - get 12 | - watch 13 | - list 14 | -------------------------------------------------------------------------------- /example-configs/clusterrole_pod-creator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: pod-creator 5 | rules: 6 | - resources: 7 | - pods 8 | apiGroups: 9 | - '' 10 | verbs: 11 | - '*' 12 | -------------------------------------------------------------------------------- /example-configs/clusterrolebinding_namespace-readers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: namespace-readers 5 | roleRef: 6 | name: namespace-reader 7 | kind: ClusterRole 8 | apiGroup: rbac.authorization.k8s.io 9 | subjects: 10 | - name: cheryl@foo-corp.com 11 | kind: User 12 | apiGroup: rbac.authorization.k8s.io 13 | -------------------------------------------------------------------------------- /example-configs/customresourcedefinition_fulfillmentcenters.foo-corp.com.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1beta1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: fulfillmentcenters.foo-corp.com 5 | spec: 6 | group: foo-corp.com 7 | names: 8 | kind: FulfillmentCenter 9 | plural: fulfillmentcenters 10 | singular: fulfillmentcenter 11 | scope: Namespaced 12 | validation: 13 | openAPIV3Schema: 14 | properties: 15 | spec: 16 | type: object 17 | properties: 18 | address: 19 | type: string 20 | required: 21 | - address 22 | versions: 23 | - name: v1 24 | served: true 25 | storage: false 26 | - name: v2 27 | served: true 28 | storage: true 29 | -------------------------------------------------------------------------------- /example-configs/gatekeeper.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sBannedConfigMapKeysV1 3 | metadata: 4 | name: no-secrets-in-configmap 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: 9 | - '' 10 | kinds: 11 | - ConfigMap 12 | parameters: 13 | keys: 14 | - private_key 15 | --- 16 | apiVersion: templates.gatekeeper.sh/v1beta1 17 | kind: ConstraintTemplate 18 | metadata: 19 | name: k8sbannedconfigmapkeysv1 20 | spec: 21 | crd: 22 | spec: 23 | names: 24 | kind: K8sBannedConfigMapKeysV1 25 | validation: 26 | openAPIV3Schema: 27 | properties: 28 | keys: 29 | type: array 30 | items: 31 | type: string 32 | targets: 33 | - rego: |- 34 | package ban_keys 35 | 36 | violation[{"msg": sprintf("%v", [val])}] { 37 | keys = {key | input.review.object.data[key]} 38 | banned = {key | input.parameters.keys[_] = key} 39 | overlap = keys & banned 40 | count(overlap) > 0 41 | val := sprintf("The following banned keys are being used in the config map: %v", [overlap]) 42 | } 43 | target: admission.k8s.gatekeeper.sh 44 | --- 45 | apiVersion: v1 46 | kind: ConfigMap 47 | metadata: 48 | name: super-secret 49 | namespace: default 50 | data: 51 | private_key: secrets here 52 | -------------------------------------------------------------------------------- /example-configs/payments-team.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: anthos.cft.dev/v1alpha1 2 | kind: Team 3 | metadata: 4 | name: payments 5 | spec: 6 | roles: 7 | - role: sre 8 | users: 9 | - jane@clearify.co 10 | - groups: 11 | - payments-developers@clearify.co 12 | role: developer 13 | users: 14 | - basic@clearify.co 15 | -------------------------------------------------------------------------------- /example-configs/podsecuritypolicy_psp.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1beta1 2 | kind: PodSecurityPolicy 3 | metadata: 4 | name: psp 5 | spec: 6 | volumes: 7 | - '*' 8 | fsGroup: 9 | rule: RunAsAny 10 | runAsUser: 11 | rule: RunAsAny 12 | seLinux: 13 | rule: RunAsAny 14 | supplementalGroups: 15 | rule: RunAsAny 16 | -------------------------------------------------------------------------------- /example-configs/shipping-dev/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: shipping-dev 5 | -------------------------------------------------------------------------------- /example-configs/shipping-dev/resourcequota_config-management-resource-quota.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ResourceQuota 3 | metadata: 4 | name: config-management-resource-quota 5 | namespace: shipping-dev 6 | labels: 7 | nomos-namespace-type: workload 8 | spec: 9 | hard: 10 | cpu: 100m 11 | memory: 100Mi 12 | pods: '1' 13 | -------------------------------------------------------------------------------- /example-configs/shipping-dev/rolebinding_job-creators.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: job-creator 5 | namespace: shipping-dev 6 | rules: 7 | - resources: 8 | - jobs 9 | apiGroups: 10 | - batch/v1 11 | verbs: 12 | - '*' 13 | --- 14 | apiVersion: rbac.authorization.k8s.io/v1 15 | kind: RoleBinding 16 | metadata: 17 | name: job-creators 18 | namespace: shipping-dev 19 | roleRef: 20 | name: job-creator 21 | kind: Role 22 | apiGroup: rbac.authorization.k8s.io 23 | subjects: 24 | - name: sam@foo-corp.com 25 | kind: User 26 | apiGroup: rbac.authorization.k8s.io 27 | -------------------------------------------------------------------------------- /example-configs/shipping-dev/rolebinding_pod-creators.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: pod-creators 5 | namespace: shipping-dev 6 | roleRef: 7 | name: pod-creator 8 | kind: ClusterRole 9 | apiGroup: rbac.authorization.k8s.io 10 | subjects: 11 | - name: bob@foo-corp.com 12 | kind: User 13 | apiGroup: rbac.authorization.k8s.io 14 | -------------------------------------------------------------------------------- /example-configs/shipping-dev/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: viewers 5 | namespace: shipping-dev 6 | roleRef: 7 | name: view 8 | kind: ClusterRole 9 | apiGroup: rbac.authorization.k8s.io 10 | subjects: 11 | - name: 'system:serviceaccounts:audit' 12 | kind: Group 13 | apiGroup: rbac.authorization.k8s.io 14 | -------------------------------------------------------------------------------- /example-configs/shipping-prod/fulfillmentcenter_production.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: foo-corp.com/v1 2 | kind: FulfillmentCenter 3 | metadata: 4 | name: production 5 | namespace: shipping-prod 6 | spec: 7 | address: 100 Industry St. 8 | -------------------------------------------------------------------------------- /example-configs/shipping-prod/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: shipping-prod 5 | -------------------------------------------------------------------------------- /example-configs/shipping-prod/rolebinding_pod-creators.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: pod-creators 5 | namespace: shipping-prod 6 | roleRef: 7 | name: pod-creator 8 | kind: ClusterRole 9 | apiGroup: rbac.authorization.k8s.io 10 | subjects: 11 | - name: bob@foo-corp.com 12 | kind: User 13 | apiGroup: rbac.authorization.k8s.io 14 | -------------------------------------------------------------------------------- /example-configs/shipping-prod/rolebinding_sre-admin.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: sre-admin 5 | namespace: shipping-prod 6 | roleRef: 7 | name: admin 8 | kind: ClusterRole 9 | apiGroup: rbac.authorization.k8s.io 10 | subjects: 11 | - name: sre@foo-corp.com 12 | kind: Group 13 | apiGroup: rbac.authorization.k8s.io 14 | -------------------------------------------------------------------------------- /example-configs/shipping-prod/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: viewers 5 | namespace: shipping-prod 6 | roleRef: 7 | name: view 8 | kind: ClusterRole 9 | apiGroup: rbac.authorization.k8s.io 10 | subjects: 11 | - name: 'system:serviceaccounts:audit' 12 | kind: Group 13 | apiGroup: rbac.authorization.k8s.io 14 | -------------------------------------------------------------------------------- /example-configs/shipping-staging/fulfillmentcenter_staging.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: foo-corp.com/v1 2 | kind: FulfillmentCenter 3 | metadata: 4 | name: staging 5 | namespace: shipping-staging 6 | spec: 7 | address: 100 Main St. 8 | -------------------------------------------------------------------------------- /example-configs/shipping-staging/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: shipping-staging 5 | -------------------------------------------------------------------------------- /example-configs/shipping-staging/rolebinding_pod-creators.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: pod-creators 5 | namespace: shipping-staging 6 | roleRef: 7 | name: pod-creator 8 | kind: ClusterRole 9 | apiGroup: rbac.authorization.k8s.io 10 | subjects: 11 | - name: bob@foo-corp.com 12 | kind: User 13 | apiGroup: rbac.authorization.k8s.io 14 | -------------------------------------------------------------------------------- /example-configs/shipping-staging/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: viewers 5 | namespace: shipping-staging 6 | roleRef: 7 | name: view 8 | kind: ClusterRole 9 | apiGroup: rbac.authorization.k8s.io 10 | subjects: 11 | - name: 'system:serviceaccounts:audit' 12 | kind: Group 13 | apiGroup: rbac.authorization.k8s.io 14 | -------------------------------------------------------------------------------- /go/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | all: fix vet fmt test lint license 3 | 4 | GOPATH := $(shell go env GOPATH) 5 | GOBIN := $(shell go env GOPATH)/bin 6 | OUT_DIR := .out 7 | MODULES = $(shell find . -name 'go.mod' -print) 8 | 9 | .PHONY: api 10 | api: 11 | (which swagger || go install github.com/go-swagger/go-swagger/cmd/swagger@v0.27.0) 12 | $(GOPATH)/bin/swagger generate spec -m -w api/kptfile/v1 -o ../openapi/kptfile.yaml 13 | 14 | .PHONY: fix 15 | fix: $(MODULES) 16 | @for f in $(^D); do (cd $$f; echo "Fixing $$f"; go fix ./...) || exit 1; done 17 | 18 | .PHONY: fmt 19 | fmt: $(MODULES) 20 | @for f in $(^D); do (cd $$f; echo "Formatting $$f"; go fmt ./...); done 21 | 22 | .PHONY: lint 23 | lint: $(MODULES) 24 | @for f in $(^D); do \ 25 | (cd $$f; echo "Checking golangci-lint $$f"; \ 26 | (which $(GOPATH)/bin/golangci-lint || go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.50.1); \ 27 | $(GOPATH)/bin/golangci-lint run ./...); \ 28 | done 29 | 30 | .PHONY: test 31 | test: $(MODULES) 32 | @for f in $(^D); do (cd $$f; echo "Testing $$f"; go test ./...) || exit 1; done 33 | 34 | .PHONY: vet 35 | vet: $(MODULES) 36 | @#for f in $(^D); do (cd $$f; echo "Checking $$f"; go run honnef.co/go/tools/cmd/staticcheck@latest ./...); done 37 | @for f in $(^D); do (cd $$f; echo "Vetting $$f"; go vet ./...); done 38 | 39 | license: 40 | GOBIN=$(GOBIN) hack/update-license.sh 41 | -------------------------------------------------------------------------------- /go/api/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/GoogleContainerTools/kpt-functions-sdk/go/api 2 | 3 | go 1.18 4 | 5 | require gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b 6 | 7 | require ( 8 | github.com/kr/pretty v0.2.0 // indirect 9 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /go/api/go.sum: -------------------------------------------------------------------------------- 1 | github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= 2 | github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 3 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 4 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 5 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 6 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 7 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= 8 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 9 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 10 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 11 | -------------------------------------------------------------------------------- /go/api/util/kptfileutil.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 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 | package util 16 | 17 | import ( 18 | "fmt" 19 | "strings" 20 | 21 | kptfilev1 "github.com/GoogleContainerTools/kpt-functions-sdk/go/api/kptfile/v1" 22 | "gopkg.in/yaml.v3" 23 | ) 24 | 25 | // DecodeKptfile decodes a KptFile from a yaml string. 26 | func DecodeKptfile(kf string) (*kptfilev1.KptFile, error) { 27 | kptfile := &kptfilev1.KptFile{} 28 | f := strings.NewReader(kf) 29 | d := yaml.NewDecoder(f) 30 | d.KnownFields(true) 31 | if err := d.Decode(&kptfile); err != nil { 32 | return &kptfilev1.KptFile{}, fmt.Errorf("invalid 'v1' Kptfile: %w", err) 33 | } 34 | return kptfile, nil 35 | } 36 | -------------------------------------------------------------------------------- /go/fn/.golangci.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 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 | run: 16 | deadline: 5m 17 | 18 | linters: 19 | disable-all: true 20 | enable: 21 | - bodyclose 22 | - deadcode 23 | - depguard 24 | - dogsled 25 | - dupl 26 | - errcheck 27 | # - funlen 28 | - gochecknoinits 29 | - goconst 30 | # - gocritic 31 | # - gocyclo 32 | - gofmt 33 | - goimports 34 | - golint 35 | - gosec 36 | - gosimple 37 | - govet 38 | - ineffassign 39 | - interfacer 40 | - lll 41 | - misspell 42 | - nakedret 43 | - scopelint 44 | - staticcheck 45 | - structcheck 46 | # stylecheck demands that acronyms not be treated as words 47 | # in camelCase, so JsonOp become JSONOp, etc. Yuck. 48 | # - stylecheck 49 | - typecheck 50 | - unconvert 51 | - unparam 52 | - unused 53 | - varcheck 54 | - whitespace 55 | 56 | linters-settings: 57 | dupl: 58 | threshold: 400 59 | lll: 60 | line-length: 170 61 | gocyclo: 62 | min-complexity: 15 63 | golint: 64 | min-confidence: 0.85 65 | -------------------------------------------------------------------------------- /go/fn/context.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package fn 16 | 17 | import ( 18 | "context" 19 | ) 20 | 21 | var _ context.Context = &Context{} 22 | 23 | // TODO: Have Context implement `context.Context`. 24 | type Context struct { 25 | context.Context 26 | } 27 | -------------------------------------------------------------------------------- /go/fn/examples/const.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package example 16 | 17 | import "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 18 | 19 | const ( 20 | apps = "apps" 21 | v1 = "v1" 22 | ) 23 | 24 | func hasDesiredGVK(obj *fn.KubeObject) bool { 25 | return obj.IsGVK(apps, v1, "Deployment") || obj.IsGVK(apps, v1, "StatefulSet") || 26 | obj.IsGVK(apps, v1, "DaemonSet") || obj.IsGVK(apps, v1, "ReplicaSet") 27 | } 28 | -------------------------------------------------------------------------------- /go/fn/examples/data/setlabels-resourcelist.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 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 | apiVersion: config.kubernetes.io/v1 16 | kind: ResourceList 17 | items: 18 | - apiVersion: v1 19 | kind: Service 20 | metadata: 21 | name: example 22 | functionConfig: 23 | apiVersion: fn.kpt.dev/v1alpha1 24 | kind: SetLabels 25 | metadata: 26 | name: setlabel-fn-config 27 | -------------------------------------------------------------------------------- /go/fn/examples/example_builtin_function_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package example_test 16 | 17 | import ( 18 | "bytes" 19 | "fmt" 20 | "strings" 21 | 22 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 23 | ) 24 | 25 | // This example removes all resources as a builtin function by using fn.Execute. 26 | 27 | type RemoveAllResources struct{} 28 | 29 | func (*RemoveAllResources) Process(rl *fn.ResourceList) (bool, error) { 30 | rl.Items = nil 31 | return true, nil 32 | } 33 | 34 | func Example_builtinFunction() { 35 | reader := strings.NewReader(` 36 | apiVersion: config.kubernetes.io/v1 37 | kind: ResourceList 38 | items: 39 | - kind: Deployment 40 | metadata: 41 | name: my-deploy 42 | - kind: Service 43 | metadata: 44 | name: my-service 45 | functionConfig: 46 | apiVersion: fn.kpt.dev/v1alpha1 47 | kind: RemoveAllResources 48 | metadata: 49 | name: fn-config`) 50 | 51 | var writer bytes.Buffer 52 | err := fn.Execute(&RemoveAllResources{}, reader, &writer) 53 | if err != nil { 54 | fmt.Println(err.Error()) 55 | } 56 | fmt.Println(writer.String()) 57 | 58 | // Output: 59 | // apiVersion: config.kubernetes.io/v1 60 | // kind: ResourceList 61 | // items: [] 62 | // functionConfig: 63 | // apiVersion: fn.kpt.dev/v1alpha1 64 | // kind: RemoveAllResources 65 | // metadata: 66 | // name: fn-config 67 | // 68 | } 69 | -------------------------------------------------------------------------------- /go/fn/examples/example_filter_GVK_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package example_test 16 | 17 | import ( 18 | "os" 19 | 20 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 21 | ) 22 | 23 | // This example implements a function that updates the replicas field for all deployments. 24 | 25 | func Example_filterGVK() { 26 | if err := fn.AsMain(fn.ResourceListProcessorFunc(updateReplicas)); err != nil { 27 | os.Exit(1) 28 | } 29 | } 30 | 31 | // updateReplicas sets a field in resources selecting by GVK. 32 | func updateReplicas(rl *fn.ResourceList) (bool, error) { 33 | if rl.FunctionConfig == nil { 34 | return false, fn.ErrMissingFnConfig{} 35 | } 36 | var replicas int 37 | found, err := rl.FunctionConfig.NestedResource(&replicas, "replicas") 38 | if err != nil || !found { 39 | return found, err 40 | } 41 | for i := range rl.Items.Where(fn.IsGVK("apps", "v1", "Deployment")) { 42 | if err := rl.Items[i].SetNestedField(replicas, "spec", "replicas"); err != nil { 43 | return false, err 44 | } 45 | } 46 | return true, nil 47 | } 48 | -------------------------------------------------------------------------------- /go/fn/examples/example_mutate_comments_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package example 16 | 17 | import ( 18 | "os" 19 | "strings" 20 | 21 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 22 | ) 23 | 24 | // In this example, we mutate line comments for field metadata.name. 25 | // Some function may want to store some information in the comments (e.g. 26 | // apply-setters function: https://catalog.kpt.dev/apply-setters/v0.2/) 27 | 28 | func Example_dMutateComments() { 29 | if err := fn.AsMain(fn.ResourceListProcessorFunc(mutateComments)); err != nil { 30 | os.Exit(1) 31 | } 32 | } 33 | 34 | func mutateComments(rl *fn.ResourceList) (bool, error) { 35 | for i := range rl.Items { 36 | lineComment, found, err := rl.Items[i].LineComment("metadata", "name") 37 | if err != nil { 38 | return false, err 39 | } 40 | if !found { 41 | return true, nil 42 | } 43 | 44 | if strings.TrimSpace(lineComment) == "" { 45 | lineComment = "bar-system" 46 | } else { 47 | lineComment = strings.Replace(lineComment, "foo", "bar", -1) 48 | } 49 | if err = rl.Items[i].SetLineComment(lineComment, "metadata", "name"); err != nil { 50 | return false, err 51 | } 52 | } 53 | return true, nil 54 | } 55 | -------------------------------------------------------------------------------- /go/fn/examples/example_read_field_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package example 16 | 17 | import ( 18 | "os" 19 | 20 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 21 | ) 22 | 23 | // In this example, we read a field from the input object and print it to the log. 24 | 25 | func Example_aReadField() { 26 | if err := fn.AsMain(fn.ResourceListProcessorFunc(readField)); err != nil { 27 | os.Exit(1) 28 | } 29 | } 30 | 31 | func readField(rl *fn.ResourceList) (bool, error) { 32 | for _, obj := range rl.Items.Where(fn.IsGVK("apps", "v1", "Deployment")) { 33 | // Style 1: like using unstrucuted.Unstructured, get/set the value from field paths* 34 | replicas, _, _ := obj.NestedInt64("spec", "replicas") 35 | fn.Logf("replicas is %v\n", replicas) 36 | paused, _, _ := obj.NestedBool("spec", "paused") 37 | fn.Logf("paused is %v\n", paused) 38 | // Update strategy from Recreate to RollingUpdate. 39 | if strategy, _, _ := obj.NestedString("spec", "strategy", "type"); strategy == "Recreate" { 40 | if err := obj.SetNestedString("RollingUpdate", "spec", "strategy", "type"); err != nil { 41 | return false, err 42 | } 43 | } 44 | 45 | // Style 2: operate each resource layer via `GetMap` 46 | spec := obj.GetMap("spec") 47 | replicas = spec.GetInt("replicas") 48 | fn.Logf("replicas is %v\n", replicas) 49 | nodeSelector := spec.GetMap("template").GetMap("spec").GetMap("nodeSelector") 50 | if nodeSelector.GetString("disktype") != "ssd" { 51 | if err := nodeSelector.SetNestedString("ssd", "disktype"); err != nil { 52 | return false, err 53 | } 54 | } 55 | } 56 | return true, nil 57 | } 58 | -------------------------------------------------------------------------------- /go/fn/examples/example_read_functionConfig_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package example 16 | 17 | import ( 18 | "os" 19 | 20 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 21 | yaml2 "sigs.k8s.io/kustomize/kyaml/yaml" 22 | ) 23 | 24 | // In this example, we convert the functionConfig as strong typed object and then 25 | // read a field from the functionConfig object. 26 | 27 | func Example_bReadFunctionConfig() { 28 | if err := fn.AsMain(fn.ResourceListProcessorFunc(readFunctionConfig)); err != nil { 29 | os.Exit(1) 30 | } 31 | } 32 | 33 | func readFunctionConfig(rl *fn.ResourceList) (bool, error) { 34 | var sr SetReplicas 35 | if err := rl.FunctionConfig.As(&sr); err != nil { 36 | return false, err 37 | } 38 | fn.Logf("desired replicas is %v\n", sr.DesiredReplicas) 39 | return true, nil 40 | } 41 | 42 | // SetReplicas is the type definition of the functionConfig 43 | type SetReplicas struct { 44 | yaml2.ResourceIdentifier `json:",inline" yaml:",inline"` 45 | DesiredReplicas int `json:"desiredReplicas,omitempty" yaml:"desiredReplicas,omitempty"` 46 | } 47 | -------------------------------------------------------------------------------- /go/fn/examples/example_select_exclude_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package example 16 | 17 | import ( 18 | "os" 19 | 20 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 21 | ) 22 | 23 | // This example implements a function that selectively includes or excludes some resources. 24 | 25 | func Example_selectExclude() { 26 | if err := fn.AsMain(fn.ResourceListProcessorFunc(selectResources)); err != nil { 27 | os.Exit(1) 28 | } 29 | } 30 | 31 | // selectResources keeps all resources with the GVK apps/v1 Deployment that do 32 | // NOT have the label foo=bar, and removes the rest. 33 | func selectResources(rl *fn.ResourceList) (bool, error) { 34 | rl.Items = rl.Items.Where(fn.IsGVK("apps", "v1", "Deployment")). 35 | WhereNot(fn.HasLabels(map[string]string{"foo": "bar"})) 36 | return true, nil 37 | } 38 | -------------------------------------------------------------------------------- /go/fn/examples/example_set_field_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package example 16 | 17 | import ( 18 | "os" 19 | 20 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 21 | ) 22 | 23 | // In this example, we read a field from the input object and print it to the log. 24 | 25 | func Example_cSetField() { 26 | if err := fn.AsMain(fn.ResourceListProcessorFunc(setField)); err != nil { 27 | os.Exit(1) 28 | } 29 | } 30 | 31 | func setField(rl *fn.ResourceList) (bool, error) { 32 | for _, obj := range rl.Items { 33 | if obj.GetAPIVersion() == "apps/v1" && obj.GetKind() == "Deployment" { 34 | replicas := 10 35 | if err := obj.SetNestedField(&replicas, "spec", "replicas"); err != nil { 36 | return false, err 37 | } 38 | } 39 | } 40 | return true, nil 41 | } 42 | -------------------------------------------------------------------------------- /go/fn/examples/example_validator_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package example 16 | 17 | import ( 18 | "os" 19 | 20 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 21 | ) 22 | 23 | // This example implements a function that validate resources to ensure 24 | // spec.template.spec.securityContext.runAsNonRoot is set in workload APIs. 25 | func Example_validator() { 26 | if err := fn.AsMain(fn.ResourceListProcessorFunc(validator)); err != nil { 27 | os.Exit(1) 28 | } 29 | } 30 | 31 | func validator(rl *fn.ResourceList) (bool, error) { 32 | var results fn.Results 33 | for _, obj := range rl.Items.Where(hasDesiredGVK) { 34 | var runAsNonRoot bool 35 | if _, err := obj.NestedResource(&runAsNonRoot, "spec", "template", "spec", "securityContext", "runAsNonRoot"); err != nil { 36 | return false, err 37 | } 38 | if !runAsNonRoot { 39 | results = append(results, fn.ConfigObjectResult("`spec.template.spec.securityContext.runAsNonRoot` must be set to true", obj, fn.Error)) 40 | } 41 | } 42 | return true, results 43 | } 44 | -------------------------------------------------------------------------------- /go/fn/functionrunner.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package fn 16 | 17 | type Runner interface { 18 | // Run provides the entrypoint to allow you make changes to input `resourcelist.Items` 19 | // Args: 20 | // items: The KRM resources in the form of a slice of KubeObject. 21 | // Note: You can only modify the existing items but not add or delete items. 22 | // We intentionally design the method this way to make the Runner be used as a Transformer or Validator, but not a Generator. 23 | // results: You can use `ErrorE` `Errorf` `Infof` `Warningf` `WarningE` to add user message to `Results`. 24 | // Returns: 25 | // return a boolean to tell whether the execution should be considered as PASS or FAIL. CLI like kpt will 26 | // display the corresponding message. 27 | Run(context *Context, functionConfig *KubeObject, items KubeObjects, results *Results) bool 28 | } 29 | -------------------------------------------------------------------------------- /go/fn/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/GoogleContainerTools/kpt-functions-sdk/go/fn 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/GoogleContainerTools/kpt-functions-sdk/go/api v0.0.0-20220720212527-133180134b93 7 | github.com/go-errors/errors v1.0.1 8 | github.com/google/go-cmp v0.5.9 9 | github.com/stretchr/testify v1.8.0 10 | k8s.io/apimachinery v0.24.0 11 | // We must not include any core k8s APIs (e.g. k8s.io/api) in 12 | // the dependencies, depending on them will likely to cause version skew for 13 | // consumers. The dependencies for tests and examples should be isolated. 14 | k8s.io/klog/v2 v2.60.1 15 | sigs.k8s.io/kustomize/kyaml v0.13.7-0.20220418212550-9d5491c2e20c 16 | 17 | ) 18 | 19 | require ( 20 | github.com/PuerkitoBio/purell v1.1.1 // indirect 21 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect 22 | github.com/davecgh/go-spew v1.1.1 // indirect 23 | github.com/go-logr/logr v1.2.0 // indirect 24 | github.com/go-openapi/jsonpointer v0.19.5 // indirect 25 | github.com/go-openapi/jsonreference v0.19.6 // indirect 26 | github.com/go-openapi/swag v0.21.1 // indirect 27 | github.com/gogo/protobuf v1.3.2 // indirect 28 | github.com/golang/protobuf v1.5.2 // indirect 29 | github.com/google/gnostic v0.5.7-v3refs // indirect 30 | github.com/josharian/intern v1.0.0 // indirect 31 | github.com/kr/pretty v0.3.0 // indirect 32 | github.com/mailru/easyjson v0.7.7 // indirect 33 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect 34 | github.com/pkg/errors v0.9.1 // indirect 35 | github.com/pmezard/go-difflib v1.0.0 // indirect 36 | github.com/rogpeppe/go-internal v1.9.0 // indirect 37 | github.com/xlab/treeprint v1.1.0 // indirect 38 | golang.org/x/net v0.7.0 // indirect 39 | golang.org/x/text v0.7.0 // indirect 40 | google.golang.org/protobuf v1.28.0 // indirect 41 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect 42 | gopkg.in/yaml.v2 v2.4.0 // indirect 43 | gopkg.in/yaml.v3 v3.0.1 // indirect 44 | k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661 // indirect 45 | sigs.k8s.io/yaml v1.3.0 // indirect 46 | ) 47 | -------------------------------------------------------------------------------- /go/fn/internal/document.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package internal 16 | 17 | import ( 18 | "bytes" 19 | "io" 20 | 21 | "sigs.k8s.io/kustomize/kyaml/yaml" 22 | ) 23 | 24 | type doc struct { 25 | nodes []*yaml.Node 26 | } 27 | 28 | func NewDoc(nodes ...*yaml.Node) *doc { 29 | return &doc{nodes: nodes} 30 | } 31 | 32 | func ParseDoc(b []byte) (*doc, error) { 33 | br := bytes.NewReader(b) 34 | 35 | var nodes []*yaml.Node 36 | decoder := yaml.NewDecoder(br) 37 | for { 38 | node := &yaml.Node{} 39 | if err := decoder.Decode(node); err != nil { 40 | if err == io.EOF { 41 | break 42 | } 43 | return nil, err 44 | } 45 | nodes = append(nodes, node) 46 | } 47 | 48 | return &doc{nodes: nodes}, nil 49 | } 50 | 51 | func (d *doc) ToYAML() ([]byte, error) { 52 | var w bytes.Buffer 53 | encoder := yaml.NewEncoder(&w) 54 | for _, node := range d.nodes { 55 | if node.Kind == yaml.DocumentNode { 56 | if len(node.Content) == 0 { 57 | // These cause errors when we try to write them 58 | continue 59 | } 60 | } 61 | if err := encoder.Encode(node); err != nil { 62 | return nil, err 63 | } 64 | } 65 | 66 | return w.Bytes(), nil 67 | } 68 | 69 | func (d *doc) Elements() ([]*MapVariant, error) { 70 | return ExtractObjects(d.nodes...) 71 | } 72 | -------------------------------------------------------------------------------- /go/fn/internal/slice.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package internal 16 | 17 | import ( 18 | "sigs.k8s.io/kustomize/kyaml/yaml" 19 | ) 20 | 21 | type sliceVariant struct { 22 | node *yaml.Node 23 | } 24 | 25 | func NewSliceVariant(s ...variant) *sliceVariant { 26 | node := buildSequenceNode() 27 | for _, v := range s { 28 | node.Content = append(node.Content, v.Node()) 29 | } 30 | return &sliceVariant{node: node} 31 | } 32 | 33 | func (v *sliceVariant) GetKind() variantKind { 34 | return variantKindSlice 35 | } 36 | 37 | func (v *sliceVariant) Node() *yaml.Node { 38 | return v.node 39 | } 40 | 41 | func (v *sliceVariant) Clear() { 42 | v.node.Content = nil 43 | } 44 | 45 | func (v *sliceVariant) Elements() ([]*MapVariant, error) { 46 | return ExtractObjects(v.node.Content...) 47 | } 48 | 49 | func (v *sliceVariant) Add(node variant) { 50 | v.node.Content = append(v.node.Content, node.Node()) 51 | } 52 | -------------------------------------------------------------------------------- /go/fn/io.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package fn 16 | 17 | import ( 18 | "sigs.k8s.io/kustomize/kyaml/errors" 19 | "sigs.k8s.io/kustomize/kyaml/kio" 20 | "sigs.k8s.io/kustomize/kyaml/yaml" 21 | ) 22 | 23 | // byteReadWriter wraps kio.ByteReadWriter 24 | type byteReadWriter struct { 25 | kio.ByteReadWriter 26 | } 27 | 28 | // Read decodes input bytes into a ResourceList 29 | func (rw *byteReadWriter) Read() (*ResourceList, error) { 30 | nodes, err := rw.ByteReadWriter.Read() 31 | if err != nil { 32 | return nil, err 33 | } 34 | var items KubeObjects 35 | for _, n := range nodes { 36 | obj, err := ParseKubeObject([]byte(n.MustString())) 37 | if err != nil { 38 | return nil, err 39 | } 40 | items = append(items, obj) 41 | } 42 | obj, err := ParseKubeObject([]byte(rw.ByteReadWriter.FunctionConfig.MustString())) 43 | if err != nil { 44 | return nil, err 45 | } 46 | return &ResourceList{ 47 | Items: items, 48 | FunctionConfig: obj, 49 | }, nil 50 | } 51 | 52 | // Write writes a ResourceList into bytes 53 | func (rw *byteReadWriter) Write(rl *ResourceList) error { 54 | if len(rl.Results) > 0 { 55 | b, err := yaml.Marshal(rl.Results) 56 | if err != nil { 57 | return errors.Wrap(err) 58 | } 59 | y, err := yaml.Parse(string(b)) 60 | if err != nil { 61 | return errors.Wrap(err) 62 | } 63 | rw.Results = y 64 | } 65 | var nodes []*yaml.RNode 66 | for _, item := range rl.Items { 67 | node, err := yaml.Parse(item.String()) 68 | if err != nil { 69 | return err 70 | } 71 | nodes = append(nodes, node) 72 | } 73 | return rw.ByteReadWriter.Write(nodes) 74 | } 75 | -------------------------------------------------------------------------------- /go/fn/log.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package fn 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | ) 21 | 22 | func Log(in ...interface{}) { 23 | fmt.Fprintln(os.Stderr, in...) 24 | } 25 | 26 | func Logf(format string, in ...interface{}) { 27 | fmt.Fprintf(os.Stderr, format, in...) 28 | } 29 | -------------------------------------------------------------------------------- /go/fn/origin_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package fn 15 | 16 | import ( 17 | "testing" 18 | ) 19 | 20 | var resource = []byte(` 21 | apiVersion: v1 22 | kind: ConfigMap 23 | metadata: 24 | name: cm 25 | annotations: 26 | internal.kpt.dev/upstream-identifier: '|ConfigMap|example|example' 27 | `) 28 | 29 | var resourceCustom = []byte(` 30 | apiVersion: test.kpt.dev/v1 31 | kind: Custom 32 | metadata: 33 | name: cm 34 | `) 35 | 36 | func TestOrigin(t *testing.T) { 37 | noGroup, _ := ParseKubeObject(resource) 38 | 39 | if id, _ := noGroup.GetOriginId(); id.String() != "|ConfigMap|example|example" { 40 | t.Fatalf("GetOriginId() expect %v, got %v", "|ConfigMap|example|example", id) 41 | } 42 | defaultNamespace, _ := ParseKubeObject(resource) 43 | if defaultNamespace.GetId().String() != "|ConfigMap|default|cm" { 44 | t.Fatalf("GetId() expect %v, got %v", "|ConfigMap|default|cm", defaultNamespace.GetId()) 45 | } 46 | sameIdAndOrigin, _ := ParseKubeObject(resourceCustom) 47 | if id, _ := sameIdAndOrigin.GetOriginId(); id.String() != sameIdAndOrigin.GetId().String() { 48 | t.Fatalf("expect the origin and id the same if upstream-identifier is not given, got OriginID %v, got ID %v", 49 | id, sameIdAndOrigin.GetId()) 50 | } 51 | unknownNamespace, _ := ParseKubeObject(resourceCustom) 52 | if unknownNamespace.GetId().Namespace != UnknownNamespace { 53 | t.Fatalf("expect unknown custom resource use namespace %v, got %v", 54 | UnknownNamespace, unknownNamespace.GetId().Namespace) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /go/fn/resourcelist_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package fn 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/google/go-cmp/cmp" 21 | ) 22 | 23 | var dupResourceInput = []byte(` 24 | apiVersion: config.kubernetes.io/v1 25 | kind: ResourceList 26 | items: 27 | - apiVersion: v1 28 | kind: Namespace 29 | metadata: 30 | name: example 31 | - apiVersion: v1 32 | kind: Namespace 33 | metadata: 34 | name: example 35 | `) 36 | 37 | func TestCheckResourceDuplication(t *testing.T) { 38 | rl, _ := ParseResourceList(dupResourceInput) 39 | err := CheckResourceDuplication(rl) 40 | if err == nil { 41 | t.Errorf("expect to received duplicate error: got nil") 42 | } 43 | expectErr := "duplicate Resource(apiVersion=v1, kind=Namespace, Namespace=, Name=example)" 44 | if err.Error() != expectErr { 45 | t.Errorf("expect CheckResourceDuplication to fail; got %v, want %v", err, expectErr) 46 | } 47 | } 48 | 49 | func TestParseResourceListResults(t *testing.T) { 50 | rl, err := ParseResourceList([]byte(` 51 | apiVersion: config.kubernetes.io/v1 52 | kind: ResourceList 53 | items: 54 | - apiVersion: v1 55 | kind: Namespace 56 | metadata: 57 | name: example 58 | results: 59 | - message: foo 60 | severity: error 61 | - message: bar 62 | severity: warning 63 | `)) 64 | if err != nil { 65 | t.Fatalf("unexpected error: %v", err) 66 | } 67 | expected := Results{ 68 | { 69 | Message: "foo", 70 | Severity: Error, 71 | }, 72 | { 73 | Message: "bar", 74 | Severity: Warning, 75 | }, 76 | } 77 | if !cmp.Equal(expected, rl.Results) { 78 | t.Fatalf("unexpected diff: %v", cmp.Diff(expected, rl.Results)) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /go/get-started/README.md: -------------------------------------------------------------------------------- 1 | # some-function-name 2 | 3 | Note: Please ensure you follow the [kpt doc style guide]. 4 | 5 | ## Overview 6 | 7 | 8 | 9 | Explain what this function does in one or two sentences. 10 | 11 | 12 | 13 | Describe why the user should care about this function. 14 | 15 | What problem does it solve? 16 | 17 | Provide some context (e.g. In the `gatekeeper` function, explain what's 18 | is `Gatekeeper` project) 19 | 20 | [//]: <> (Note: The content between `` and the following 21 | `` will be used as the short description for the command.) 22 | 23 | 24 | 25 | ## Usage 26 | 27 | How do I use this function? 28 | 29 | Explain what does it do in details. 30 | 31 | Is this function meant to be used declaratively, imperatively or both? 32 | 33 | ### FunctionConfig 34 | 35 | Omit this section, if the function doesn't support any `functionConfigs`. 36 | Otherwise, explain the function config and behavior for this function in detail. 37 | For each field in the function config, specify: 38 | 39 | - An example value 40 | - Whether it is optional, and if so, the default value 41 | 42 | If showing the function orchestrator (e.g. kpt) can make it clear about how to 43 | use the function, it's recommended to use it. 44 | 45 | [//]: <> (Note: The content between `` and the following 46 | `` will be used as the long description for the command.) 47 | 48 | 49 | 50 | ## Examples 51 | 52 | 53 | 54 | Omit this section if you are providing complete example kpt packages which are 55 | linked from the catalog site. 56 | 57 | Otherwise, provide inline examples in this section. 58 | 59 | [//]: <> (Note: The content between `` and the following 60 | `` will be used as the examples for the command.) 61 | 62 | 63 | 64 | [kpt doc style guide]: https://github.com/GoogleContainerTools/kpt/blob/main/docs/style-guides/docs.md 65 | -------------------------------------------------------------------------------- /go/get-started/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/GoogleContainerTools/kpt-functions-sdk/go/get-started 2 | 3 | go 1.19 4 | 5 | require github.com/GoogleContainerTools/kpt-functions-sdk/go/fn v0.0.0-20221018174030-e63010a12b00 6 | 7 | require ( 8 | github.com/GoogleContainerTools/kpt-functions-sdk/go/api v0.0.0-20221018174030-e63010a12b00 // indirect 9 | github.com/davecgh/go-spew v1.1.1 // indirect 10 | github.com/go-errors/errors v1.4.2 // indirect 11 | github.com/go-logr/logr v1.2.3 // indirect 12 | github.com/go-openapi/jsonpointer v0.19.5 // indirect 13 | github.com/go-openapi/jsonreference v0.20.0 // indirect 14 | github.com/go-openapi/swag v0.22.3 // indirect 15 | github.com/gogo/protobuf v1.3.2 // indirect 16 | github.com/golang/protobuf v1.5.2 // indirect 17 | github.com/google/gnostic v0.6.9 // indirect 18 | github.com/google/go-cmp v0.5.9 // indirect 19 | github.com/google/gofuzz v1.2.0 // indirect 20 | github.com/josharian/intern v1.0.0 // indirect 21 | github.com/mailru/easyjson v0.7.7 // indirect 22 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect 23 | github.com/stretchr/testify v1.8.1 // indirect 24 | github.com/xlab/treeprint v1.1.0 // indirect 25 | golang.org/x/sys v0.5.0 // indirect 26 | google.golang.org/protobuf v1.28.1 // indirect 27 | gopkg.in/yaml.v2 v2.4.0 // indirect 28 | gopkg.in/yaml.v3 v3.0.1 // indirect 29 | k8s.io/apimachinery v0.25.3 // indirect 30 | k8s.io/klog/v2 v2.80.1 // indirect 31 | k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect 32 | sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect 33 | ) 34 | -------------------------------------------------------------------------------- /go/get-started/golden_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package main 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 21 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn/testhelpers" 22 | ) 23 | 24 | const TestDataPath = "testdata" 25 | 26 | func TestFunction(t *testing.T) { 27 | fnRunner := fn.WithContext(context.TODO(), &YourFunction{}) 28 | // This golden test expects each sub-directory of `testdata` can has its input resources (in `resources.yaml`) 29 | // be modified to the output resources (in `_expected.yaml`). 30 | testhelpers.RunGoldenTests(t, TestDataPath, fnRunner) 31 | } 32 | -------------------------------------------------------------------------------- /go/get-started/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package main 16 | 17 | import ( 18 | "context" 19 | "os" 20 | 21 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 22 | ) 23 | 24 | var _ fn.Runner = &YourFunction{} 25 | 26 | // TODO: Change to your functionConfig "Kind" name. 27 | type YourFunction struct { 28 | FnConfigBool bool 29 | FnConfigInt int 30 | FnConfigFoo string 31 | } 32 | 33 | // Run is the main function logic. 34 | // `items` is parsed from the STDIN "ResourceList.Items". 35 | // `functionConfig` is from the STDIN "ResourceList.FunctionConfig". The value has been assigned to the r attributes 36 | // `results` is the "ResourceList.Results" that you can write result info to. 37 | func (r *YourFunction) Run(ctx *fn.Context, functionConfig *fn.KubeObject, items fn.KubeObjects, results *fn.Results) bool { 38 | // TODO: Write your code. 39 | return true 40 | } 41 | 42 | func main() { 43 | runner := fn.WithContext(context.Background(), &YourFunction{}) 44 | if err := fn.AsMain(runner); err != nil { 45 | os.Exit(1) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /go/get-started/testdata/test1/_expected.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: config.kubernetes.io/v1 2 | kind: ResourceList 3 | items: 4 | - apiVersion: apps/v1 5 | kind: Deployment 6 | metadata: 7 | name: nginx-deployment 8 | labels: 9 | app: nginx 10 | spec: 11 | replicas: 3 12 | selector: 13 | matchLabels: 14 | app: nginx 15 | template: 16 | metadata: 17 | labels: 18 | app: nginx 19 | spec: 20 | containers: 21 | - name: nginx 22 | image: nginx:1.14.2 23 | ports: 24 | - containerPort: 80 25 | - apiVersion: v1 26 | kind: Service 27 | metadata: 28 | name: test 29 | spec: 30 | selector: 31 | app: MyApp 32 | ports: 33 | - protocol: TCP 34 | port: 80 35 | targetPort: 9376 36 | functionConfig: 37 | apiVersion: fn.kpt.dev/v1alpha1 38 | kind: YourFunction 39 | metadata: 40 | name: test 41 | fnConfigFoo: example 42 | -------------------------------------------------------------------------------- /go/get-started/testdata/test1/_fnconfig.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 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 | apiVersion: fn.kpt.dev/v1alpha1 16 | kind: YourFunction 17 | metadata: 18 | name: test 19 | fnConfigFoo: example -------------------------------------------------------------------------------- /go/get-started/testdata/test1/resources.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 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 | apiVersion: v1 16 | kind: Service 17 | metadata: 18 | name: test 19 | spec: 20 | selector: 21 | app: MyApp 22 | ports: 23 | - protocol: TCP 24 | port: 80 25 | targetPort: 9376 26 | --- 27 | apiVersion: apps/v1 28 | kind: Deployment 29 | metadata: 30 | name: nginx-deployment 31 | labels: 32 | app: nginx 33 | spec: 34 | replicas: 3 35 | selector: 36 | matchLabels: 37 | app: nginx 38 | template: 39 | metadata: 40 | labels: 41 | app: nginx 42 | spec: 43 | containers: 44 | - name: nginx 45 | image: nginx:1.14.2 46 | ports: 47 | - containerPort: 80 -------------------------------------------------------------------------------- /go/hack/update-license.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # don't add licenses to the site directory, it will break the docs 18 | # and will add them to the theme which is a submodule (bad) 19 | command -v addlicense || go install github.com/google/addlicense@v1.0.0 20 | # - `addlicense` skips the .yaml files (specifically for golden test _expected.yaml) to avoid the conflict where 21 | # the `addlicense` adds unexpected license header that fails the golden tests diff-comparison in _expected.yaml. 22 | # - the [0-9a-z] is a trick to avoid using `**/**/*.yaml` directly which hits the shellcheck SC2035. SC2035 only accepts 23 | # ./*glob* or -- *glob* which can't be recoganized by addlicese. 24 | # See https://www.shellcheck.net/wiki/SC2035 25 | find . -print0 | xargs "$GOBIN"/addlicense -y 2022 -l apache -ignore [0-9a-z]**/**/_expected.yaml 26 | 27 | -------------------------------------------------------------------------------- /go/kfn/commands/embed/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 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 | FROM golang:1.19-alpine3.15 16 | ENV CGO_ENABLED=0 17 | WORKDIR /go/src/ 18 | COPY go.mod go.sum ./ 19 | RUN go mod download 20 | COPY . . 21 | RUN go build -o /usr/local/bin/function ./ 22 | FROM gcr.io/distroless/static:latest 23 | COPY --from=0 /usr/local/bin/function /usr/local/bin/function 24 | ENTRYPOINT ["function"] -------------------------------------------------------------------------------- /go/kfn/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/GoogleContainerTools/kpt-functions-sdk/go/kfn 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/heroku/color v0.0.6 7 | github.com/spf13/cobra v1.6.1 8 | github.com/stretchr/testify v1.8.1 9 | ) 10 | 11 | require ( 12 | github.com/davecgh/go-spew v1.1.1 // indirect 13 | github.com/inconshreveable/mousetrap v1.0.1 // indirect 14 | github.com/mattn/go-colorable v0.1.2 // indirect 15 | github.com/mattn/go-isatty v0.0.8 // indirect 16 | github.com/pmezard/go-difflib v1.0.0 // indirect 17 | github.com/spf13/pflag v1.0.5 // indirect 18 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect 19 | gopkg.in/yaml.v3 v3.0.1 // indirect 20 | ) 21 | -------------------------------------------------------------------------------- /go/kfn/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package main 16 | 17 | import ( 18 | "context" 19 | "os" 20 | 21 | "github.com/GoogleContainerTools/kpt-functions-sdk/go/kfn/commands" 22 | "github.com/spf13/cobra" 23 | ) 24 | 25 | func main() { 26 | var err error 27 | cmd := &cobra.Command{ 28 | Use: "kfn", 29 | Short: "a CLI tool to edit your own KRM functions with ease", 30 | } 31 | ctx := context.Background() 32 | cmd.AddCommand(commands.NewInitRunner(ctx).Command) 33 | cmd.AddCommand(commands.NewBuildRunner(ctx).Command) 34 | err = cmd.Execute() 35 | if err != nil { 36 | os.Exit(1) 37 | } 38 | os.Exit(0) 39 | } 40 | -------------------------------------------------------------------------------- /hack/ci-validate-go.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2022 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | set -o errexit 16 | set -o nounset 17 | set -o pipefail 18 | 19 | make go 20 | 21 | changes=$(git status --porcelain) 22 | if [ -n "${changes}" ]; then 23 | echo "ERROR: files are not to date; please run: hack/generate.sh" 24 | echo "changed files:" 25 | printf "%s" "${changes}\n" 26 | echo "git diff:" 27 | git --no-pager diff 28 | exit 1 29 | fi 30 | -------------------------------------------------------------------------------- /starlark/get-started/data/resources.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-service 5 | spec: 6 | selector: 7 | app: MyApp 8 | ports: 9 | - protocol: TCP 10 | port: 80 11 | targetPort: 9376 12 | --- 13 | apiVersion: apps/v1 14 | kind: Deployment 15 | metadata: 16 | name: nginx-deployment 17 | labels: 18 | app: nginx 19 | spec: 20 | replicas: 3 21 | selector: 22 | matchLabels: 23 | app: nginx 24 | template: 25 | metadata: 26 | labels: 27 | app: nginx 28 | spec: 29 | containers: 30 | - name: nginx 31 | image: nginx:1.14.2 32 | ports: 33 | - containerPort: 80 -------------------------------------------------------------------------------- /starlark/get-started/starlark-fn-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: fn.kpt.dev/v1alpha1 2 | kind: StarlarkRun 3 | metadata: 4 | name: set-annotation 5 | # EDIT THE SOURCE! 6 | # This should be your starlark script which preloads the `ResourceList` to `ctx.resource_list` 7 | source: | 8 | for resource in ctx.resource_list["items"]: 9 | if resource.get("kind") == "Deployment": 10 | resource["metadata"]["annotations"]["managed-by"] = "kpt" 11 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/README.md: -------------------------------------------------------------------------------- 1 | # kpt Functions SDK CLI 2 | 3 | Documentation: 4 | 5 | https://kpt.dev/book/05-developing-functions/03-developing-in-Typescript 6 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": ".", 3 | "spec_files": ["dist/**/*_test.js"], 4 | "helpers": [], 5 | "stopSpecOnExpectationFailure": false, 6 | "random": true 7 | } 8 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/src/cmd/docker_build.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { spawnSync } from 'child_process'; 18 | import { processDockerfile } from './docker_create'; 19 | import { log } from '../utils/log'; 20 | 21 | export function dockerBuild(packageDir: string, dockerTag: string) { 22 | log('Building image...\n'); 23 | processDockerfile( 24 | packageDir, 25 | dockerTag, 26 | (dockerFile, functionName, image) => { 27 | const build = spawnSync( 28 | 'docker', 29 | ['build', '-q', '-t', image, '-f', dockerFile, '.'], 30 | { 31 | stdio: 'inherit', 32 | } 33 | ); 34 | if (build.status !== 0) { 35 | let msg = 'Failed to build docker image'; 36 | if (build.error) { 37 | msg = `${msg}: ${build.error}`; 38 | } 39 | throw new Error(msg); 40 | } 41 | } 42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/src/cmd/docker_push.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { spawnSync } from 'child_process'; 18 | import { log } from '../utils/log'; 19 | import { processDockerfile } from './docker_create'; 20 | 21 | export function dockerPush(packageDir: string, dockerTag: string) { 22 | log('Pushing image...\n'); 23 | processDockerfile( 24 | packageDir, 25 | dockerTag, 26 | (dockerFile, functionName, image) => { 27 | const push = spawnSync('docker', ['push', image], { stdio: 'inherit' }); 28 | if (push.status !== 0) { 29 | let msg = 'Failed to push docker image'; 30 | if (push.error) { 31 | msg = `${msg}: ${push.error}`; 32 | } 33 | throw new Error(msg); 34 | } 35 | } 36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/src/cmd/function_create.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { question } from 'cli-interact'; 18 | import * as path from 'path'; 19 | import { USER_PACKAGE } from '../paths'; 20 | import * as format from '../utils/format'; 21 | import { log } from '../utils/log'; 22 | import { Templates } from '../utils/templates'; 23 | import * as validator from '../utils/validator'; 24 | 25 | export function functionCreate(appDir: string) { 26 | const desc = 'Adding a kpt function.'; 27 | log(format.startMarker(desc)); 28 | 29 | const defaultFuncName = 'my_func'; 30 | const funcName = validator.getValidString( 31 | () => question(`> What is the function name (${defaultFuncName})? `), 32 | validator.isValidFuncName, 33 | defaultFuncName 34 | ); 35 | log(`Using function name "${funcName}".\n`); 36 | 37 | const tsFuncName = validator.toTSName(funcName); 38 | const srcDir = path.join(appDir, USER_PACKAGE.src); 39 | 40 | new Templates([ 41 | { 42 | templateFile: 'func.mustache', 43 | outputPath: path.join(srcDir, funcName + '.ts'), 44 | view: { 45 | func_name: tsFuncName, 46 | }, 47 | }, 48 | { 49 | templateFile: 'run.mustache', 50 | outputPath: path.join(srcDir, funcName + '_run.ts'), 51 | view: { 52 | file_name: funcName, 53 | func_name: tsFuncName, 54 | }, 55 | }, 56 | { 57 | templateFile: 'test.mustache', 58 | outputPath: path.join(srcDir, funcName + '_test.ts'), 59 | view: { 60 | file_name: funcName, 61 | func_name: tsFuncName, 62 | }, 63 | }, 64 | ]).render(); 65 | 66 | log(format.finishMarker(desc)); 67 | } 68 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/src/paths.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { resolve } from 'path'; 18 | 19 | // Absolute paths in this package. 20 | export const CLI_PACKAGE = { 21 | binDir: resolve(__dirname, '..', 'node_modules', '.bin'), 22 | templates: resolve(__dirname, '..', 'templates'), 23 | }; 24 | 25 | // Paths relative to user package. 26 | export const USER_PACKAGE = { 27 | src: 'src', 28 | build: 'build', 29 | workflows: 'workflows', 30 | }; 31 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/src/utils/format.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import chalk from 'chalk'; 18 | 19 | /** 20 | * Formats an input string to indicate nothing is wrong. 21 | */ 22 | export function success(s: string): string { 23 | return chalk.green(s); 24 | } 25 | 26 | /** 27 | * Formats an input string to indicate an error condition. 28 | */ 29 | export function failure(s: string): string { 30 | return chalk.red(chalk.bold(s)); 31 | } 32 | 33 | /** 34 | * Formats an input string to indicate a warn condition. 35 | */ 36 | export function warn(s: string): string { 37 | return chalk.yellow(chalk.bold(s)); 38 | } 39 | 40 | /** 41 | * Marks the starting point of an operation. 42 | */ 43 | export function startMarker(s: string): string { 44 | return chalk.bold(`\nStarting: ${s}\n`); 45 | } 46 | 47 | /** 48 | * Marks the ending point of an operation that was completed successfully. 49 | */ 50 | export function finishMarker(s: string): string { 51 | return success(`\nCompleted: ${s}\n`); 52 | } 53 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/src/utils/log.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * An overwritable log command allowing redirecting logging output. 19 | * 20 | * It is possible to directly overwrite console.log, but this causes many known issues. 21 | * 22 | * A better solution would involve defining our own logger. 23 | */ 24 | export let log = console.log; 25 | 26 | /** 27 | * Causes log to do nothing. For use in testing. 28 | */ 29 | export function disableLogForTesting() { 30 | log = () => { 31 | return; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/src/utils/templates.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'; 18 | import { render } from 'mustache'; 19 | import { dirname, isAbsolute, join } from 'path'; 20 | import { CLI_PACKAGE } from '../paths'; 21 | import { log } from './log'; 22 | 23 | interface Template { 24 | // Template file relative to TEMPLATE_DIR 25 | templateFile: string; 26 | // Absolute path to the output file. 27 | // If the parent directory doesn't exit, it will be created recursively. 28 | outputPath: string; 29 | // Values to substitude in the template. 30 | view?: any; 31 | } 32 | 33 | export class Templates { 34 | constructor(private templates: Template[]) {} 35 | 36 | public render() { 37 | for (const t of this.templates) { 38 | const before = readFileSync( 39 | join(CLI_PACKAGE.templates, t.templateFile), 40 | 'utf8' 41 | ).toString(); 42 | const after = t.view ? render(before, t.view) : before; 43 | if (!isAbsolute(t.outputPath)) { 44 | throw new Error(`outputPath must be absolute: ${t.outputPath}`); 45 | } 46 | const parentDir = dirname(t.outputPath); 47 | if (!existsSync(parentDir)) { 48 | mkdirSync(parentDir, { recursive: true }); 49 | } 50 | writeFileSync(t.outputPath, after); 51 | log(`Generated ${t.outputPath}`); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/templates/Dockerfile.mustache: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/{{{file_name}}}"] 34 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/templates/dockerignore: -------------------------------------------------------------------------------- 1 | **/dist/ 2 | **/node_modules/ 3 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/templates/func.mustache: -------------------------------------------------------------------------------- 1 | import { Configs } from 'kpt-functions'; 2 | 3 | export async function {{func_name}}(configs: Configs) { 4 | // TODO: implement. 5 | } 6 | 7 | {{func_name}}.usage = ` 8 | TODO: fill the following usage template. 9 | 10 | Overview 11 | Explain what this function does in one or two sentences. 12 | 13 | Synopsis 14 | Explain the function config and behavior for this function in detail. If the 15 | function supports both ConfigMap and CRD as function config, both should be 16 | documented. 17 | 18 | Examples 19 | Use examples to demonstrate how to use this function in different scenarios. 20 | Each example should have input, exact command to run and output. 21 | `; 22 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/templates/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": ".", 3 | "spec_files": ["dist/**/*_test.js"], 4 | "helpers": [ 5 | ], 6 | "stopSpecOnExpectationFailure": false, 7 | "random": true 8 | } 9 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/templates/package.json.mustache: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{{package_name}}}", 3 | "version": "0.1.0", 4 | "scripts": { 5 | "prepare": "npm run build", 6 | "build": "tsc", 7 | "watch": "tsc --watch", 8 | "clean": "rm -Rf node_modules/ dist/", 9 | "pretest": "npm run build", 10 | "test": "jasmine --config=jasmine.json", 11 | "kpt:docker-create": "kpt docker-create", 12 | "kpt:docker-build": "kpt docker-build", 13 | "kpt:docker-push": "kpt docker-push", 14 | "kpt:function-create": "kpt function-create", 15 | "kpt:type-create": "kpt type-create" 16 | }, 17 | "dependencies": { 18 | "kpt-functions": "^0.16.0" 19 | }, 20 | "devDependencies": { 21 | "create-kpt-functions": "^0.19.0", 22 | "@types/jasmine": "^3.7.6", 23 | "@types/node": "^14.17.1", 24 | "jasmine": "^3.7.0", 25 | "tslint": "^6.1.3", 26 | "typescript": "^4.3.2" 27 | }, 28 | "config": { 29 | "docker_repo_base": "{{{docker_repo_base}}}" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/templates/run.mustache: -------------------------------------------------------------------------------- 1 | import { {{func_name}} } from './{{{file_name}}}'; 2 | import { run } from 'kpt-functions'; 3 | 4 | run({{func_name}}); 5 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/templates/test.mustache: -------------------------------------------------------------------------------- 1 | import { Configs, TestRunner } from 'kpt-functions'; 2 | import { {{{func_name}}} } from './{{{file_name}}}'; 3 | 4 | const RUNNER = new TestRunner({{{func_name}}}); 5 | 6 | describe('{{{func_name}}}', () => { 7 | it('does something', async () => { 8 | // TODO: Populate the input to the function. 9 | const input = new Configs(); 10 | 11 | // TODO: Populate the expected output of the function. 12 | const expectedOutput = new Configs(); 13 | 14 | await RUNNER.assert(input, expectedOutput); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/templates/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "resolveJsonModule": true, 6 | "esModuleInterop": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noUnusedLocals": true, 10 | "noImplicitAny": true, 11 | "noImplicitReturns": true, 12 | "moduleResolution": "node", 13 | "sourceMap": true, 14 | "outDir": "dist", 15 | "lib": [ 16 | "es2015" 17 | ], 18 | "rootDir": "src/" 19 | }, 20 | "exclude": [ 21 | "node_modules", 22 | "dist" 23 | ], 24 | "include": [ 25 | "src/**/*" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /ts/create-kpt-functions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowUnreachableCode": false, 4 | "allowUnusedLabels": false, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "lib": ["es2018"], 9 | "module": "commonjs", 10 | "moduleResolution": "node", 11 | "noEmitOnError": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "noImplicitAny": true, 14 | "noImplicitReturns": true, 15 | "noUnusedLocals": true, 16 | "outDir": "dist", 17 | "pretty": true, 18 | "resolveJsonModule": true, 19 | "rootDir": "src", 20 | "sourceMap": true, 21 | "strict": true, 22 | "target": "es2018" 23 | }, 24 | "exclude": ["node_modules", "dist"], 25 | "include": ["src/**/*"] 26 | } 27 | -------------------------------------------------------------------------------- /ts/demo-functions/.dockerignore: -------------------------------------------------------------------------------- 1 | **/dist/ 2 | **/node_modules/ 3 | 4 | -------------------------------------------------------------------------------- /ts/demo-functions/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /ts/demo-functions/build/annotate_config.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/annotate_config_run.js"] 34 | -------------------------------------------------------------------------------- /ts/demo-functions/build/expand_team_cr.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/expand_team_cr_run.js"] 34 | -------------------------------------------------------------------------------- /ts/demo-functions/build/label_namespace.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/label_namespace_run.js"] 34 | -------------------------------------------------------------------------------- /ts/demo-functions/build/mutate_psp.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/mutate_psp_run.js"] 34 | -------------------------------------------------------------------------------- /ts/demo-functions/build/no_op.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/no_op_run.js"] 34 | -------------------------------------------------------------------------------- /ts/demo-functions/build/read_yaml.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/read_yaml_run.js"] 34 | -------------------------------------------------------------------------------- /ts/demo-functions/build/suggest_psp.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/suggest_psp_run.js"] 34 | -------------------------------------------------------------------------------- /ts/demo-functions/build/validate_rolebinding.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/validate_rolebinding_run.js"] 34 | -------------------------------------------------------------------------------- /ts/demo-functions/build/write_yaml.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/write_yaml_run.js"] 34 | -------------------------------------------------------------------------------- /ts/demo-functions/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": ".", 3 | "spec_files": ["dist/**/*_test.js"], 4 | "helpers": [], 5 | "stopSpecOnExpectationFailure": false, 6 | "random": true 7 | } 8 | -------------------------------------------------------------------------------- /ts/demo-functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-functions", 3 | "version": "0.0.1", 4 | "description": "kpt functions for demo purposes", 5 | "author": "kpt Authors", 6 | "license": "Apache-2.0", 7 | "scripts": { 8 | "prepare": "npm run build", 9 | "build": "tsc", 10 | "watch": "tsc --watch", 11 | "clean": "rm -Rf node_modules/ dist/", 12 | "lint": "tslint -p package.json && prettier \"src/**\" \"*.json\" --check", 13 | "lint-license": "license-checker --onlyAllow 'Apache-2.0;MIT;BSD;BSD-2-Clause;BSD-3-Clause;ISC;CC-BY-3.0;CC0-1.0;Python-2.0;Unlicense'", 14 | "format": "prettier \"src/**\" \"*.json\" --write", 15 | "pretest": "npm run build", 16 | "test": "jasmine --config=jasmine.json", 17 | "posttest": "npm run lint", 18 | "kpt:docker-create": "kpt docker-create", 19 | "kpt:docker-build": "kpt docker-build", 20 | "kpt:docker-push": "kpt docker-push", 21 | "kpt:function-create": "kpt function-create", 22 | "kpt:type-create": "kpt type-create" 23 | }, 24 | "dependencies": { 25 | "glob": "^7.2.0", 26 | "js-yaml": "^3.14.1", 27 | "kpt-functions": "^0.16.1-rc.0" 28 | }, 29 | "devDependencies": { 30 | "@types/fs-extra": "^9.0.13", 31 | "@types/glob": "^7.2.0", 32 | "@types/jasmine": "^3.9.1", 33 | "@types/js-yaml": "^3.12.5", 34 | "@types/node": "^14.17.19", 35 | "create-kpt-functions": "^0.19.0", 36 | "dir-compare": "^2.4.0", 37 | "fs-extra": "^9.0.1", 38 | "jasmine": "^3.9.0", 39 | "license-checker": "^25.0.1", 40 | "prettier": "2.4.1", 41 | "tslint": "^6.1.3", 42 | "tslint-config-prettier": "1.18.0", 43 | "tslint-consistent-codestyle": "^1.16.0", 44 | "typescript": "^4.4.4" 45 | }, 46 | "kpt": { 47 | "docker_repo_base": "gcr.io/kpt-functions" 48 | }, 49 | "repository": { 50 | "type": "git" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ts/demo-functions/src/annotate_config.ts: -------------------------------------------------------------------------------- 1 | import { Configs, addAnnotation } from 'kpt-functions'; 2 | 3 | const ANNOTATION_NAME = 'annotation_name'; 4 | const ANNOTATION_VALUE = 'annotation_value'; 5 | 6 | export async function annotateConfig(configs: Configs) { 7 | const annotationName = configs.getFunctionConfigValueOrThrow(ANNOTATION_NAME); 8 | const annotationValue = 9 | configs.getFunctionConfigValueOrThrow(ANNOTATION_VALUE); 10 | configs 11 | .getAll() 12 | .forEach((n) => addAnnotation(n, annotationName, annotationValue)); 13 | } 14 | 15 | annotateConfig.usage = ` 16 | Adds an annotation to all configuration files. 17 | 18 | Configured using a ConfigMap with the following keys: 19 | 20 | ${ANNOTATION_NAME}: Annotation name to add to configs. 21 | ${ANNOTATION_VALUE}: Annotation value to add to configs. 22 | 23 | Example: 24 | 25 | To add an annotation 'org: sre-supported' to Namespaces: 26 | 27 | apiVersion: v1 28 | kind: ConfigMap 29 | data: 30 | ${ANNOTATION_NAME}: org 31 | ${ANNOTATION_VALUE}: sre-supported 32 | metadata: 33 | name: my-config 34 | `; 35 | -------------------------------------------------------------------------------- /ts/demo-functions/src/annotate_config_run.ts: -------------------------------------------------------------------------------- 1 | import { annotateConfig } from './annotate_config'; 2 | import { run } from 'kpt-functions'; 3 | 4 | run(annotateConfig); 5 | -------------------------------------------------------------------------------- /ts/demo-functions/src/annotate_config_test.ts: -------------------------------------------------------------------------------- 1 | import { Configs, TestRunner } from 'kpt-functions'; 2 | import { annotateConfig } from './annotate_config'; 3 | import { ConfigMap, Namespace } from './gen/io.k8s.api.core.v1'; 4 | import { FunctionConfigError } from 'kpt-functions'; 5 | 6 | const RUNNER = new TestRunner(annotateConfig); 7 | const TEST_NAMESPACE = 'testNamespace'; 8 | const TEST_ANNOTATION_NAME = 'configsupport'; 9 | const TEST_ANNOTATION_VALUE = 'ops-supported'; 10 | const FUNC_CONFIG: ConfigMap = new ConfigMap({ 11 | metadata: { name: 'config' }, 12 | data: { 13 | annotation_name: TEST_ANNOTATION_NAME, 14 | annotation_value: TEST_ANNOTATION_VALUE, 15 | }, 16 | }); 17 | 18 | describe('annotateConfig', () => { 19 | it( 20 | 'empty input ok', 21 | RUNNER.assertCallback(new Configs(undefined, FUNC_CONFIG), 'unchanged') 22 | ); 23 | 24 | it( 25 | 'requires functionConfig', 26 | RUNNER.assertCallback(undefined, undefined, FunctionConfigError) 27 | ); 28 | 29 | it('adds annotation namespace when metadata.annotations is undefined', async () => { 30 | const input = new Configs(undefined, FUNC_CONFIG); 31 | input.insert(Namespace.named(TEST_NAMESPACE)); 32 | 33 | const output = new Configs(); 34 | output.insert( 35 | new Namespace({ 36 | metadata: { 37 | name: TEST_NAMESPACE, 38 | annotations: { [TEST_ANNOTATION_NAME]: TEST_ANNOTATION_VALUE }, 39 | }, 40 | }) 41 | ); 42 | 43 | await RUNNER.assert(input, output); 44 | }); 45 | 46 | it('adds annotation to namespace when metadata.annotations is defined', async () => { 47 | const input = new Configs(undefined, FUNC_CONFIG); 48 | input.insert( 49 | new Namespace({ 50 | metadata: { 51 | name: TEST_NAMESPACE, 52 | annotations: { a: 'b' }, 53 | }, 54 | }) 55 | ); 56 | 57 | const output = new Configs(); 58 | output.insert( 59 | new Namespace({ 60 | metadata: { 61 | name: TEST_NAMESPACE, 62 | annotations: { 63 | a: 'b', 64 | [TEST_ANNOTATION_NAME]: TEST_ANNOTATION_VALUE, 65 | }, 66 | }, 67 | }) 68 | ); 69 | 70 | await RUNNER.assert(input, output); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /ts/demo-functions/src/expand_team_cr_run.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { expandTeamCr } from './expand_team_cr'; 18 | import { run } from 'kpt-functions'; 19 | 20 | run(expandTeamCr); 21 | -------------------------------------------------------------------------------- /ts/demo-functions/src/gen/io.k8s.apimachinery.pkg.util.intstr.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // IntOrString is a type that can hold an int32 or a string. When used in JSON or YAML marshalling and unmarshalling, it produces or consumes the inner type. This allows you to have, for example, a JSON field that can accept a name or number. 18 | export type IntOrString = string; 19 | -------------------------------------------------------------------------------- /ts/demo-functions/src/gen/io.k8s.apimachinery.pkg.version.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Info contains versioning information. how we'll want to distribute that information. 18 | export class Info { 19 | public buildDate: string; 20 | 21 | public compiler: string; 22 | 23 | public gitCommit: string; 24 | 25 | public gitTreeState: string; 26 | 27 | public gitVersion: string; 28 | 29 | public goVersion: string; 30 | 31 | public major: string; 32 | 33 | public minor: string; 34 | 35 | public platform: string; 36 | 37 | constructor(desc: Info) { 38 | this.buildDate = desc.buildDate; 39 | this.compiler = desc.compiler; 40 | this.gitCommit = desc.gitCommit; 41 | this.gitTreeState = desc.gitTreeState; 42 | this.gitVersion = desc.gitVersion; 43 | this.goVersion = desc.goVersion; 44 | this.major = desc.major; 45 | this.minor = desc.minor; 46 | this.platform = desc.platform; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ts/demo-functions/src/label_namespace.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { addLabel, Configs } from 'kpt-functions'; 18 | import { isNamespace } from './gen/io.k8s.api.core.v1'; 19 | 20 | const LABEL_NAME = 'label_name'; 21 | const LABEL_VALUE = 'label_value'; 22 | 23 | export async function labelNamespace(configs: Configs) { 24 | const labelName = configs.getFunctionConfigValueOrThrow(LABEL_NAME); 25 | const labelValue = configs.getFunctionConfigValueOrThrow(LABEL_VALUE); 26 | configs.get(isNamespace).forEach((n) => addLabel(n, labelName, labelValue)); 27 | } 28 | 29 | labelNamespace.usage = ` 30 | Adds a label to all Namespaces. 31 | 32 | Configured using a ConfigMap with the following keys: 33 | 34 | ${LABEL_NAME}: Label name to add to Namespaces. 35 | ${LABEL_VALUE}: Label value to add to Namespaces. 36 | 37 | Example: 38 | 39 | To add a label 'color: orange' to Namespaces: 40 | 41 | apiVersion: v1 42 | kind: ConfigMap 43 | data: 44 | ${LABEL_NAME}: color 45 | ${LABEL_VALUE}: orange 46 | metadata: 47 | name: my-config 48 | `; 49 | -------------------------------------------------------------------------------- /ts/demo-functions/src/label_namespace_run.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { labelNamespace } from './label_namespace'; 18 | import { run } from 'kpt-functions'; 19 | 20 | run(labelNamespace); 21 | -------------------------------------------------------------------------------- /ts/demo-functions/src/mutate_psp.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Configs } from 'kpt-functions'; 18 | import { isPodSecurityPolicy } from './gen/io.k8s.api.policy.v1beta1'; 19 | 20 | export async function mutatePsp(configs: Configs) { 21 | // Iterate over all PodSecurityPolicy objects in the input and if 22 | // the 'allowPrivilegeEscalation' field is not to 'false', set the field to false. 23 | configs 24 | .get(isPodSecurityPolicy) 25 | .filter((psp) => psp.spec && psp.spec.allowPrivilegeEscalation !== false) 26 | .forEach((psp) => (psp!.spec!.allowPrivilegeEscalation = false)); 27 | } 28 | 29 | mutatePsp.usage = ` 30 | Mutates all PodSecurityPolicy by setting 'spec.allowPrivilegeEscalation' field to 'false'. 31 | `; 32 | -------------------------------------------------------------------------------- /ts/demo-functions/src/mutate_psp_run.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { mutatePsp } from './mutate_psp'; 18 | import { run } from 'kpt-functions'; 19 | 20 | run(mutatePsp); 21 | -------------------------------------------------------------------------------- /ts/demo-functions/src/mutate_psp_test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Configs, TestRunner } from 'kpt-functions'; 18 | import { PodSecurityPolicy } from './gen/io.k8s.api.policy.v1beta1'; 19 | import { mutatePsp } from './mutate_psp'; 20 | 21 | const RUNNER = new TestRunner(mutatePsp); 22 | 23 | describe('mutatePsp', () => { 24 | it('empty configs is noop', RUNNER.assertCallback(undefined, 'unchanged')); 25 | 26 | it( 27 | 'modifies PSP with allowPrivilegeEscalation = true to false', 28 | RUNNER.assertCallback(new Configs([psp(true)]), new Configs([psp(false)])) 29 | ); 30 | 31 | it( 32 | 'leaves PSP with allowPrivilegeEscalation = false alone', 33 | RUNNER.assertCallback(new Configs([psp(false)]), 'unchanged') 34 | ); 35 | }); 36 | 37 | function psp(allowPrivilegeEscalation: boolean): PodSecurityPolicy { 38 | return new PodSecurityPolicy({ 39 | metadata: { 40 | name: 'pod', 41 | }, 42 | spec: { 43 | allowPrivilegeEscalation, 44 | fsGroup: { rule: 'RunAsAny' }, 45 | runAsUser: { rule: 'RunAsAny' }, 46 | seLinux: { rule: 'RunAsAny' }, 47 | supplementalGroups: { rule: 'RunAsAny' }, 48 | }, 49 | }); 50 | } 51 | -------------------------------------------------------------------------------- /ts/demo-functions/src/no_op.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Configs } from 'kpt-functions'; 18 | 19 | export async function noOp(configs: Configs) {} 20 | 21 | noOp.usage = ` 22 | A NO OP kpt function used for testing and demo purposes. 23 | `; 24 | -------------------------------------------------------------------------------- /ts/demo-functions/src/no_op_run.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { noOp } from './no_op'; 18 | import { run } from 'kpt-functions'; 19 | 20 | run(noOp); 21 | -------------------------------------------------------------------------------- /ts/demo-functions/src/no_op_test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Configs, TestRunner } from 'kpt-functions'; 18 | import { noOp } from './no_op'; 19 | import { Role } from './gen/io.k8s.api.rbac.v1'; 20 | 21 | const RUNNER = new TestRunner(noOp); 22 | 23 | describe('noOp', () => { 24 | it('empty passes', RUNNER.assertCallback(undefined, 'unchanged')); 25 | 26 | it( 27 | 'pass through', 28 | RUNNER.assertCallback(new Configs([Role.named('alice')]), 'unchanged') 29 | ); 30 | }); 31 | -------------------------------------------------------------------------------- /ts/demo-functions/src/read_yaml_run.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { readYaml } from './read_yaml'; 18 | import { run } from 'kpt-functions'; 19 | 20 | run(readYaml); 21 | -------------------------------------------------------------------------------- /ts/demo-functions/src/suggest_psp.ts: -------------------------------------------------------------------------------- 1 | import { Configs, kubernetesObjectResult } from 'kpt-functions'; 2 | import { isPodSecurityPolicy } from './gen/io.k8s.api.policy.v1beta1'; 3 | 4 | export async function suggestPsp(configs: Configs) { 5 | // Iterate over all PodSecurityPolicy objects in the input and flag any 6 | // that do not have 'allowPrivilegeEscalation' field set to true. 7 | const results = configs 8 | .get(isPodSecurityPolicy) 9 | .filter((psp) => psp.spec && psp.spec.allowPrivilegeEscalation !== false) 10 | .map((psp) => 11 | kubernetesObjectResult( 12 | 'Suggest explicitly disabling privilege escalation', 13 | psp, 14 | { path: 'spec.allowPrivilegeEscalation', suggestedValue: false }, 15 | 'warn', 16 | { category: 'security' } 17 | ) 18 | ); 19 | 20 | configs.addResults(...results); 21 | } 22 | 23 | suggestPsp.usage = ` 24 | Lints PodSecurityPolicy by suggesting 'spec.allowPrivilegeEscalation' field be set to 'false'. 25 | `; 26 | -------------------------------------------------------------------------------- /ts/demo-functions/src/suggest_psp_run.ts: -------------------------------------------------------------------------------- 1 | import { suggestPsp } from './suggest_psp'; 2 | import { run } from 'kpt-functions'; 3 | 4 | run(suggestPsp); 5 | -------------------------------------------------------------------------------- /ts/demo-functions/src/suggest_psp_test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Configs, TestRunner, kubernetesObjectResult } from 'kpt-functions'; 18 | import { PodSecurityPolicy } from './gen/io.k8s.api.policy.v1beta1'; 19 | import { suggestPsp } from './suggest_psp'; 20 | 21 | const RUNNER = new TestRunner(suggestPsp); 22 | 23 | describe('suggestPsp', () => { 24 | it('empty configs is noop', RUNNER.assertCallback(undefined, 'unchanged')); 25 | 26 | it( 27 | 'suggest PSP with allowPrivilegeEscalation = true to false', 28 | RUNNER.assertCallback( 29 | new Configs([psp(true)]), 30 | new Configs([psp(true)], undefined, [ 31 | kubernetesObjectResult( 32 | 'Suggest explicitly disabling privilege escalation', 33 | psp(true), 34 | { path: 'spec.allowPrivilegeEscalation', suggestedValue: false }, 35 | 'warn', 36 | { category: 'security' } 37 | ), 38 | ]) 39 | ) 40 | ); 41 | 42 | it( 43 | 'leaves PSP with allowPrivilegeEscalation = false alone', 44 | RUNNER.assertCallback(new Configs([psp(false)]), 'unchanged') 45 | ); 46 | }); 47 | 48 | function psp(allowPrivilegeEscalation: boolean): PodSecurityPolicy { 49 | return new PodSecurityPolicy({ 50 | metadata: { 51 | name: 'pod', 52 | }, 53 | spec: { 54 | allowPrivilegeEscalation, 55 | fsGroup: { rule: 'RunAsAny' }, 56 | runAsUser: { rule: 'RunAsAny' }, 57 | seLinux: { rule: 'RunAsAny' }, 58 | supplementalGroups: { rule: 'RunAsAny' }, 59 | }, 60 | }); 61 | } 62 | -------------------------------------------------------------------------------- /ts/demo-functions/src/validate_rolebinding.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Configs, kubernetesObjectResult } from 'kpt-functions'; 18 | import { isRoleBinding } from './gen/io.k8s.api.rbac.v1'; 19 | 20 | const SUBJECT_NAME = 'subject_name'; 21 | 22 | export async function validateRolebinding(configs: Configs) { 23 | // Get the subject name parameter. 24 | const subjectName = configs.getFunctionConfigValueOrThrow(SUBJECT_NAME); 25 | 26 | // Iterate over all RoleBinding objects in the input, and filter those that have a subject 27 | // we're looking for. 28 | const results = configs 29 | .get(isRoleBinding) 30 | .filter( 31 | (rb) => 32 | rb && rb.subjects && rb.subjects.find((s) => s.name === subjectName) 33 | ) 34 | .map((rb) => 35 | kubernetesObjectResult(`Found banned subject '${subjectName}'`, rb) 36 | ); 37 | 38 | configs.addResults(...results); 39 | } 40 | 41 | validateRolebinding.usage = ` 42 | Disallows RBAC RoleBinding objects with the given subject name. 43 | 44 | Configured using a ConfigMap with the following key: 45 | 46 | ${SUBJECT_NAME}: RoleBinding subjects.name to disallow. 47 | 48 | Example: 49 | 50 | apiVersion: v1 51 | kind: ConfigMap 52 | data: 53 | ${SUBJECT_NAME}: alice 54 | metadata: 55 | name: my-config 56 | `; 57 | -------------------------------------------------------------------------------- /ts/demo-functions/src/validate_rolebinding_run.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { validateRolebinding } from './validate_rolebinding'; 18 | import { run } from 'kpt-functions'; 19 | 20 | run(validateRolebinding); 21 | -------------------------------------------------------------------------------- /ts/demo-functions/src/write_yaml_run.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { writeYaml } from './write_yaml'; 18 | import { run } from 'kpt-functions'; 19 | 20 | run(writeYaml); 21 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/audit/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: viewers 5 | namespace: audit 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: view 10 | subjects: 11 | - apiGroup: rbac.authorization.k8s.io 12 | kind: Group 13 | name: 'system:serviceaccounts:audit' 14 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/clusterrole_namespace-reader.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: namespace-reader 5 | rules: 6 | - apiGroups: 7 | - '' 8 | resources: 9 | - namespaces 10 | verbs: 11 | - get 12 | - watch 13 | - list 14 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/clusterrole_pod-creator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: pod-creator 5 | rules: 6 | - apiGroups: 7 | - '' 8 | resources: 9 | - pods 10 | verbs: 11 | - '*' 12 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/clusterrolebinding_namespace-readers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: namespace-readers 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: namespace-reader 9 | subjects: 10 | - apiGroup: rbac.authorization.k8s.io 11 | kind: User 12 | name: cheryl@foo-corp.com 13 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/customresourcedefinition_fulfillmentcenters.foo-corp.com.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1beta1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: fulfillmentcenters.foo-corp.com 5 | spec: 6 | group: foo-corp.com 7 | names: 8 | kind: FulfillmentCenter 9 | plural: fulfillmentcenters 10 | singular: fulfillmentcenter 11 | scope: Namespaced 12 | validation: 13 | openAPIV3Schema: 14 | properties: 15 | spec: 16 | properties: 17 | address: 18 | type: string 19 | required: 20 | - address 21 | type: object 22 | versions: 23 | - name: v1 24 | served: true 25 | storage: false 26 | - name: v2 27 | served: true 28 | storage: true 29 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/podsecuritypolicy_psp.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1beta1 2 | kind: PodSecurityPolicy 3 | metadata: 4 | name: psp 5 | spec: 6 | fsGroup: 7 | rule: RunAsAny 8 | runAsUser: 9 | rule: RunAsAny 10 | seLinux: 11 | rule: RunAsAny 12 | supplementalGroups: 13 | rule: RunAsAny 14 | volumes: 15 | - '*' 16 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-dev/resourcequota_config-management-resource-quota.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ResourceQuota 3 | metadata: 4 | labels: 5 | nomos-namespace-type: workload 6 | name: config-management-resource-quota 7 | namespace: shipping-dev 8 | spec: 9 | hard: 10 | cpu: 100m 11 | memory: 100Mi 12 | pods: '1' 13 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-dev/rolebinding_job-creators.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: job-creator 5 | namespace: shipping-dev 6 | rules: 7 | - apiGroups: 8 | - batch/v1 9 | resources: 10 | - jobs 11 | verbs: 12 | - '*' 13 | --- 14 | apiVersion: rbac.authorization.k8s.io/v1 15 | kind: RoleBinding 16 | metadata: 17 | name: job-creators 18 | namespace: shipping-dev 19 | roleRef: 20 | apiGroup: rbac.authorization.k8s.io 21 | kind: Role 22 | name: job-creator 23 | subjects: 24 | - apiGroup: rbac.authorization.k8s.io 25 | kind: User 26 | name: sam@foo-corp.com 27 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-dev/rolebinding_pod-creators.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: pod-creators 5 | namespace: shipping-dev 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: pod-creator 10 | subjects: 11 | - apiGroup: rbac.authorization.k8s.io 12 | kind: User 13 | name: bob@foo-corp.com 14 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-dev/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: viewers 5 | namespace: shipping-dev 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: view 10 | subjects: 11 | - apiGroup: rbac.authorization.k8s.io 12 | kind: Group 13 | name: 'system:serviceaccounts:audit' 14 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-prod/fulfillmentcenter_production.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: foo-corp.com/v1 2 | kind: FulfillmentCenter 3 | metadata: 4 | name: production 5 | namespace: shipping-prod 6 | spec: 7 | address: 100 Industry St. 8 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-prod/rolebinding_pod-creators.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: pod-creators 5 | namespace: shipping-prod 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: pod-creator 10 | subjects: 11 | - apiGroup: rbac.authorization.k8s.io 12 | kind: User 13 | name: bob@foo-corp.com 14 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-prod/rolebinding_sre-admin.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: sre-admin 5 | namespace: shipping-prod 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: admin 10 | subjects: 11 | - apiGroup: rbac.authorization.k8s.io 12 | kind: Group 13 | name: sre@foo-corp.com 14 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-prod/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: viewers 5 | namespace: shipping-prod 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: view 10 | subjects: 11 | - apiGroup: rbac.authorization.k8s.io 12 | kind: Group 13 | name: 'system:serviceaccounts:audit' 14 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-staging/fulfillmentcenter_staging.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: foo-corp.com/v1 2 | kind: FulfillmentCenter 3 | metadata: 4 | name: staging 5 | namespace: shipping-staging 6 | spec: 7 | address: 100 Main St. 8 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-staging/rolebinding_pod-creators.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: pod-creators 5 | namespace: shipping-staging 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: pod-creator 10 | subjects: 11 | - apiGroup: rbac.authorization.k8s.io 12 | kind: User 13 | name: bob@foo-corp.com 14 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/sink/foo-yaml/foo-corp-1.0.0/shipping-staging/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: viewers 5 | namespace: shipping-staging 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: view 10 | subjects: 11 | - apiGroup: rbac.authorization.k8s.io 12 | kind: Group 13 | name: 'system:serviceaccounts:audit' 14 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/empty/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/krm-functions-sdk/1126697ce2d12abd3e85d651ab178c9c5ca30847/ts/demo-functions/test-data/source/empty/.empty -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/audit/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: RoleBinding 17 | metadata: 18 | name: viewers 19 | namespace: audit 20 | roleRef: 21 | apiGroup: rbac.authorization.k8s.io 22 | kind: ClusterRole 23 | name: view 24 | subjects: 25 | - apiGroup: rbac.authorization.k8s.io 26 | kind: Group 27 | name: 'system:serviceaccounts:audit' 28 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/clusterrole_namespace-reader.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: ClusterRole 17 | metadata: 18 | name: namespace-reader 19 | rules: 20 | - apiGroups: 21 | - '' 22 | resources: 23 | - namespaces 24 | verbs: 25 | - get 26 | - watch 27 | - list 28 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/clusterrole_pod-creator.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: ClusterRole 17 | metadata: 18 | name: pod-creator 19 | rules: 20 | - apiGroups: 21 | - '' 22 | resources: 23 | - pods 24 | verbs: 25 | - '*' 26 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/clusterrolebinding_namespace-readers.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: ClusterRoleBinding 17 | metadata: 18 | name: namespace-readers 19 | roleRef: 20 | apiGroup: rbac.authorization.k8s.io 21 | kind: ClusterRole 22 | name: namespace-reader 23 | subjects: 24 | - apiGroup: rbac.authorization.k8s.io 25 | kind: User 26 | name: cheryl@foo-corp.com 27 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/customresourcedefinition_fulfillmentcenters.foo-corp.com.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: apiextensions.k8s.io/v1beta1 16 | kind: CustomResourceDefinition 17 | metadata: 18 | name: fulfillmentcenters.foo-corp.com 19 | spec: 20 | group: foo-corp.com 21 | names: 22 | kind: FulfillmentCenter 23 | plural: fulfillmentcenters 24 | singular: fulfillmentcenter 25 | scope: Namespaced 26 | validation: 27 | openAPIV3Schema: 28 | properties: 29 | spec: 30 | properties: 31 | address: 32 | type: string 33 | required: 34 | - address 35 | type: object 36 | versions: 37 | - name: v1 38 | served: true 39 | storage: false 40 | - name: v2 41 | served: true 42 | storage: true 43 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/podsecuritypolicy_psp.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: policy/v1beta1 16 | kind: PodSecurityPolicy 17 | metadata: 18 | name: psp 19 | spec: 20 | fsGroup: 21 | rule: RunAsAny 22 | runAsUser: 23 | rule: RunAsAny 24 | seLinux: 25 | rule: RunAsAny 26 | supplementalGroups: 27 | rule: RunAsAny 28 | volumes: 29 | - '*' 30 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-dev/resourcequota_config-management-resource-quota.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: v1 16 | kind: ResourceQuota 17 | metadata: 18 | labels: 19 | nomos-namespace-type: workload 20 | name: config-management-resource-quota 21 | namespace: shipping-dev 22 | spec: 23 | hard: 24 | cpu: 100m 25 | memory: 100Mi 26 | pods: '1' 27 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-dev/rolebinding_job-creators.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: Role 17 | metadata: 18 | name: job-creator 19 | namespace: shipping-dev 20 | rules: 21 | - apiGroups: 22 | - batch/v1 23 | resources: 24 | - jobs 25 | verbs: 26 | - '*' 27 | --- 28 | apiVersion: rbac.authorization.k8s.io/v1 29 | kind: RoleBinding 30 | metadata: 31 | name: job-creators 32 | namespace: shipping-dev 33 | roleRef: 34 | apiGroup: rbac.authorization.k8s.io 35 | kind: Role 36 | name: job-creator 37 | subjects: 38 | - apiGroup: rbac.authorization.k8s.io 39 | kind: User 40 | name: sam@foo-corp.com 41 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-dev/rolebinding_pod-creators.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: RoleBinding 17 | metadata: 18 | name: pod-creators 19 | namespace: shipping-dev 20 | roleRef: 21 | apiGroup: rbac.authorization.k8s.io 22 | kind: ClusterRole 23 | name: pod-creator 24 | subjects: 25 | - apiGroup: rbac.authorization.k8s.io 26 | kind: User 27 | name: bob@foo-corp.com 28 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-dev/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: RoleBinding 17 | metadata: 18 | name: viewers 19 | namespace: shipping-dev 20 | roleRef: 21 | apiGroup: rbac.authorization.k8s.io 22 | kind: ClusterRole 23 | name: view 24 | subjects: 25 | - apiGroup: rbac.authorization.k8s.io 26 | kind: Group 27 | name: 'system:serviceaccounts:audit' 28 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-prod/fulfillmentcenter_production.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: foo-corp.com/v1 16 | kind: FulfillmentCenter 17 | metadata: 18 | name: production 19 | namespace: shipping-prod 20 | spec: 21 | address: 100 Industry St. 22 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-prod/rolebinding_pod-creators.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: RoleBinding 17 | metadata: 18 | name: pod-creators 19 | namespace: shipping-prod 20 | roleRef: 21 | apiGroup: rbac.authorization.k8s.io 22 | kind: ClusterRole 23 | name: pod-creator 24 | subjects: 25 | - apiGroup: rbac.authorization.k8s.io 26 | kind: User 27 | name: bob@foo-corp.com 28 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-prod/rolebinding_sre-admin.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: RoleBinding 17 | metadata: 18 | name: sre-admin 19 | namespace: shipping-prod 20 | roleRef: 21 | apiGroup: rbac.authorization.k8s.io 22 | kind: ClusterRole 23 | name: admin 24 | subjects: 25 | - apiGroup: rbac.authorization.k8s.io 26 | kind: Group 27 | name: sre@foo-corp.com 28 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-prod/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: RoleBinding 17 | metadata: 18 | name: viewers 19 | namespace: shipping-prod 20 | roleRef: 21 | apiGroup: rbac.authorization.k8s.io 22 | kind: ClusterRole 23 | name: view 24 | subjects: 25 | - apiGroup: rbac.authorization.k8s.io 26 | kind: Group 27 | name: 'system:serviceaccounts:audit' 28 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-staging/fulfillmentcenter_staging.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: foo-corp.com/v1 16 | kind: FulfillmentCenter 17 | metadata: 18 | name: staging 19 | namespace: shipping-staging 20 | spec: 21 | address: 100 Main St. 22 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-staging/rolebinding_pod-creators.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: RoleBinding 17 | metadata: 18 | name: pod-creators 19 | namespace: shipping-staging 20 | roleRef: 21 | apiGroup: rbac.authorization.k8s.io 22 | kind: ClusterRole 23 | name: pod-creator 24 | subjects: 25 | - apiGroup: rbac.authorization.k8s.io 26 | kind: User 27 | name: bob@foo-corp.com 28 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/foo-yaml/foo-corp-1.0.0/shipping-staging/rolebinding_viewers.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: RoleBinding 17 | metadata: 18 | name: viewers 19 | namespace: shipping-staging 20 | roleRef: 21 | apiGroup: rbac.authorization.k8s.io 22 | kind: ClusterRole 23 | name: view 24 | subjects: 25 | - apiGroup: rbac.authorization.k8s.io 26 | kind: Group 27 | name: 'system:serviceaccounts:audit' 28 | -------------------------------------------------------------------------------- /ts/demo-functions/test-data/source/invalid/invalid.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 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 | kind: I don't have apiVersion 16 | -------------------------------------------------------------------------------- /ts/demo-functions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowUnreachableCode": false, 4 | "allowUnusedLabels": false, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "lib": ["es2018"], 9 | "module": "commonjs", 10 | "moduleResolution": "node", 11 | "noEmitOnError": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "noImplicitAny": true, 14 | "noImplicitReturns": true, 15 | "noUnusedLocals": true, 16 | "outDir": "dist", 17 | "pretty": true, 18 | "resolveJsonModule": true, 19 | "rootDir": "src", 20 | "sourceMap": true, 21 | "strict": true, 22 | "target": "es2018" 23 | }, 24 | "exclude": ["node_modules", "dist"], 25 | "include": ["src/**/*"] 26 | } 27 | -------------------------------------------------------------------------------- /ts/hello-world/.dockerignore: -------------------------------------------------------------------------------- 1 | **/dist/ 2 | **/node_modules/ 3 | -------------------------------------------------------------------------------- /ts/hello-world/build/label_namespace.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/label_namespace_run.js"] 34 | -------------------------------------------------------------------------------- /ts/hello-world/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": ".", 3 | "spec_files": ["dist/**/*_test.js"], 4 | "helpers": [ 5 | ], 6 | "stopSpecOnExpectationFailure": false, 7 | "random": true 8 | } 9 | -------------------------------------------------------------------------------- /ts/hello-world/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-world", 3 | "version": "0.1.0", 4 | "scripts": { 5 | "prepare": "npm run build", 6 | "build": "tsc", 7 | "watch": "tsc --watch", 8 | "clean": "rm -Rf node_modules/ dist/", 9 | "pretest": "npm run build", 10 | "test": "jasmine --config=jasmine.json", 11 | "kpt:docker-create": "kpt docker-create", 12 | "kpt:docker-build": "kpt docker-build", 13 | "kpt:docker-push": "kpt docker-push", 14 | "kpt:function-create": "kpt function-create", 15 | "kpt:type-create": "kpt type-create" 16 | }, 17 | "dependencies": { 18 | "kpt-functions": "^0.16.1-rc.0" 19 | }, 20 | "devDependencies": { 21 | "@types/jasmine": "^3.10.7", 22 | "@types/node": "^14.17.18", 23 | "create-kpt-functions": "^0.18.0", 24 | "jasmine": "^3.9.0", 25 | "tslint": "^6.1.3", 26 | "typescript": "^4.4.3" 27 | }, 28 | "kpt": { 29 | "docker_repo_base": "gcr.io/kpt-functions" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ts/hello-world/src/gen/io.k8s.apimachinery.pkg.runtime.ts: -------------------------------------------------------------------------------- 1 | // RawExtension is used to hold extensions in external versions. 2 | // 3 | // To use this, make a field which has RawExtension as its type in your external, versioned struct, and Object in your internal struct. You also need to register your various plugin types. 4 | // 5 | // // Internal package: type MyAPIObject struct { 6 | // runtime.TypeMeta `json:",inline"` 7 | // MyPlugin runtime.Object `json:"myPlugin"` 8 | // } type PluginA struct { 9 | // AOption string `json:"aOption"` 10 | // } 11 | // 12 | // // External package: type MyAPIObject struct { 13 | // runtime.TypeMeta `json:",inline"` 14 | // MyPlugin runtime.RawExtension `json:"myPlugin"` 15 | // } type PluginA struct { 16 | // AOption string `json:"aOption"` 17 | // } 18 | // 19 | // // On the wire, the JSON will look something like this: { 20 | // "kind":"MyAPIObject", 21 | // "apiVersion":"v1", 22 | // "myPlugin": { 23 | // "kind":"PluginA", 24 | // "aOption":"foo", 25 | // }, 26 | // } 27 | // 28 | // So what happens? Decode first uses json or yaml to unmarshal the serialized data into your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked. The next step is to copy (using pkg/conversion) into the internal struct. The runtime package's DefaultScheme has conversion functions installed which will unpack the JSON stored in RawExtension, turning it into the correct object type, and storing it in the Object. (TODO: In the case where the object is of an unknown type, a runtime.Unknown object will be created and stored.) 29 | export class RawExtension { 30 | // Raw is the underlying serialization of this object. 31 | public Raw: string; 32 | 33 | constructor(desc: RawExtension) { 34 | this.Raw = desc.Raw; 35 | } 36 | } -------------------------------------------------------------------------------- /ts/hello-world/src/gen/io.k8s.apimachinery.pkg.util.intstr.ts: -------------------------------------------------------------------------------- 1 | // IntOrString is a type that can hold an int32 or a string. When used in JSON or YAML marshalling and unmarshalling, it produces or consumes the inner type. This allows you to have, for example, a JSON field that can accept a name or number. 2 | export type IntOrString = string; -------------------------------------------------------------------------------- /ts/hello-world/src/gen/io.k8s.apimachinery.pkg.version.ts: -------------------------------------------------------------------------------- 1 | // Info contains versioning information. how we'll want to distribute that information. 2 | export class Info { 3 | public buildDate: string; 4 | 5 | public compiler: string; 6 | 7 | public gitCommit: string; 8 | 9 | public gitTreeState: string; 10 | 11 | public gitVersion: string; 12 | 13 | public goVersion: string; 14 | 15 | public major: string; 16 | 17 | public minor: string; 18 | 19 | public platform: string; 20 | 21 | constructor(desc: Info) { 22 | this.buildDate = desc.buildDate; 23 | this.compiler = desc.compiler; 24 | this.gitCommit = desc.gitCommit; 25 | this.gitTreeState = desc.gitTreeState; 26 | this.gitVersion = desc.gitVersion; 27 | this.goVersion = desc.goVersion; 28 | this.major = desc.major; 29 | this.minor = desc.minor; 30 | this.platform = desc.platform; 31 | } 32 | } -------------------------------------------------------------------------------- /ts/hello-world/src/label_namespace.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { addLabel, Configs } from 'kpt-functions'; 18 | import { isNamespace } from './gen/io.k8s.api.core.v1'; 19 | 20 | export const LABEL_NAME = 'label_name'; 21 | export const LABEL_VALUE = 'label_value'; 22 | 23 | export async function labelNamespace(configs: Configs) { 24 | const labelName = configs.getFunctionConfigValueOrThrow(LABEL_NAME); 25 | const labelValue = configs.getFunctionConfigValueOrThrow(LABEL_VALUE); 26 | configs.get(isNamespace).forEach(n => addLabel(n, labelName, labelValue)); 27 | } 28 | 29 | labelNamespace.usage = ` 30 | Adds a label to all Namespaces. 31 | 32 | Configured using a ConfigMap with the following keys: 33 | 34 | ${LABEL_NAME}: Label name to add to Namespaces. 35 | ${LABEL_VALUE}: Label value to add to Namespaces. 36 | 37 | Example: 38 | 39 | To add a label 'color: orange' to Namespaces: 40 | 41 | apiVersion: v1 42 | kind: ConfigMap 43 | data: 44 | ${LABEL_NAME}: color 45 | ${LABEL_VALUE}: orange 46 | metadata: 47 | name: my-config 48 | `; 49 | -------------------------------------------------------------------------------- /ts/hello-world/src/label_namespace_run.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { labelNamespace } from './label_namespace'; 18 | import { run } from 'kpt-functions'; 19 | 20 | run(labelNamespace); 21 | -------------------------------------------------------------------------------- /ts/hello-world/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "resolveJsonModule": true, 6 | "esModuleInterop": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noUnusedLocals": true, 10 | "noImplicitAny": true, 11 | "noImplicitReturns": true, 12 | "moduleResolution": "node", 13 | "sourceMap": true, 14 | "outDir": "dist", 15 | "lib": [ 16 | "es2015" 17 | ], 18 | "rootDir": "src/" 19 | }, 20 | "exclude": [ 21 | "node_modules", 22 | "dist" 23 | ], 24 | "include": [ 25 | "src/**/*" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /ts/init-package/.dockerignore: -------------------------------------------------------------------------------- 1 | **/dist/ 2 | **/node_modules/ 3 | -------------------------------------------------------------------------------- /ts/init-package/build/my_func.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | RUN mkdir -p /home/node/app && \ 4 | chown -R node:node /home/node/app 5 | 6 | USER node 7 | 8 | WORKDIR /home/node/app 9 | 10 | # Install dependencies and cache them. 11 | COPY --chown=node:node package*.json ./ 12 | RUN npm ci --ignore-scripts 13 | 14 | # Build the source. 15 | COPY --chown=node:node tsconfig.json . 16 | COPY --chown=node:node src src 17 | RUN npm run build && \ 18 | npm prune --production && \ 19 | rm -r src tsconfig.json 20 | 21 | ############################################# 22 | 23 | FROM node:lts-alpine 24 | 25 | # Run as non-root user as a best-practices: 26 | # https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md 27 | USER node 28 | 29 | WORKDIR /home/node/app 30 | 31 | COPY --from=builder /home/node/app /home/node/app 32 | 33 | ENTRYPOINT ["node", "/home/node/app/dist/my_func_run.js"] 34 | -------------------------------------------------------------------------------- /ts/init-package/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": ".", 3 | "spec_files": ["dist/**/*_test.js"], 4 | "helpers": [ 5 | ], 6 | "stopSpecOnExpectationFailure": false, 7 | "random": true 8 | } 9 | -------------------------------------------------------------------------------- /ts/init-package/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "init-package", 3 | "version": "0.1.0", 4 | "scripts": { 5 | "prepare": "npm run build", 6 | "build": "tsc", 7 | "watch": "tsc --watch", 8 | "clean": "rm -Rf node_modules/ dist/", 9 | "pretest": "npm run build", 10 | "test": "jasmine --config=jasmine.json", 11 | "kpt:docker-create": "kpt docker-create", 12 | "kpt:docker-build": "kpt docker-build", 13 | "kpt:docker-push": "kpt docker-push", 14 | "kpt:function-create": "kpt function-create", 15 | "kpt:type-create": "kpt type-create" 16 | }, 17 | "dependencies": { 18 | "kpt-functions": "^0.16.1-rc.0" 19 | }, 20 | "devDependencies": { 21 | "@types/jasmine": "^3.7.6", 22 | "@types/node": "^14.17.1", 23 | "create-kpt-functions": "^0.18.0", 24 | "jasmine": "^3.9.0", 25 | "tslint": "^6.1.3", 26 | "typescript": "^4.4.2" 27 | }, 28 | "kpt": { 29 | "docker_repo_base": "gcr.io/kpt-functions-demo" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ts/init-package/src/gen/io.k8s.apimachinery.pkg.runtime.ts: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * CODE GENERATED BY 'typgen' BINARY. 4 | * 5 | * DO NOT EDIT. 6 | */ 7 | 8 | // RawExtension is used to hold extensions in external versions. 9 | // 10 | // To use this, make a field which has RawExtension as its type in your external, versioned struct, and Object in your internal struct. You also need to register your various plugin types. 11 | // 12 | // // Internal package: type MyAPIObject struct { 13 | // runtime.TypeMeta `json:",inline"` 14 | // MyPlugin runtime.Object `json:"myPlugin"` 15 | // } type PluginA struct { 16 | // AOption string `json:"aOption"` 17 | // } 18 | // 19 | // // External package: type MyAPIObject struct { 20 | // runtime.TypeMeta `json:",inline"` 21 | // MyPlugin runtime.RawExtension `json:"myPlugin"` 22 | // } type PluginA struct { 23 | // AOption string `json:"aOption"` 24 | // } 25 | // 26 | // // On the wire, the JSON will look something like this: { 27 | // "kind":"MyAPIObject", 28 | // "apiVersion":"v1", 29 | // "myPlugin": { 30 | // "kind":"PluginA", 31 | // "aOption":"foo", 32 | // }, 33 | // } 34 | // 35 | // So what happens? Decode first uses json or yaml to unmarshal the serialized data into your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked. The next step is to copy (using pkg/conversion) into the internal struct. The runtime package's DefaultScheme has conversion functions installed which will unpack the JSON stored in RawExtension, turning it into the correct object type, and storing it in the Object. (TODO: In the case where the object is of an unknown type, a runtime.Unknown object will be created and stored.) 36 | export type RawExtension = object; -------------------------------------------------------------------------------- /ts/init-package/src/gen/io.k8s.apimachinery.pkg.util.intstr.ts: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * CODE GENERATED BY 'typgen' BINARY. 4 | * 5 | * DO NOT EDIT. 6 | */ 7 | 8 | // IntOrString is a type that can hold an int32 or a string. When used in JSON or YAML marshalling and unmarshalling, it produces or consumes the inner type. This allows you to have, for example, a JSON field that can accept a name or number. 9 | export type IntOrString = string; -------------------------------------------------------------------------------- /ts/init-package/src/gen/io.k8s.apimachinery.pkg.version.ts: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * CODE GENERATED BY 'typgen' BINARY. 4 | * 5 | * DO NOT EDIT. 6 | */ 7 | 8 | // Info contains versioning information. how we'll want to distribute that information. 9 | export class Info { 10 | public buildDate: string; 11 | 12 | public compiler: string; 13 | 14 | public gitCommit: string; 15 | 16 | public gitTreeState: string; 17 | 18 | public gitVersion: string; 19 | 20 | public goVersion: string; 21 | 22 | public major: string; 23 | 24 | public minor: string; 25 | 26 | public platform: string; 27 | 28 | constructor(desc: Info) { 29 | this.buildDate = desc.buildDate; 30 | this.compiler = desc.compiler; 31 | this.gitCommit = desc.gitCommit; 32 | this.gitTreeState = desc.gitTreeState; 33 | this.gitVersion = desc.gitVersion; 34 | this.goVersion = desc.goVersion; 35 | this.major = desc.major; 36 | this.minor = desc.minor; 37 | this.platform = desc.platform; 38 | } 39 | } -------------------------------------------------------------------------------- /ts/init-package/src/my_func.ts: -------------------------------------------------------------------------------- 1 | import { Configs } from 'kpt-functions'; 2 | 3 | export async function myFunc(configs: Configs) { 4 | // TODO: implement. 5 | } 6 | 7 | myFunc.usage = ` 8 | TODO: fill the following usage template. 9 | 10 | Overview 11 | Explain what this function does in one or two sentences. 12 | 13 | Synopsis 14 | Explain the function config and behavior for this function in detail. If the 15 | function supports both ConfigMap and CRD as function config, both should be 16 | documented. 17 | 18 | Examples 19 | Use examples to demonstrate how to use this function in different scenarios. 20 | Each example should have input, exact command to run and output. 21 | `; 22 | -------------------------------------------------------------------------------- /ts/init-package/src/my_func_run.ts: -------------------------------------------------------------------------------- 1 | import { myFunc } from './my_func'; 2 | import { run } from 'kpt-functions'; 3 | 4 | run(myFunc); 5 | -------------------------------------------------------------------------------- /ts/init-package/src/my_func_test.ts: -------------------------------------------------------------------------------- 1 | import { Configs, TestRunner } from 'kpt-functions'; 2 | import { myFunc } from './my_func'; 3 | 4 | const RUNNER = new TestRunner(myFunc); 5 | 6 | describe('myFunc', () => { 7 | it('does something', async () => { 8 | // TODO: Populate the input to the function. 9 | const input = new Configs(); 10 | 11 | // TODO: Populate the expected output of the function. 12 | const expectedOutput = new Configs(); 13 | 14 | await RUNNER.assert(input, expectedOutput); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /ts/init-package/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "resolveJsonModule": true, 6 | "esModuleInterop": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noUnusedLocals": true, 10 | "noImplicitAny": true, 11 | "noImplicitReturns": true, 12 | "moduleResolution": "node", 13 | "sourceMap": true, 14 | "outDir": "dist", 15 | "lib": [ 16 | "es2015" 17 | ], 18 | "rootDir": "src/" 19 | }, 20 | "exclude": [ 21 | "node_modules", 22 | "dist" 23 | ], 24 | "include": [ 25 | "src/**/*" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /ts/kpt-functions/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /ts/kpt-functions/@types/rw/index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Package rw does not have type definitions. 18 | declare module 'rw' { 19 | var rw: any; 20 | export default rw; 21 | } -------------------------------------------------------------------------------- /ts/kpt-functions/@types/rw/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@types/rw", 3 | "version": "1.3.3", 4 | "license": "Apache-2.0" 5 | } 6 | -------------------------------------------------------------------------------- /ts/kpt-functions/README.md: -------------------------------------------------------------------------------- 1 | # kpt Functions SDK Library 2 | 3 | Documentation: 4 | 5 | https://kpt.dev/book/05-developing-functions/03-developing-in-Typescript 6 | -------------------------------------------------------------------------------- /ts/kpt-functions/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export * from './src/errors'; 18 | export * from './src/io'; 19 | export * from './src/metadata'; 20 | export * from './src/result'; 21 | export * from './src/run'; 22 | export * from './src/testing'; 23 | export * from './src/types'; 24 | -------------------------------------------------------------------------------- /ts/kpt-functions/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": ".", 3 | "spec_files": ["dist/**/*_test.js"], 4 | "helpers": [], 5 | "stopSpecOnExpectationFailure": false, 6 | "random": true 7 | } 8 | -------------------------------------------------------------------------------- /ts/kpt-functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kpt-functions", 3 | "version": "0.16.1", 4 | "description": "kpt functions framework library", 5 | "author": "kpt Authors", 6 | "license": "Apache-2.0", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/GoogleContainerTools/kpt-functions-sdk.git", 10 | "directory": "ts/kpt-functions" 11 | }, 12 | "main": "dist/index.js", 13 | "types": "dist/index.d.ts", 14 | "files": [ 15 | "dist/", 16 | "!**/*_test.*" 17 | ], 18 | "scripts": { 19 | "prepare": "npm run build", 20 | "build": "tsc", 21 | "watch": "tsc --watch", 22 | "clean": "rm -Rf dist/ node_modules/", 23 | "lint": "tslint -p package.json && prettier \"src/**\" \"*.json\" --check", 24 | "lint-license": "license-checker --onlyAllow 'Apache-2.0;MIT;BSD;BSD-2-Clause;BSD-3-Clause;ISC;CC-BY-3.0;CC0-1.0;Python-2.0;Unlicense'", 25 | "format": "prettier \"src/**\" \"*.json\" --write", 26 | "pretest": "npm run build", 27 | "test": "jasmine --config=jasmine.json", 28 | "posttest": "npm run lint", 29 | "gen-docs": "typedoc --tsconfig tsconfig.json" 30 | }, 31 | "dependencies": { 32 | "argparse": "^1.0.10", 33 | "js-yaml": "^3.14.1", 34 | "rw": "^1.3.3" 35 | }, 36 | "devDependencies": { 37 | "@types/argparse": "^1.0.36", 38 | "@types/jasmine": "^3.10.4", 39 | "@types/js-yaml": "^3.12.5", 40 | "@types/lodash": "^4.14.180", 41 | "@types/node": "^12.20.43", 42 | "@types/rw": "file:@types/rw", 43 | "jasmine": "^3.9.0", 44 | "license-checker": "^25.0.1", 45 | "lodash": "^4.17.20", 46 | "path-parse": "^1.0.7", 47 | "prettier": "2.6.0", 48 | "tslint": "^6.1.3", 49 | "tslint-config-prettier": "1.18.0", 50 | "tslint-consistent-codestyle": "^1.16.0", 51 | "typedoc": "^0.22.17", 52 | "typescript": "^4.4.4" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ts/kpt-functions/src/errors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Represents an error with the functionConfig used to parametrize the function. 19 | */ 20 | export class FunctionConfigError extends Error { 21 | constructor(message: string) { 22 | super(message); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ts/kpt-functions/src/gen/io.k8s.apimachinery.pkg.util.intstr.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // IntOrString is a type that can hold an int32 or a string. When used in JSON or YAML marshalling and unmarshalling, it produces or consumes the inner type. This allows you to have, for example, a JSON field that can accept a name or number. 18 | export type IntOrString = string; 19 | -------------------------------------------------------------------------------- /ts/kpt-functions/src/gen/io.k8s.apimachinery.pkg.version.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Info contains versioning information. how we'll want to distribute that information. 18 | export class Info { 19 | public buildDate: string; 20 | 21 | public compiler: string; 22 | 23 | public gitCommit: string; 24 | 25 | public gitTreeState: string; 26 | 27 | public gitVersion: string; 28 | 29 | public goVersion: string; 30 | 31 | public major: string; 32 | 33 | public minor: string; 34 | 35 | public platform: string; 36 | 37 | constructor(desc: Info) { 38 | this.buildDate = desc.buildDate; 39 | this.compiler = desc.compiler; 40 | this.gitCommit = desc.gitCommit; 41 | this.gitTreeState = desc.gitTreeState; 42 | this.gitVersion = desc.gitVersion; 43 | this.goVersion = desc.goVersion; 44 | this.major = desc.major; 45 | this.minor = desc.minor; 46 | this.platform = desc.platform; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ts/kpt-functions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowUnreachableCode": false, 4 | "allowUnusedLabels": false, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "lib": ["es2018"], 9 | "module": "commonjs", 10 | "moduleResolution": "node", 11 | "noEmitOnError": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "noImplicitAny": true, 14 | "noImplicitReturns": true, 15 | "noUnusedLocals": true, 16 | "outDir": "dist", 17 | "pretty": true, 18 | "resolveJsonModule": true, 19 | "rootDir": ".", 20 | "sourceMap": true, 21 | "strict": true, 22 | "target": "es2018" 23 | }, 24 | "exclude": ["node_modules", "dist"], 25 | "include": ["index.ts", "src/**/*"] 26 | } 27 | -------------------------------------------------------------------------------- /ts/kpt-functions/typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "entryPoints": ["index.ts"], 3 | "out": "../../docs/api", 4 | "readme": "none", 5 | "exclude": ["src/**/*_test.ts", "src/io.ts", "src/gen/**"], 6 | "excludePrivate": true, 7 | "excludeExternals": true 8 | } 9 | -------------------------------------------------------------------------------- /ts/scripts/demo/demo-magic/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [*.mdown] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /ts/scripts/demo/demo-magic/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | -------------------------------------------------------------------------------- /ts/scripts/demo/demo-magic/license.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Paxton Hare 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ts/scripts/demo/demo-magic/samples/demo-template.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | ######################## 18 | # include the magic 19 | ######################## 20 | . ../demo-magic.sh 21 | 22 | 23 | ######################## 24 | # Configure the options 25 | ######################## 26 | 27 | # 28 | # speed at which to simulate typing. bigger num = faster 29 | # 30 | # TYPE_SPEED=20 31 | 32 | # 33 | # custom prompt 34 | # 35 | # see http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/bash-prompt-escape-sequences.html for escape sequences 36 | # 37 | DEMO_PROMPT="${GREEN}➜ ${CYAN}\W " 38 | 39 | # hide the evidence 40 | clear 41 | 42 | 43 | # put your demo awesomeness here 44 | if [ ! -d "stuff" ]; then 45 | pe "mkdir stuff" 46 | fi 47 | 48 | pe "cd stuff" 49 | 50 | pe "ls" 51 | 52 | p "cat \"something you dont want to really run\"" 53 | 54 | # show a prompt so as not to reveal our true nature after 55 | # the demo has concluded 56 | p "" 57 | -------------------------------------------------------------------------------- /ts/scripts/gen-api-docs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Usage ex: 17 | # $ gen-docs.sh 18 | 19 | set -euo pipefail 20 | 21 | ( 22 | cd ts/kpt-functions 23 | npm run gen-docs 24 | ) 25 | git add docs/api 26 | git commit -m "Generate API docs" 27 | -------------------------------------------------------------------------------- /ts/scripts/init-package.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | set -euo pipefail 18 | 19 | PKG=init-package 20 | 21 | # Fail if kind cluster generate-init-pkg already exists. 22 | if kind get clusters | grep -w "generate-init-pkg" 23 | then 24 | echo "Kind cluster generate-init-pkg already exists." 25 | echo "Delete the cluster with:" 26 | echo "kind delete cluster --name=generate-init-pkg" 27 | else 28 | # Use images from https://hub.docker.com/r/kindest/node/tags 29 | kind create cluster --name=generate-init-pkg --image=kindest/node:v1.21.2 30 | sleep 10 # Wait for cluster to become fully available. Potentially flaky. 31 | fi 32 | 33 | cd ts 34 | rm -rf $PKG 35 | mkdir $PKG 36 | cd $PKG 37 | npm init kpt-functions 38 | -------------------------------------------------------------------------------- /ts/scripts/mirrorImages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | declare -A imagearray=() 6 | imagearray["gcr.io/kpt-functions/read-yaml"]="gcr.io/config-management-release/read-yaml" 7 | imagearray["gcr.io/kpt-functions/write-yaml"]="gcr.io/config-management-release/write-yaml" 8 | imagearray["gcr.io/kpt-functions/gatekeeper-validate"]="gcr.io/kpt-functions/gatekeeper-validate" 9 | imagearray["gcr.io/kpt-functions/gatekeeper-validate"]="gcr.io/config-management-release/policy-controller-validate" 10 | imagearray["gcr.io/kpt-dev/kpt"]="gcr.io/config-management-release/kpt" 11 | imagearray["gcr.io/kpt-functions/helm-template"]="gcr.io/kpt-functions/helm-template" 12 | imagearray["gcr.io/kpt-functions/helm-template"]="gcr.io/config-management-release/helm-template" 13 | imagearray["gcr.io/kpt-functions/kubeval"]="gcr.io/kpt-functions/kubeval" 14 | imagearray["gcr.io/kpt-functions/kubeval"]="gcr.io/config-management-release/kubeval" 15 | imagearray["gcr.io/kpt-functions/istioctl-analyze"]="gcr.io/kpt-functions/istioctl-analyze" 16 | imagearray["gcr.io/kpt-functions/istioctl-analyze"]="gcr.io/config-management-release/istioctl-analyze" 17 | 18 | for image in "${!imagearray[@]}"; do 19 | docker pull ${image} 20 | docker tag ${image} ${imagearray[$image]}:latest 21 | docker tag ${image} ${imagearray[$image]}:stable 22 | docker push ${imagearray[$image]}:latest 23 | docker push ${imagearray[$image]}:stable 24 | done 25 | -------------------------------------------------------------------------------- /ts/scripts/publish-bins.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Usage ex: 17 | # $ publish-bins.sh release-typegen-v0.13.0 18 | 19 | set -xeuo pipefail 20 | 21 | VERSION=${1#*-v}; 22 | 23 | cd ts/typegen/.out 24 | gsutil cp -- *.tar.gz gs://kpt-functions/v"${VERSION}" 25 | -------------------------------------------------------------------------------- /ts/scripts/publish-npm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Usage ex: 17 | # $ publish-npm.sh release-ts-kpt-functions-v0.13.0-rc.1 18 | 19 | set -euo pipefail 20 | 21 | 22 | TAG_VERSION=${1#*-v}; 23 | echo "tag version: $TAG_VERSION" 24 | 25 | PACKAGE_VERSION=$(node -p "require('./package.json').version") 26 | echo "package version: $PACKAGE_VERSION" 27 | 28 | if [[ "$PACKAGE_VERSION" != "$TAG_VERSION" ]]; then 29 | echo "package version does not match the tag" 30 | exit 1 31 | fi 32 | 33 | 34 | if [[ "$PACKAGE_VERSION" == *"rc"* ]]; then 35 | npm publish --tag rc 36 | else 37 | npm publish 38 | fi 39 | -------------------------------------------------------------------------------- /ts/scripts/version-kpt-functions-sdk-deps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Usage ex: 17 | # version-kpt-functions-sdk-deps.sh 0.13.0.-rc.1 18 | 19 | set -euo pipefail 20 | 21 | 22 | TAG_VERSION=${1}; 23 | 24 | 25 | PACKAGES=( demo-functions hello-world init-package) 26 | for p in "${PACKAGES[@]}" 27 | do 28 | pushd . 29 | cd "ts/${p}" 30 | npm install "kpt-functions@${TAG_VERSION}" 31 | git add package.json package-lock.json 32 | popd 33 | done 34 | 35 | git commit -m "Update deps to use kpt-functions@${TAG_VERSION}" -------------------------------------------------------------------------------- /ts/scripts/version-kpt-functions-sdk.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Usage: 17 | # $ version-kpt-functions-sdk.sh 0.13.0-rc.1 18 | 19 | set -euo pipefail 20 | 21 | TAG_VERSION=${1}; 22 | 23 | cd ts/kpt-functions 24 | npm --no-git-tag-version version "${TAG_VERSION}" 25 | git add package.json package-lock.json 26 | git commit -m "kpt-functions@${TAG_VERSION}" 27 | -------------------------------------------------------------------------------- /ts/typegen/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: fix vet fmt test lint 2 | 3 | GOPATH := $(shell go env GOPATH) 4 | GOBIN := $(shell go env GOPATH)/bin 5 | OUT_DIR := .out 6 | MODULES = $(shell find . -name 'go.mod' -print) 7 | 8 | all: fix fmt lint test 9 | 10 | .PHONY: fix 11 | fix: $(MODULES) 12 | @for f in $(^D); do (cd $$f; echo "Fixing $$f"; go fix ./...) || exit 1; done 13 | 14 | .PHONY: fmt 15 | fmt: $(MODULES) 16 | @for f in $(^D); do (cd $$f; echo "Formatting $$f"; gofmt -s -w .); done 17 | 18 | .PHONY: lint 19 | lint: $(MODULES) 20 | @for f in $(^D); do \ 21 | (cd $$f; echo "Checking golangci-lint $$f"; \ 22 | (which $(GOPATH)/bin/golangci-lint || go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.51.2); \ 23 | $(GOPATH)/bin/golangci-lint run ./...); \ 24 | done 25 | 26 | .PHONY: test 27 | test: $(MODULES) 28 | @for f in $(^D); do (cd $$f; echo "Testing $$f"; go test ./...) || exit 1; done 29 | 30 | .PHONY: vet 31 | vet: $(MODULES) 32 | @#for f in $(^D); do (cd $$f; echo "Checking $$f"; go run honnef.co/go/tools/cmd/staticcheck@latest ./...); done 33 | @for f in $(^D); do (cd $$f; echo "Vetting $$f"; go vet ./...); done 34 | 35 | build-typegen: fix fmt test lint 36 | env GOOS=linux GOARCH=amd64 go build -o $(OUT_DIR)/linux/amd64/typegen ./cmd 37 | env GOOS=darwin GOARCH=amd64 go build -o $(OUT_DIR)/darwin/amd64/typegen ./cmd 38 | env GOOS=windows GOARCH=amd64 go build -o $(OUT_DIR)/windows/amd64/typegen ./cmd 39 | env GOOS=linux GOARCH=arm64 go build -o $(OUT_DIR)/linux/arm64/typegen ./cmd 40 | env GOOS=darwin GOARCH=arm64 go build -o $(OUT_DIR)/darwin/arm64/typegen ./cmd 41 | env GOOS=windows GOARCH=arm64 go build -o $(OUT_DIR)/windows/arm64/typegen ./cmd 42 | 43 | package-typegen: build-typegen 44 | tar -C $(OUT_DIR)/linux/amd64 -czvf $(OUT_DIR)/typegen_linux_amd64.tar.gz typegen 45 | tar -C $(OUT_DIR)/darwin/amd64 -czvf $(OUT_DIR)/typegen_darwin_amd64.tar.gz typegen 46 | tar -C $(OUT_DIR)/windows/amd64 -czvf $(OUT_DIR)/typegen_windows_amd64.tar.gz typegen 47 | tar -C $(OUT_DIR)/linux/arm64 -czvf $(OUT_DIR)/typegen_linux_arm64.tar.gz typegen 48 | tar -C $(OUT_DIR)/darwin/arm64 -czvf $(OUT_DIR)/typegen_darwin_arm64.tar.gz typegen 49 | tar -C $(OUT_DIR)/windows/arm64 -czvf $(OUT_DIR)/typegen_windows_arm64.tar.gz typegen 50 | -------------------------------------------------------------------------------- /ts/typegen/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/GoogleContainerTools/kpt-functions-sdk/ts/typegen 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/google/go-cmp v0.5.8 7 | github.com/pkg/errors v0.9.1 8 | github.com/spf13/cobra v1.4.0 9 | ) 10 | 11 | require ( 12 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 13 | github.com/spf13/pflag v1.0.5 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /ts/typegen/go.sum: -------------------------------------------------------------------------------- 1 | github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 2 | github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= 3 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 4 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 5 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 6 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 7 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 8 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 9 | github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= 10 | github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= 11 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 12 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 13 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 14 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 15 | -------------------------------------------------------------------------------- /ts/typegen/swagger/alias.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package swagger 16 | 17 | // Alias represents a trivial type that doesn't need a full object definition, such as a Reference or a Primitive. 18 | type Alias struct { 19 | DefinitionMeta 20 | Type Type 21 | } 22 | 23 | // Meta implements Definition. 24 | func (a Alias) Meta() DefinitionMeta { 25 | return a.DefinitionMeta 26 | } 27 | 28 | // Imports implements Definition. 29 | func (a Alias) Imports() []Ref { 30 | if ref, isRef := a.Type.(Ref); isRef { 31 | return []Ref{ref} 32 | } 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /ts/typegen/swagger/definition.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package swagger 16 | 17 | import "fmt" 18 | 19 | // Definition corresponds to a specific type in a swagger.json file. This includes all types in the "definitions" map 20 | // as well as any nested types. 21 | type Definition interface { 22 | // Meta returns the metadata for this Definition. 23 | Meta() DefinitionMeta 24 | // Imports are the imports required to use this Definition. 25 | Imports() []Ref 26 | } 27 | 28 | // DefinitionMeta holds metadata common to all definitions. 29 | type DefinitionMeta struct { 30 | // Name is the name of the definition being declared. 31 | Name string 32 | // Package is the APIVersion containing this definition. 33 | Package string 34 | // Namespace marks nested definitions which should be contained by their outer definition if the language allows it. 35 | Namespace []string 36 | // Description is the human-readable textual comment describing this definition. 37 | Description string 38 | } 39 | 40 | func (d DefinitionMeta) ToRef() Ref { 41 | return Ref{ 42 | Name: d.Name, 43 | Package: d.Package, 44 | } 45 | } 46 | 47 | // FullName implements Definition. 48 | func FullName(d Definition) string { 49 | return fmt.Sprintf("%s.%s", d.Meta().Package, d.Meta().Name) 50 | } 51 | -------------------------------------------------------------------------------- /ts/typegen/swagger/empty.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package swagger 16 | 17 | // Empty represents a type for which we have no type information. 18 | type Empty struct{} 19 | 20 | var _ Type = Empty{} 21 | 22 | // Imports implements Type. 23 | func (Empty) Imports() []Ref { 24 | return nil 25 | } 26 | 27 | // NestedTypes implements Type. 28 | func (Empty) NestedTypes() []Object { 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /ts/typegen/swagger/language/languages.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package language 16 | 17 | import "github.com/GoogleContainerTools/kpt-functions-sdk/ts/typegen/swagger" 18 | 19 | // Language implements the minimum required to print client code for a Definition in a particular programming language. 20 | // 21 | // Implementors of Language must satisfy the following properties: 22 | // 23 | // 1) The order Definitions are printed in a file MUST have no impact on whether code compiles/works. 24 | type Language interface { 25 | // File returns the relative path to definition's client code. 26 | File(definition swagger.Definition) string 27 | 28 | // PrintHeaderComment prints the top-level comment block. 29 | PrintHeaderComment() string 30 | 31 | // PrintHeader prints everything appearing before any Definitions, such as import statements. 32 | // 33 | // definitions is the set of Definitions to be printed in the current file. 34 | PrintHeader(definitions []swagger.Definition) string 35 | 36 | // PrintDefinition prints a single definition. 37 | PrintDefinition(definition swagger.Definition) string 38 | } 39 | -------------------------------------------------------------------------------- /ts/typegen/swagger/map.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package swagger 16 | 17 | // Map is a map from strings to any Type. 18 | // 19 | // Corresponds to swagger's Free-Form Object with "additionalProperties" but no "properties" defined. 20 | type Map struct { 21 | // Values is the type of Values in the map. Defined in the "additionalProperties" field. 22 | Values Type 23 | } 24 | 25 | var _ Type = Map{} 26 | 27 | func (p parser) newMap(meta DefinitionMeta, o map[string]interface{}) Map { 28 | additionalPropertiesMap := getRequiredMap("additionalProperties", o) 29 | // TODO(b/141928662): Handle map of nested type. Uncommon case. 30 | if isObject(additionalPropertiesMap) { 31 | return Map{ 32 | Values: Empty{}, 33 | } 34 | } 35 | return Map{ 36 | Values: p.parseType(meta, additionalPropertiesMap), 37 | } 38 | } 39 | 40 | // Imports implements Type. 41 | func (m Map) Imports() []Ref { 42 | return m.Values.Imports() 43 | } 44 | 45 | // NestedTypes implements Type. 46 | func (Map) NestedTypes() []Object { 47 | // Will change once we support maps of nested type. 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /ts/typegen/swagger/refs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package swagger 16 | 17 | import ( 18 | "fmt" 19 | "strings" 20 | ) 21 | 22 | // Ref references another type which has already been defined. 23 | // Defined in "$ref" 24 | type Ref struct { 25 | Package string 26 | Name string 27 | } 28 | 29 | // GroupVersionKind holds the Kubernetes GroupVersionKind. 30 | type GroupVersionKind struct { 31 | Group string 32 | Version string 33 | Kind string 34 | } 35 | 36 | // APIVersion returns the formatted APIVersion. 37 | func (gvk GroupVersionKind) APIVersion() string { 38 | if gvk.Group == "" { 39 | return gvk.Version 40 | } 41 | return fmt.Sprintf("%s/%s", gvk.Group, gvk.Version) 42 | } 43 | 44 | var _ Type = Ref{} 45 | 46 | func newRef(r map[string]interface{}) Ref { 47 | ref := getRequiredString("$ref", r) 48 | 49 | if !strings.HasPrefix(ref, "#/definitions/") { 50 | panic(fmt.Sprintf("invalid $ref, must begin with '#/definitions/': %s", r)) 51 | } 52 | i := strings.LastIndex(ref, ".") 53 | 54 | return Ref{ 55 | Package: ref[14:i], 56 | Name: ref[i+1:], 57 | } 58 | } 59 | 60 | // Imports implements Type. 61 | func (r Ref) Imports() []Ref { 62 | return []Ref{r} 63 | } 64 | 65 | // NestedTypes implements Type. 66 | func (Ref) NestedTypes() []Object { 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /ts/typegen/swagger/swagger.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package swagger 16 | 17 | import "sort" 18 | 19 | // ParseSwagger parses a Swagger map into an array of Definitions. 20 | // 21 | // Returns Definitions are sorted by fully-qualified name and amap from all References to Definitions to the Definitions. 22 | func ParseSwagger(swagger map[string]interface{}) ([]Definition, map[Ref]Object) { 23 | definitions := getRequiredMap("definitions", swagger) 24 | var result []Definition 25 | p := newParser() 26 | for name := range definitions { 27 | definition := getRequiredMap(name, definitions) 28 | result = append(result, p.parseDefinition(name, definition)) 29 | } 30 | sort.Slice(result, func(i, j int) bool { 31 | return FullName(result[i]) < FullName(result[j]) 32 | }) 33 | return result, p.RefObjects 34 | } 35 | -------------------------------------------------------------------------------- /ts/typegen/swagger/swagger_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 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 | package swagger 16 | 17 | import ( 18 | "encoding/json" 19 | "os" 20 | "testing" 21 | ) 22 | 23 | func TestSwagger(t *testing.T) { 24 | // Ensures real Swagger definitions are actually parseable. Will be updated as type generation is made more 25 | // sophisticated. 26 | testCases := map[string]struct { 27 | name string 28 | path string 29 | }{ 30 | "k8s 1.13.0": { 31 | path: "testdata/swagger-v1.13.0.json", 32 | }, 33 | "k8s 1.14.3": { 34 | path: "testdata/swagger-v1.14.3.json", 35 | }, 36 | "two arrays in the same spec": { 37 | path: "testdata/two-arrays-swagger.json", 38 | }, 39 | } 40 | 41 | for tn := range testCases { 42 | tc := testCases[tn] 43 | t.Run(tn, func(t *testing.T) { 44 | bytes, err := os.ReadFile(tc.path) 45 | if err != nil { 46 | t.Fatal(err) 47 | } 48 | 49 | var swagger map[string]interface{} 50 | err = json.Unmarshal(bytes, &swagger) 51 | if err != nil { 52 | t.Fatal(err) 53 | } 54 | 55 | ParseSwagger(swagger) 56 | }) 57 | } 58 | } 59 | --------------------------------------------------------------------------------