├── .dockerignore ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── codeql-analysis.yml │ ├── e2e-info.yml │ ├── integration-install.yml │ ├── integration-json.yml │ ├── integration-per-language.yml │ ├── integration-tests.yml │ ├── poll-starter.yml │ ├── release-and-publish.yml │ └── unit-tests.yml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── Makefile ├── NOTICE.md ├── README.md ├── SECURITY.md ├── cmd ├── create.go ├── create_test.go ├── createconfig.go ├── generateworkflow.go ├── info.go ├── root.go ├── setupgh.go ├── setupgh_test.go ├── update.go ├── validate.go ├── validate_test.go ├── validate_test_helpers.go ├── version.go └── version_test.go ├── docs ├── README.md └── maintenance │ └── README.md ├── example ├── deployment.go ├── deployment_test.go ├── dockerfile.go └── dockerfile_test.go ├── ghAssets ├── Draft-Gradient@3x.png ├── draft-create.png ├── draft-validate.png ├── generate-workflow.png ├── setup-gh.png ├── videoasset1.png └── videoasset2.png ├── go.mod ├── go.sum ├── main.go ├── package-lock.json ├── pkg ├── cmdhelpers │ ├── addon_helpers.go │ ├── addon_helpers_test.go │ ├── github_workflow.go │ ├── workflow_helpers.go │ └── workflow_service_types.go ├── config │ ├── draftconfig.go │ ├── draftconfig_template_test.go │ ├── draftconfig_test.go │ ├── transformers │ │ ├── transformers.go │ │ └── transformers_test.go │ └── validators │ │ ├── validators.go │ │ └── validators_test.go ├── consts │ └── consts.go ├── cred │ └── cred.go ├── dryrun │ └── dryrun.go ├── embedutils │ └── embedutil.go ├── filematches │ ├── filematches.go │ ├── filematches_test.go │ └── templates │ │ ├── invalid_template.yaml │ │ └── valid_template.yaml ├── fixtures │ ├── addons │ │ └── ingress │ │ │ └── ingress.yaml │ ├── deployments │ │ ├── helm │ │ │ └── charts │ │ │ │ ├── .helmignore │ │ │ │ ├── Chart.yaml │ │ │ │ ├── production.yaml │ │ │ │ ├── templates │ │ │ │ ├── _helpers.tpl │ │ │ │ ├── configmap.yaml │ │ │ │ ├── deployment.yaml │ │ │ │ └── service.yaml │ │ │ │ └── values.yaml │ │ ├── kustomize │ │ │ ├── base │ │ │ │ ├── configmap.yaml │ │ │ │ ├── deployment-override-workload-identity.yaml │ │ │ │ ├── deployment.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ ├── namespace.yaml │ │ │ │ └── service.yaml │ │ │ └── overlays │ │ │ │ └── production │ │ │ │ ├── deployment-override-workload-identity.yaml │ │ │ │ ├── deployment.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── service.yaml │ │ └── manifest │ │ │ └── manifests │ │ │ ├── configmap.yaml │ │ │ ├── deployment-override-workload-identity.yaml │ │ │ ├── deployment.yaml │ │ │ └── service.yaml │ ├── dockerfiles │ │ ├── clojure │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── csharp │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── erlang │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── go │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── gomodule │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── gradle │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── gradlew │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── java │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── javascript │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── php │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── python │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── ruby │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ ├── rust │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ │ └── swift │ │ │ ├── .dockerignore │ │ │ └── Dockerfile │ ├── manifests │ │ ├── hpa │ │ │ ├── hpa-memory.yaml │ │ │ └── hpa.yaml │ │ ├── ingress │ │ │ ├── ingress-simple.yaml │ │ │ └── ingress.yaml │ │ ├── pdb │ │ │ └── pdb.yaml │ │ └── service │ │ │ └── service.yaml │ ├── pipelines │ │ ├── kustomize.yaml │ │ └── manifests.yaml │ ├── validatetemplate.go │ └── workflows │ │ ├── azure-kubernetes-service-helm.yml │ │ ├── azurepipelines │ │ ├── kustomize │ │ │ └── .pipelines │ │ │ │ └── azure-kubernetes-service.yaml │ │ └── manifests │ │ │ └── .pipelines │ │ │ └── azure-kubernetes-service.yaml │ │ └── github │ │ ├── helm │ │ └── .github │ │ │ └── workflows │ │ │ └── azure-kubernetes-service-helm.yml │ │ ├── kustomize │ │ └── .github │ │ │ └── workflows │ │ │ └── azure-kubernetes-service-kustomize.yml │ │ └── manifests │ │ └── .github │ │ └── workflows │ │ └── azure-kubernetes-service.yml ├── handlers │ ├── template.go │ ├── template_test.go │ ├── template_utils.go │ ├── template_utils_test.go │ ├── templatetests │ │ ├── deployment_helm_test.go │ │ ├── deployment_kustomize_test.go │ │ ├── deployment_manifest_test.go │ │ ├── dockerfile_test.go │ │ ├── manifests_hpa_test.go │ │ ├── manifests_ingress_test.go │ │ ├── manifests_pdb_test.go │ │ ├── manifests_service_test.go │ │ ├── template_test.go │ │ ├── workflows_azure_kustomize_test.go │ │ ├── workflows_azure_manifest_test.go │ │ ├── workflows_github_helm_test.go │ │ └── workflows_github_kustomize_test.go │ └── variableextractors │ │ └── defaults │ │ ├── gradle.go │ │ ├── gradle_test.go │ │ ├── python.go │ │ ├── python_test.go │ │ └── testdata │ │ └── sample.gradle ├── linguist │ ├── README.md │ ├── analyse.go │ ├── data │ │ ├── classifier │ │ ├── data.go │ │ ├── documentation.yml │ │ ├── generate.go │ │ ├── generate_classifier.go │ │ ├── languages.yml │ │ └── vendor.yml │ ├── generate.go │ ├── generate_static.go │ ├── linguist.go │ ├── linguist_test.go │ ├── static.go │ ├── testdirs │ │ ├── app-documentation │ │ │ ├── .gitattributes │ │ │ ├── app.py │ │ │ └── docs │ │ │ │ └── index.html │ │ ├── app-duck │ │ │ ├── .gitattributes │ │ │ └── main.duck │ │ ├── app-emptydir │ │ │ └── .gitkeep │ │ ├── app-generated │ │ │ ├── .gitattributes │ │ │ ├── man1 │ │ │ │ └── generated.html │ │ │ └── src │ │ │ │ └── app.py │ │ ├── app-not-vendored │ │ │ ├── .gitattributes │ │ │ ├── app.py │ │ │ └── vendor.html │ │ ├── app-python │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ └── app-vendored │ │ │ ├── .gitattributes │ │ │ ├── app.py │ │ │ └── vendor.html │ ├── tokenizer │ │ └── tokenizer.go │ └── util.go ├── logger │ └── logger.go ├── osutil │ ├── osutil.go │ └── osutil_test.go ├── prompts │ ├── prompts.go │ └── prompts_test.go ├── providers │ ├── az-client.go │ ├── azcli.go │ ├── azcli_test.go │ ├── azure.go │ ├── commandrunner.go │ ├── ghcli.go │ ├── ghcli_test.go │ └── mock │ │ └── az-client.go ├── reporeader │ ├── readers │ │ └── localfsreader.go │ └── reporeader.go ├── safeguards │ ├── helpers.go │ ├── helpers_test.go │ ├── lib │ │ ├── manifests │ │ │ ├── v1.0.0 │ │ │ │ ├── container-allowed-images │ │ │ │ │ ├── constraint.yaml │ │ │ │ │ └── template.yaml │ │ │ │ ├── container-enforce-probes │ │ │ │ │ ├── constraint.yaml │ │ │ │ │ └── template.yaml │ │ │ │ ├── container-resource-limits │ │ │ │ │ ├── constraint.yaml │ │ │ │ │ └── template.yaml │ │ │ │ ├── container-restricted-image-pulls │ │ │ │ │ ├── constraint.yaml │ │ │ │ │ └── template.yaml │ │ │ │ ├── disallowed-bad-pod-disruption-budgets │ │ │ │ │ ├── constraint.yaml │ │ │ │ │ └── template.yaml │ │ │ │ ├── pod-enforce-antiaffinity │ │ │ │ │ ├── constraint.yaml │ │ │ │ │ └── template.yaml │ │ │ │ ├── restricted-taints │ │ │ │ │ ├── constraint.yaml │ │ │ │ │ └── template.yaml │ │ │ │ └── unique-service-selectors │ │ │ │ │ ├── constraint.yaml │ │ │ │ │ └── template.yaml │ │ │ └── v2.0.0 │ │ │ │ ├── container-allowed-images │ │ │ │ ├── constraint.yaml │ │ │ │ └── template.yaml │ │ │ │ ├── container-enforce-probes │ │ │ │ ├── constraint.yaml │ │ │ │ └── template.yaml │ │ │ │ ├── container-resource-limits │ │ │ │ ├── constraint.yaml │ │ │ │ └── template.yaml │ │ │ │ ├── container-restricted-image-pulls │ │ │ │ ├── constraint.yaml │ │ │ │ └── template.yaml │ │ │ │ ├── disallowed-bad-pod-disruption-budgets │ │ │ │ ├── constraint.yaml │ │ │ │ └── template.yaml │ │ │ │ ├── pod-enforce-antiaffinity │ │ │ │ ├── constraint.yaml │ │ │ │ └── template.yaml │ │ │ │ ├── restricted-taints │ │ │ │ ├── constraint.yaml │ │ │ │ └── template.yaml │ │ │ │ └── unique-service-selectors │ │ │ │ ├── constraint.yaml │ │ │ │ └── template.yaml │ │ └── v1.0.0 │ │ │ ├── container-allowed-images │ │ │ ├── constraint.yaml │ │ │ └── template.yaml │ │ │ ├── container-enforce-probes │ │ │ ├── constraint.yaml │ │ │ └── template.yaml │ │ │ ├── container-resource-limits │ │ │ ├── constraint.yaml │ │ │ └── template.yaml │ │ │ ├── container-restricted-image-pulls │ │ │ ├── constraint.yaml │ │ │ └── template.yaml │ │ │ ├── disallowed-bad-pod-disruption-budgets │ │ │ ├── constraint.yaml │ │ │ └── template.yaml │ │ │ ├── pod-enforce-antiaffinity │ │ │ ├── constraint.yaml │ │ │ └── template.yaml │ │ │ ├── restricted-taints │ │ │ ├── constraint.yaml │ │ │ └── template.yaml │ │ │ └── unique-service-selectors │ │ │ ├── constraint.yaml │ │ │ └── template.yaml │ ├── manifestresults.go │ ├── manifestresults_test.go │ ├── preprocessing │ │ ├── preprocessing.go │ │ ├── preprocessing_helpers.go │ │ ├── preprocessing_test.go │ │ └── preprocessing_test_helpers.go │ ├── tests │ │ ├── all │ │ │ ├── error │ │ │ │ ├── all-error-manifest-1.yaml │ │ │ │ └── all-error-manifest-2.yaml │ │ │ └── success │ │ │ │ ├── all-success-manifest-1.yaml │ │ │ │ └── all-success-manifest-2.yaml │ │ ├── container-allowed-images │ │ │ ├── CAI-error-manifest.yaml │ │ │ └── CAI-success-manifest.yaml │ │ ├── container-enforce-probes │ │ │ ├── CEP-error-manifest.yaml │ │ │ └── CEP-success-manifest.yaml │ │ ├── container-resource-limits │ │ │ ├── CRL-error-manifest.yaml │ │ │ └── CRL-success-manifest.yaml │ │ ├── container-restricted-image-pulls │ │ │ ├── CRIP-error-manifest.yaml │ │ │ └── CRIP-success-manifest.yaml │ │ ├── disallowed-bad-pod-disruption-budgets │ │ │ ├── DBPDB-error-manifest.yaml │ │ │ └── DBPDB-success-manifest.yaml │ │ ├── kustomize │ │ │ ├── base │ │ │ │ ├── deployment.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ ├── namespace.yaml │ │ │ │ └── service.yaml │ │ │ └── overlays │ │ │ │ └── production │ │ │ │ ├── deployment.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ ├── namespace.yaml │ │ │ │ └── service.yaml │ │ ├── not-yaml │ │ │ └── readme.md │ │ ├── pod-enforce-antiaffinity │ │ │ ├── PEA-error-manifest.yaml │ │ │ └── PEA-success-manifest.yaml │ │ ├── restricted-taints │ │ │ ├── RT-error-manifest.yaml │ │ │ └── RT-success-manifest.yaml │ │ ├── testmanifests │ │ │ ├── different-structure │ │ │ │ ├── Chart.yaml │ │ │ │ ├── templates │ │ │ │ │ ├── _helpers.tpl │ │ │ │ │ ├── deployment.yaml │ │ │ │ │ └── service.yaml │ │ │ │ └── values.yaml │ │ │ ├── expected-helpers-deployment.yaml │ │ │ ├── expected-helpers-service.yaml │ │ │ ├── expected-mainchart.yaml │ │ │ ├── expected-resources.yaml │ │ │ ├── expected-subchart1.yaml │ │ │ ├── expected-subchart2.yaml │ │ │ ├── expecteddeployment.yaml │ │ │ ├── expecteddeployment_flags.yaml │ │ │ ├── expectedingress.yaml │ │ │ ├── expectedingress_flags.yaml │ │ │ ├── expectedservice.yaml │ │ │ ├── expectedservice2.yaml │ │ │ ├── expectedservice_flags.yaml │ │ │ ├── invalidchart │ │ │ │ ├── Chart.yaml │ │ │ │ ├── templates │ │ │ │ │ └── deployment.yaml │ │ │ │ └── values.yaml │ │ │ ├── invaliddeployment-syntax │ │ │ │ ├── Chart.yaml │ │ │ │ ├── templates │ │ │ │ │ └── invaliddeploymentsyntax.yaml │ │ │ │ └── values.yaml │ │ │ ├── invaliddeployment-values │ │ │ │ ├── Chart.yaml │ │ │ │ ├── templates │ │ │ │ │ └── invaliddeploymentvalues.yaml │ │ │ │ └── values.yaml │ │ │ ├── invalidvalues │ │ │ │ ├── Chart.yaml │ │ │ │ ├── templates │ │ │ │ │ └── service.yaml │ │ │ │ └── values.yaml │ │ │ ├── multiple-charts │ │ │ │ ├── Chart.yaml │ │ │ │ ├── charts │ │ │ │ │ ├── subchart1 │ │ │ │ │ │ ├── Chart.yaml │ │ │ │ │ │ ├── templates │ │ │ │ │ │ │ └── deployment1.yaml │ │ │ │ │ │ └── values.yaml │ │ │ │ │ └── subchart2 │ │ │ │ │ │ ├── Chart.yaml │ │ │ │ │ │ ├── templates │ │ │ │ │ │ └── deployment2.yaml │ │ │ │ │ │ └── values.yaml │ │ │ │ ├── templates │ │ │ │ │ └── maindeployment.yaml │ │ │ │ └── values.yaml │ │ │ ├── multiple-templates │ │ │ │ ├── Chart.yaml │ │ │ │ ├── templates │ │ │ │ │ ├── resources.yaml │ │ │ │ │ └── services │ │ │ │ │ │ ├── service-1.yaml │ │ │ │ │ │ └── service-2.yaml │ │ │ │ └── values.yaml │ │ │ ├── nochart-invalid │ │ │ │ ├── templates │ │ │ │ │ └── deployment.yaml │ │ │ │ └── values.yaml │ │ │ └── validchart │ │ │ │ ├── Chart.yaml │ │ │ │ ├── templates │ │ │ │ ├── deployment.yaml │ │ │ │ ├── ingress.yaml │ │ │ │ └── service.yaml │ │ │ │ └── values.yaml │ │ └── unique-service-selectors │ │ │ ├── USS-error-manifest.yaml │ │ │ └── USS-success-manifest.yaml │ └── types │ │ ├── constants.go │ │ ├── test_constants.go │ │ └── types.go ├── spinner │ └── spinner.go └── templatewriter │ ├── templatewriter.go │ └── writers │ ├── filemapwriter.go │ ├── filemapwriter_test.go │ └── localfswriter.go ├── scripts └── install.sh ├── template ├── README.md ├── addons │ └── azure │ │ └── webapp_routing │ │ ├── draft.yaml │ │ └── ingress.yaml ├── azurePipelines │ ├── kustomize │ │ ├── .pipelines │ │ │ └── azure-kubernetes-service.yaml │ │ └── draft.yaml │ └── manifests │ │ ├── .pipelines │ │ └── azure-kubernetes-service.yaml │ │ └── draft.yaml ├── deployments │ ├── helm │ │ ├── charts │ │ │ ├── .helmignore │ │ │ ├── Chart.yaml │ │ │ ├── production.yaml │ │ │ ├── templates │ │ │ │ ├── _helpers.tpl │ │ │ │ ├── configmap.yaml │ │ │ │ ├── deployment.yaml │ │ │ │ └── service.yaml │ │ │ └── values.yaml │ │ └── draft.yaml │ ├── kustomize │ │ ├── base │ │ │ ├── configmap.yaml │ │ │ ├── deployment.yaml │ │ │ ├── kustomization.yaml │ │ │ └── service.yaml │ │ ├── draft.yaml │ │ └── overlays │ │ │ └── production │ │ │ ├── deployment.yaml │ │ │ ├── kustomization.yaml │ │ │ └── service.yaml │ └── manifests │ │ ├── draft.yaml │ │ └── manifests │ │ ├── configmap.yaml │ │ ├── deployment.yaml │ │ └── service.yaml ├── dockerfiles │ ├── clojure │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── csharp │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── erlang │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── go │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── gomodule │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── gradle │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── gradlew │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── java │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── javascript │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── php │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── python │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── ruby │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── rust │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ ├── swift │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── draft.yaml │ └── tomcat │ │ ├── Dockerfile │ │ └── draft.yaml ├── manifests │ ├── HorizontalPodAutoscaler │ │ └── manifests │ │ │ ├── draft.yaml │ │ │ └── hpa.yaml │ ├── Ingress │ │ └── manifests │ │ │ ├── draft.yaml │ │ │ └── ingress.yaml │ ├── PodDisruptionBudget │ │ └── manifests │ │ │ ├── draft.yaml │ │ │ └── pdb.yaml │ └── Service │ │ └── manifests │ │ ├── draft.yaml │ │ └── service.yaml ├── templates.go └── workflows │ ├── helm │ ├── .github │ │ └── workflows │ │ │ └── azure-kubernetes-service-helm.yml │ └── draft.yaml │ ├── kustomize │ ├── .github │ │ └── workflows │ │ │ └── azure-kubernetes-service-kustomize.yml │ └── draft.yaml │ └── manifests │ ├── .github │ └── workflows │ │ └── azure-kubernetes-service.yml │ └── draft.yaml └── test ├── README.md ├── check_info_schema.sh ├── check_windows_addon_helm.ps1 ├── check_windows_addon_kustomize.ps1 ├── check_windows_helm.ps1 ├── check_windows_kustomize.ps1 ├── dry_run_schema.json ├── gen_windows_check.sh ├── info_schema.json ├── integration ├── clojure │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── csharp │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── erlang │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── go │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── gomodule │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── gradle │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── java │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── javascript │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── python │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── ruby │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── rust │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml └── swift │ ├── helm.yaml │ ├── kustomize.yaml │ └── manifest.yaml ├── skaffold.yaml ├── templates ├── config.yaml ├── deployment.yaml ├── ensure_file.yaml ├── helm │ └── charts │ │ ├── .helmignore │ │ ├── Chart.yaml │ │ ├── production.yaml │ │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── namespace.yaml │ │ └── service.yaml │ │ └── values.yaml ├── helm_prod_values.yaml ├── invalid_deployment.yaml ├── kustomize │ ├── base │ │ ├── deployment.yaml │ │ ├── kustomization.yaml │ │ └── service.yaml │ └── overlays │ │ └── production │ │ ├── deployment.yaml │ │ ├── kustomization.yaml │ │ └── service.yaml ├── manifests │ └── manifests │ │ ├── deployment.yaml │ │ └── service.yaml ├── service_w_annotations.yaml └── unsupported_no_of_containers.yaml └── update_dry_run_schema.json /.dockerignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .idea/ 3 | /pkg/deployments/deployTypes/ 4 | /pkg/workflows/workflow/ 5 | .DS_Store 6 | draft 7 | langtest -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Mention the platform you are using** 14 | Mention what platform you are using (az-extension, oss draft, vscode) and pick the corresponding label. 15 | 16 | **To Reproduce** 17 | Steps to reproduce the behavior: 18 | 1. Go to '...' 19 | 2. Click on '....' 20 | 3. Scroll down to '....' 21 | 4. See error 22 | 23 | **Expected behavior** 24 | A clear and concise description of what you expected to happen. 25 | 26 | **Screenshots** 27 | If applicable, add screenshots to help explain your problem. 28 | 29 | **Desktop (please complete the following information):** 30 | - OS: [e.g. iOS] 31 | - Browser [e.g. chrome, safari] 32 | - Version [e.g. 22] 33 | 34 | **Smartphone (please complete the following information):** 35 | - Device: [e.g. iPhone6] 36 | - OS: [e.g. iOS8.1] 37 | - Browser [e.g. stock browser, safari] 38 | - Version [e.g. 22] 39 | 40 | **Additional context** 41 | Add any other context about the problem here. 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Mention what platform you want to support the new feature** 14 | Mention what platform you would like the feature request to live in (az-extension, oss draft, vscode) and select the proper label. 15 | 16 | **Describe the solution you'd like** 17 | A clear and concise description of what you want to happen. 18 | 19 | **Describe alternatives you've considered** 20 | A clear and concise description of any alternative solutions or features you've considered. 21 | 22 | **Additional context** 23 | Add any other context or screenshots about the feature request here. 24 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gomod 4 | directory: / 5 | schedule: 6 | interval: "weekly" 7 | - package-ecosystem: "github-actions" 8 | directory: ".github/workflows" 9 | schedule: 10 | interval: weekly 11 | - package-ecosystem: "github-actions" 12 | directory: "/template/workflows/helm/.github/workflows" 13 | schedule: 14 | interval: "weekly" 15 | - package-ecosystem: "github-actions" 16 | directory: "/template/workflows/kustomize/.github/workflows" 17 | schedule: 18 | interval: "weekly" 19 | - package-ecosystem: "github-actions" 20 | directory: "/template/workflows/manifests/.github/workflows" 21 | schedule: 22 | interval: "weekly" 23 | - package-ecosystem: "github-actions" 24 | directory: "/" 25 | schedule: 26 | interval: "weekly" 27 | labels: 28 | - "dependencies" 29 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Please include the related issue if relevant, and motivation/context. Please also list any dependencies required for this change. 4 | 5 | Fixes # (issue) 6 | Feature # (details) 7 | 8 | ## Type of change 9 | 10 | - [ ] Bug fix (non-breaking change which fixes an issue) 11 | - [ ] New feature (non-breaking change which adds functionality) 12 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 13 | - [ ] This change requires a documentation update 14 | - [ ] Refactor 15 | 16 | ## How Has This Been Tested? 17 | 18 | Provide instructions so we can reproduce, and list any relevant details for your test configuration. Please mention if this is a breaking change which will impact consuming tool(s). 19 | 20 | - [ ] Unit Test: 21 | - [ ] E2E Test: 22 | - [ ] Other Test: 23 | 24 | 25 | ## Checklist: 26 | 27 | - [ ] My code follows the style guidelines of this project 28 | - [ ] I have performed a self-review of my code 29 | - [ ] I have commented my code, particularly in hard-to-understand areas 30 | - [ ] I have made corresponding changes to the documentation 31 | - [ ] My changes generate no new warnings 32 | - [ ] I have added tests that prove my fix is effective or that my feature works 33 | - [ ] New and existing unit tests pass locally with my changes 34 | - [ ] Any dependent changes have been merged and published in downstream modules 35 | 36 | -------------------------------------------------------------------------------- /.github/workflows/e2e-info.yml: -------------------------------------------------------------------------------- 1 | name: Draft Info E2E Test 2 | on: 3 | pull_request: 4 | branches: [ main ] 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | actions: read 11 | contents: read 12 | deployments: read 13 | packages: none 14 | steps: 15 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 16 | - name: Set up Go 17 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 18 | with: 19 | go-version: 1.22 20 | - name: make 21 | run: make 22 | - name: Validate JSON 23 | run: | 24 | ./test/check_info_schema.sh -------------------------------------------------------------------------------- /.github/workflows/unit-tests.yml: -------------------------------------------------------------------------------- 1 | name: draft Unit Tests 2 | on: 3 | pull_request: 4 | branches: [ main ] 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 11 | - name: Set up Go 12 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 13 | with: 14 | go-version: 1.22 15 | - name: make 16 | run: make run-unit-tests 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .idea/ 3 | /pkg/workflows/workflows/ 4 | /pkg/addons/addons/ 5 | .DS_Store 6 | draft 7 | draft.exe 8 | langtest 9 | .vscode/ 10 | /pkg/languages/builders 11 | test/temp/ 12 | bin/ -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | 3 | This project welcomes contributions and suggestions. Most contributions require you to 4 | agree to a Contributor License Agreement (CLA) declaring that you have the right to, 5 | and actually do, grant us the rights to use your contribution. For details, visit 6 | https://cla.microsoft.com. 7 | 8 | When you submit a pull request, a CLA-bot will automatically determine whether you need 9 | to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the 10 | instructions provided by the bot. You will only need to do this once across all repositories using our CLA. 11 | 12 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 13 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 14 | or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23-alpine 2 | 3 | WORKDIR /draft 4 | 5 | RUN apk add gcc musl-dev python3-dev libffi-dev openssl-dev cargo make 6 | RUN apk add py3-pip 7 | 8 | RUN python3 -m venv az-cli-env 9 | RUN az-cli-env/bin/pip install --upgrade pip 10 | RUN az-cli-env/bin/pip install --upgrade setuptools 11 | RUN az-cli-env/bin/pip install --upgrade azure-cli 12 | RUN az-cli-env/bin/pip install --upgrade setuptools 13 | RUN az-cli-env/bin/az --version 14 | 15 | ENV PATH "$PATH:/draft/az-cli-env/bin" 16 | 17 | RUN apk add github-cli 18 | 19 | COPY . ./ 20 | 21 | RUN go mod download 22 | ENTRYPOINT ["go"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Microsoft Azure 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 | -------------------------------------------------------------------------------- /cmd/createconfig.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | type CreateConfig struct { 4 | DeployType string `yaml:"deployType"` 5 | LanguageType string `yaml:"languageType"` 6 | DeployVariables []UserInputs `yaml:"deployVariables"` 7 | LanguageVariables []UserInputs `yaml:"languageVariables"` 8 | } 9 | 10 | type UserInputs struct { 11 | Name string `yaml:"name"` 12 | Value string `yaml:"value"` 13 | } 14 | -------------------------------------------------------------------------------- /cmd/validate_test_helpers.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | types "github.com/Azure/draft/pkg/safeguards/types" 5 | ) 6 | 7 | func countTestViolations(results []types.ManifestResult) int { 8 | numViolations := 0 9 | for _, r := range results { 10 | numViolations += len(r.ObjectViolations) 11 | } 12 | 13 | return numViolations 14 | } 15 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | log "github.com/sirupsen/logrus" 6 | "github.com/spf13/cobra" 7 | "runtime/debug" 8 | ) 9 | 10 | var VERSION = "v0.0.7" 11 | 12 | func newVersionCmd() *cobra.Command { 13 | // versionCmd represents the version command 14 | var version = &cobra.Command{ 15 | Use: "version", 16 | Short: "Get the current version of Draft", 17 | Long: `Returns the running version of Draft`, 18 | RunE: func(cmd *cobra.Command, args []string) error { 19 | 20 | vcsInfo := getVCSInfoFromRuntime() 21 | 22 | fmt.Println("version: ", VERSION) 23 | fmt.Println("runtime SHA: ", vcsInfo) 24 | return nil 25 | }, 26 | } 27 | 28 | return version 29 | 30 | } 31 | 32 | func getVCSInfoFromRuntime() string { 33 | buildInfo, ok := debug.ReadBuildInfo() 34 | if !ok { 35 | log.Fatal("could not get vcs info at runtime") 36 | } 37 | 38 | for _, kv := range buildInfo.Settings { 39 | if kv.Key == "vcs.revision" { 40 | return kv.Value 41 | } 42 | } 43 | 44 | return "" 45 | } 46 | 47 | func init() { 48 | rootCmd.AddCommand(newVersionCmd()) 49 | } 50 | -------------------------------------------------------------------------------- /cmd/version_test.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestGetVersionAtRuntime(t *testing.T) { 9 | vcsInfo := getVCSInfoFromRuntime() 10 | assert.Empty(t, vcsInfo) 11 | } 12 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Draft CLI Tool 2 | 3 | ## Maintenance 4 | 5 | * [How to release](maintenance/README.md) 6 | 7 | -------------------------------------------------------------------------------- /docs/maintenance/README.md: -------------------------------------------------------------------------------- 1 | ## How to Release 2 | 3 | To make a new release and publish please follow the following steps. 4 | 5 | 1. Create a branch `publish-x.y.z` 6 | 2. Add a section to `CHANGELOG.md` with the header `## [x.y.z]` (N.B: make sure to write the new version in square brackets as the `changelog-reader` action only works if the `CHANGELOG.md` file follows the [Keep a Changelog standard](https://github.com/olivierlacan/keep-a-changelog)) 7 | 3. Create a new PR, get approval and merge 8 | 4. Run the `Draft Release & Publish` workflow manually from the GH Actions tab 9 | 10 | Note: `DRAFT_VERSION` can be written as a step env var. For more reference: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable 11 | 12 | ### Sample Changelog content for first release. 13 | 14 | For first release using new release and publish using changelog here is a sample: 15 | 16 | ``` 17 | 18 | ## [0.0.26] 19 | 20 | * What is getting released here + @commit 21 | 22 | Thanks to whoever was involved, pm. 23 | 24 | ``` 25 | -------------------------------------------------------------------------------- /example/deployment_test.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestWriteDeploymentFilesExample(t *testing.T) { 8 | err := WriteDeploymentFilesExample() 9 | if err != nil { 10 | t.Errorf("WriteDockerfileExample failed: %e", err) 11 | t.Fail() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/dockerfile_test.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestWriteDockerfileExample(t *testing.T) { 8 | err := WriteDockerfileExample() 9 | if err != nil { 10 | t.Errorf("WriteDockerfileExample failed: %e", err) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ghAssets/Draft-Gradient@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/draft/9e9240a6a0cce34ad92a09634b0fe2edc4bc0145/ghAssets/Draft-Gradient@3x.png -------------------------------------------------------------------------------- /ghAssets/draft-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/draft/9e9240a6a0cce34ad92a09634b0fe2edc4bc0145/ghAssets/draft-create.png -------------------------------------------------------------------------------- /ghAssets/draft-validate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/draft/9e9240a6a0cce34ad92a09634b0fe2edc4bc0145/ghAssets/draft-validate.png -------------------------------------------------------------------------------- /ghAssets/generate-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/draft/9e9240a6a0cce34ad92a09634b0fe2edc4bc0145/ghAssets/generate-workflow.png -------------------------------------------------------------------------------- /ghAssets/setup-gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/draft/9e9240a6a0cce34ad92a09634b0fe2edc4bc0145/ghAssets/setup-gh.png -------------------------------------------------------------------------------- /ghAssets/videoasset1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/draft/9e9240a6a0cce34ad92a09634b0fe2edc4bc0145/ghAssets/videoasset1.png -------------------------------------------------------------------------------- /ghAssets/videoasset2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/draft/9e9240a6a0cce34ad92a09634b0fe2edc4bc0145/ghAssets/videoasset2.png -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 NAME HERE 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 | package main 17 | 18 | import "github.com/Azure/draft/cmd" 19 | 20 | func main() { 21 | cmd.Execute() 22 | } 23 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "draft", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": {} 6 | } 7 | -------------------------------------------------------------------------------- /pkg/cmdhelpers/github_workflow.go: -------------------------------------------------------------------------------- 1 | package cmdhelpers 2 | 3 | // GitHubWorkflow is a rough struct to allow for yaml editing including deletion of Job steps 4 | type GitHubWorkflow struct { 5 | Name string 6 | On on `yaml:"on"` 7 | Env map[string]string 8 | Jobs map[string]job 9 | } 10 | 11 | type on struct { 12 | Push push 13 | WorkflowDispatch interface{} `yaml:"workflow_dispatch"` 14 | } 15 | 16 | type push struct { 17 | Branches []string 18 | } 19 | 20 | type job struct { 21 | Permissions map[string]string 22 | RunsOn string `yaml:"runs-on"` 23 | Needs []string `yaml:"needs,omitempty"` 24 | Steps []map[string]interface{} 25 | } 26 | -------------------------------------------------------------------------------- /pkg/config/transformers/transformers.go: -------------------------------------------------------------------------------- 1 | package transformers 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | func GetTransformer(variableKind string) func(string) (any, error) { 9 | switch variableKind { 10 | case "envVarMap": 11 | return EnvironmentVariableMapTransformer 12 | default: 13 | return DefaultTransformer 14 | } 15 | } 16 | 17 | func EnvironmentVariableMapTransformer(inputVar string) (any, error) { 18 | var inputVarMap map[string]string 19 | if err := json.Unmarshal([]byte(inputVar), &inputVarMap); err != nil { 20 | return "", fmt.Errorf("failed to unmarshal variable as map[string]string: %s", err) 21 | } 22 | return inputVarMap, nil 23 | } 24 | 25 | func DefaultTransformer(inputVar string) (any, error) { 26 | return inputVar, nil 27 | } 28 | -------------------------------------------------------------------------------- /pkg/config/transformers/transformers_test.go: -------------------------------------------------------------------------------- 1 | package transformers 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestGetTransformer(t *testing.T) { 10 | assert.NotNil(t, GetTransformer("NonExistentKind")) 11 | } 12 | 13 | func TestDefaultTransformer(t *testing.T) { 14 | res, err := DefaultTransformer("test") 15 | assert.Nil(t, err) 16 | assert.Equal(t, "test", res) 17 | } 18 | -------------------------------------------------------------------------------- /pkg/config/validators/validators_test.go: -------------------------------------------------------------------------------- 1 | package validators 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestGetValidator(t *testing.T) { 10 | assert.NotNil(t, GetValidator("NonExistentKind")) 11 | } 12 | 13 | func TestDefaultValidator(t *testing.T) { 14 | assert.Nil(t, defaultValidator("test")) 15 | } 16 | 17 | func TestKubernetesProbeTypeValidator(t *testing.T) { 18 | assert.Nil(t, kubernetesProbeTypeValidator("httpGet")) 19 | assert.Nil(t, kubernetesProbeTypeValidator("tcpSocket")) 20 | assert.NotNil(t, kubernetesProbeTypeValidator("exec")) 21 | } 22 | 23 | func TestKeyValueMapValidator(t *testing.T) { 24 | assert.Nil(t, keyValueMapValidator(`{"key": "value"}`)) 25 | assert.NotNil(t, keyValueMapValidator(`{"key": "value"`)) 26 | } 27 | 28 | func TestScalingResourceTypeValidator(t *testing.T) { 29 | assert.Nil(t, scalingResourceTypeValidator("cpu")) 30 | assert.Nil(t, scalingResourceTypeValidator("memory")) 31 | assert.NotNil(t, scalingResourceTypeValidator("disk")) 32 | } 33 | 34 | func TestImagePullPolicyValidator(t *testing.T) { 35 | assert.Nil(t, imagePullPolicyValidator("Always")) 36 | assert.Nil(t, imagePullPolicyValidator("IfNotPresent")) 37 | assert.Nil(t, imagePullPolicyValidator("Never")) 38 | assert.NotNil(t, imagePullPolicyValidator("Sometimes")) 39 | } 40 | -------------------------------------------------------------------------------- /pkg/consts/consts.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | var HelmReferencePathMapping = map[string]map[string]string{ 4 | "service": { 5 | "metadata.name": `{{ include "{{APPNAME}}.fullname" . }}`, 6 | "spec.ports.port": `{{ .Values.service.port }}`, 7 | "metadata.namespace": "default", 8 | }, 9 | } 10 | 11 | var RefPathLookups = map[string]map[string][]string{ 12 | "service": { 13 | "metadata.name": []string{"metadata", "name"}, 14 | "spec.ports.port": []string{"spec", "ports", "-", "port"}, 15 | "metadata.namespace": []string{"metadata", "namespace"}, 16 | }, 17 | } 18 | 19 | var DeploymentFilePaths = map[string]string{ 20 | "helm": "charts/templates", 21 | "kustomize": "overlays/production", 22 | "manifests": "manifests", 23 | } 24 | -------------------------------------------------------------------------------- /pkg/cred/cred.go: -------------------------------------------------------------------------------- 1 | package cred 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Azure/azure-sdk-for-go/sdk/azidentity" 6 | ) 7 | 8 | var ( 9 | cred *azidentity.DefaultAzureCredential 10 | ) 11 | 12 | func GetCred() (*azidentity.DefaultAzureCredential, error) { 13 | if cred != nil { 14 | return cred, nil 15 | } 16 | 17 | var err error 18 | cred, err = azidentity.NewDefaultAzureCredential(nil) 19 | if err != nil { 20 | return nil, fmt.Errorf("authenticating to Azure: %w", err) 21 | } 22 | 23 | return cred, nil 24 | } 25 | -------------------------------------------------------------------------------- /pkg/dryrun/dryrun.go: -------------------------------------------------------------------------------- 1 | package dryrun 2 | 3 | type DryRunInfo struct { 4 | Variables map[string]string `json:"variables"` 5 | FilesToWrite []string `json:"filesToWrite"` 6 | } 7 | 8 | type DryRunRecorder struct { 9 | DryRunInfo *DryRunInfo 10 | } 11 | 12 | func (d *DryRunRecorder) WriteFile(path string, data []byte) error { 13 | d.DryRunInfo.FilesToWrite = append(d.DryRunInfo.FilesToWrite, path) 14 | return nil 15 | } 16 | 17 | func (d *DryRunRecorder) EnsureDirectory(path string) error { 18 | return nil 19 | } 20 | 21 | func (d *DryRunRecorder) Record(key, value string) { 22 | d.DryRunInfo.Variables[key] = value 23 | } 24 | 25 | func NewDryRunRecorder() *DryRunRecorder { 26 | return &DryRunRecorder{ 27 | DryRunInfo: &DryRunInfo{ 28 | Variables: make(map[string]string), 29 | FilesToWrite: make([]string, 0), 30 | }, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pkg/embedutils/embedutil.go: -------------------------------------------------------------------------------- 1 | package embedutils 2 | 3 | import ( 4 | "embed" 5 | "fmt" 6 | "io/fs" 7 | ) 8 | 9 | func EmbedFStoMap(embedFS embed.FS, path string) (map[string]fs.DirEntry, error) { 10 | files, err := embedFS.ReadDir(path) 11 | if err != nil { 12 | return nil, fmt.Errorf("failed to readDir: %w", err) 13 | } 14 | 15 | mapping := make(map[string]fs.DirEntry) 16 | 17 | for _, f := range files { 18 | if f.IsDir() { 19 | mapping[f.Name()] = f 20 | } 21 | } 22 | 23 | return mapping, nil 24 | } 25 | 26 | func EmbedFStoMapWithFiles(embedFS fs.FS, path string) (map[string]fs.DirEntry, error) { 27 | mapping := make(map[string]fs.DirEntry) 28 | err := fs.WalkDir(embedFS, path, func(path string, f fs.DirEntry, err error) error { 29 | if err != nil { 30 | return err 31 | } 32 | mapping[path] = f 33 | return nil 34 | }) 35 | 36 | if err != nil { 37 | return nil, fmt.Errorf("failed to walkDir: %w", err) 38 | } 39 | 40 | return mapping, nil 41 | } 42 | -------------------------------------------------------------------------------- /pkg/filematches/templates/invalid_template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | metadata: 3 | name: nginx 4 | spec: 5 | containers: 6 | - name: nginx 7 | image: nginx:1.14.2 8 | ports: 9 | - containerPort: 80 -------------------------------------------------------------------------------- /pkg/filematches/templates/valid_template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: nginx 5 | spec: 6 | containers: 7 | - name: nginx 8 | image: nginx:1.14.2 9 | ports: 10 | - containerPort: 80 11 | 12 | -------------------------------------------------------------------------------- /pkg/fixtures/addons/ingress/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | annotations: 5 | kubernetes.azure.com/tls-cert-keyvault-uri: "test.uri" 6 | kubernetes.azure.com/use-osm-mtls: "false" 7 | nginx.ingress.kubernetes.io/backend-protocol: HTTPS 8 | nginx.ingress.kubernetes.io/configuration-snippet: |2- 9 | 10 | proxy_ssl_name "default.test-namespace.cluster.local"; 11 | nginx.ingress.kubernetes.io/proxy-ssl-secret: kube-system/osm-ingress-client-cert 12 | nginx.ingress.kubernetes.io/proxy-ssl-verify: "on" 13 | name: "test-service" 14 | namespace: "test-namespace" 15 | labels: 16 | kubernetes.azure.com/generator: draft 17 | spec: 18 | ingressClassName: webapprouting.kubernetes.azure.com 19 | rules: 20 | - host: "host" 21 | http: 22 | paths: 23 | - backend: 24 | service: 25 | name: "test-service" 26 | port: 27 | number: 80 28 | path: / 29 | pathType: Prefix 30 | tls: 31 | - hosts: 32 | - "host" 33 | secretName: "keyvault-test-service" -------------------------------------------------------------------------------- /pkg/fixtures/deployments/helm/charts/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /pkg/fixtures/deployments/helm/charts/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: testapp 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.16.0" 25 | -------------------------------------------------------------------------------- /pkg/fixtures/deployments/helm/charts/production.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: "testimage" 3 | tag: "latest" 4 | pullPolicy: "Always" 5 | service: 6 | annotations: {} 7 | type: LoadBalancer 8 | port: "80" 9 | -------------------------------------------------------------------------------- /pkg/fixtures/deployments/helm/charts/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | 2 | {{- define "testapp.name" -}} 3 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 4 | {{- end }} 5 | 6 | 7 | {{- define "testapp.fullname" -}} 8 | {{- if .Values.fullnameOverride }} 9 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 10 | {{- else }} 11 | {{- $name := default .Chart.Name .Values.nameOverride }} 12 | {{- if contains $name .Release.Name }} 13 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 14 | {{- else }} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 16 | {{- end }} 17 | {{- end }} 18 | {{- end }} 19 | 20 | 21 | {{- define "testapp.chart" -}} 22 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 23 | {{- end }} 24 | 25 | 26 | {{- define "testapp.labels" -}} 27 | helm.sh/chart: {{ include "testapp.chart" . }} 28 | {{ include "testapp.selectorLabels" . }} 29 | kubernetes.azure.com/generator: {{ .Values.generatorLabel }} 30 | {{- if .Chart.AppVersion }} 31 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 32 | {{- end }} 33 | app.kubernetes.io/managed-by: {{ .Release.Service }} 34 | {{- end }} 35 | 36 | 37 | {{- define "testapp.selectorLabels" -}} 38 | app.kubernetes.io/name: {{ include "testapp.name" . }} 39 | app.kubernetes.io/instance: {{ .Release.Name }} 40 | {{- end }} -------------------------------------------------------------------------------- /pkg/fixtures/deployments/helm/charts/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ include "testapp.fullname" . }}-config 5 | labels: 6 | {{- include "testapp.labels" . | nindent 4 }} 7 | namespace: {{ .Values.namespace }} 8 | data: 9 | {{- range $key, $value := .Values.envVars }} 10 | {{ $key }}: {{ $value }} 11 | {{- end }} 12 | -------------------------------------------------------------------------------- /pkg/fixtures/deployments/helm/charts/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "testapp.fullname" . }} 5 | labels: 6 | {{- include "testapp.labels" . | nindent 4 }} 7 | annotations: 8 | {{ toYaml .Values.service.annotations | nindent 4 }} 9 | namespace: {{ .Values.namespace }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | ports: 13 | - port: {{ .Values.service.port }} 14 | targetPort: {{ .Values.containerPort }} 15 | protocol: TCP 16 | name: svchttp 17 | selector: 18 | {{- include "testapp.selectorLabels" . | nindent 6 }} 19 | -------------------------------------------------------------------------------- /pkg/fixtures/deployments/kustomize/base/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: testapp-config 5 | namespace: default 6 | labels: 7 | app.kubernetes.io/name: testapp 8 | kubernetes.azure.com/generator: draft 9 | data: -------------------------------------------------------------------------------- /pkg/fixtures/deployments/kustomize/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - deployment.yaml 5 | - service.yaml 6 | - configmap.yaml -------------------------------------------------------------------------------- /pkg/fixtures/deployments/kustomize/base/namespace.yaml: -------------------------------------------------------------------------------- 1 | kind: Namespace 2 | apiVersion: v1 3 | metadata: 4 | name: default 5 | labels: 6 | kubernetes.azure.com/generator: draft -------------------------------------------------------------------------------- /pkg/fixtures/deployments/kustomize/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: testapp 5 | namespace: default 6 | labels: 7 | app.kubernetes.io/name: testapp 8 | kubernetes.azure.com/generator: draft 9 | spec: 10 | type: LoadBalancer 11 | selector: 12 | app.kubernetes.io/name: testapp 13 | ports: 14 | - protocol: TCP 15 | port: 80 16 | targetPort: 80 -------------------------------------------------------------------------------- /pkg/fixtures/deployments/kustomize/overlays/production/deployment-override-workload-identity.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: testapp 5 | labels: 6 | app.kubernetes.io/name: testapp 7 | kubernetes.azure.com/generator: draft 8 | namespace: default 9 | spec: 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/name: testapp 13 | template: 14 | spec: 15 | containers: 16 | - name: testapp 17 | image: testimage:latest -------------------------------------------------------------------------------- /pkg/fixtures/deployments/kustomize/overlays/production/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: testapp 5 | labels: 6 | app.kubernetes.io/name: testapp 7 | kubernetes.azure.com/generator: draft 8 | namespace: default 9 | spec: 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/name: testapp 13 | template: 14 | spec: 15 | containers: 16 | - name: testapp 17 | image: testimage:latest -------------------------------------------------------------------------------- /pkg/fixtures/deployments/kustomize/overlays/production/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namePrefix: production- 2 | namespace: default 3 | resources: 4 | - ../../base 5 | patchesStrategicMerge: 6 | - deployment.yaml 7 | - service.yaml -------------------------------------------------------------------------------- /pkg/fixtures/deployments/kustomize/overlays/production/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: testapp 5 | namespace: default 6 | labels: 7 | app.kubernetes.io/name: testapp 8 | kubernetes.azure.com/generator: draft 9 | spec: 10 | type: LoadBalancer -------------------------------------------------------------------------------- /pkg/fixtures/deployments/manifest/manifests/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: testapp-config 5 | namespace: default 6 | labels: 7 | app.kubernetes.io/name: testapp 8 | kubernetes.azure.com/generator: draft 9 | data: 10 | key1: value1 11 | key2: value2 -------------------------------------------------------------------------------- /pkg/fixtures/deployments/manifest/manifests/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: testapp 5 | namespace: default 6 | labels: 7 | app.kubernetes.io/name: testapp 8 | kubernetes.azure.com/generator: draft 9 | spec: 10 | type: LoadBalancer 11 | selector: 12 | app.kubernetes.io/name: testapp 13 | ports: 14 | - protocol: TCP 15 | port: 80 16 | targetPort: 80 -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/clojure/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | resources/ 4 | target/ 5 | test/ 6 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/clojure/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM clojure as BUILD 2 | COPY . /usr/src/app 3 | WORKDIR /usr/src/app 4 | RUN lein ring uberjar 5 | 6 | FROM eclipse-temurin:19-jdk-alpine 7 | 8 | RUN apk update && apk upgrade && apk add bash 9 | ENV PORT 80 10 | EXPOSE 80 11 | COPY --from=BUILD /usr/src/app/target/*.jar /opt/ 12 | WORKDIR /opt 13 | CMD ["/bin/bash", "-c", "find -type f -name '*standalone.jar' | xargs java -jar"] 14 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/csharp/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | bin/ 4 | obj/ 5 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/csharp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/sdk:6.0 AS builder 2 | WORKDIR /app 3 | 4 | # caches restore result by copying csproj file separately 5 | COPY *.csproj . 6 | RUN dotnet restore 7 | 8 | COPY . . 9 | RUN dotnet publish --output /app/ --configuration Release --no-restore 10 | RUN sed -n 's:.*\(.*\).*:\1:p' *.csproj > __assemblyname 11 | RUN if [ ! -s __assemblyname ]; then filename=$(ls *.csproj); echo ${filename%.*} > __assemblyname; fi 12 | 13 | # Stage 2 14 | FROM mcr.microsoft.com/dotnet/aspnet:6.0 15 | WORKDIR /app 16 | COPY --from=builder /app . 17 | 18 | ENV PORT 80 19 | EXPOSE 80 20 | 21 | ENTRYPOINT dotnet $(cat /app/__assemblyname).dll --urls "http://*:80" 22 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/erlang/.dockerignore: -------------------------------------------------------------------------------- 1 | # files and directories to exclude from context 2 | Dockerfile 3 | _build -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/erlang/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM erlang:27.0-alpine as builder 2 | 3 | RUN apk add --update tar curl git bash make libc-dev gcc g++ && \ 4 | rm -rf /var/cache/apk/* 5 | 6 | RUN set -xe \ 7 | && curl -fSL -o rebar3 "https://s3.amazonaws.com/rebar3/rebar3" \ 8 | && chmod +x ./rebar3 \ 9 | && ./rebar3 local install \ 10 | && rm ./rebar3 11 | 12 | WORKDIR /usr/src/app 13 | COPY . /usr/src/app 14 | 15 | ENV PATH "$PATH:/root/.cache/rebar3/bin" 16 | RUN rebar3 as prod tar 17 | 18 | RUN mkdir -p /opt/rel 19 | RUN tar -zxvf /usr/src/app/_build/prod/rel/*/*.tar.gz -C /opt/rel 20 | 21 | RUN relname=$(ls _build/prod/rel) ; echo $relname > /opt/rel/__relname 22 | 23 | FROM alpine:3.17 24 | 25 | RUN apk add --no-cache openssl-dev ncurses libstdc++ libgcc 26 | 27 | WORKDIR /opt/rel 28 | 29 | ENV RELX_REPLACE_OS_VARS true 30 | ENV HTTP_PORT 80 31 | 32 | COPY --from=builder /opt/rel /opt/rel 33 | 34 | EXPOSE 80 80 35 | 36 | RUN ln -s /opt/rel/bin/$(cat /opt/rel/__relname) /opt/rel/bin/start_script 37 | ENTRYPOINT ["/opt/rel/bin/start_script"] 38 | 39 | CMD ["foreground"] 40 | 41 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/go/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/go/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23 2 | ENV PORT=80 3 | EXPOSE 80 4 | 5 | WORKDIR /go/src/app 6 | COPY . . 7 | 8 | ARG GO111MODULE=off 9 | RUN go build -v -o app ./main.go 10 | RUN mv ./app /go/bin/ 11 | 12 | CMD ["app"] -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/gomodule/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/gomodule/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23 AS builder 2 | 3 | WORKDIR /build 4 | COPY go.mod go.sum ./ 5 | RUN go mod download && go mod verify 6 | COPY . . 7 | RUN CGO_ENABLED=0 GOOS=linux go build -v -o app-binary 8 | 9 | FROM gcr.io/distroless/static-debian12 10 | 11 | ENV PORT=80 12 | EXPOSE 80 13 | 14 | WORKDIR /app 15 | COPY --from=builder /build/app-binary . 16 | CMD ["/app/app-binary"] 17 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/gradle/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/gradle/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gradle:jdk21 as BUILD 2 | 3 | COPY --chown=gradle:gradle . /project 4 | RUN gradle -i -s -b /project/build.gradle clean build 5 | 6 | FROM eclipse-temurin:21-jre 7 | ENV PORT 80 8 | EXPOSE 80 9 | 10 | COPY --from=BUILD /project/build/libs/* /opt/ 11 | WORKDIR /opt/ 12 | RUN ls -l 13 | CMD ["/bin/bash", "-c", "find -type f -name '*SNAPSHOT.jar' | xargs java -jar"] 14 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/gradlew/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/gradlew/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gradle:jdk21 as BUILD 2 | 3 | COPY --chown=gradle:gradle . /project 4 | COPY gradlew gradlew 5 | COPY gradle/wrapper gradle/wrapper 6 | RUN chmod +x gradle/wrapper 7 | RUN chmod +x gradlew 8 | RUN ./gradlew -i -s -b /project/build.gradle clean build 9 | 10 | FROM eclipse-temurin:21-jre 11 | ENV PORT 80 12 | EXPOSE 80 13 | 14 | COPY --from=BUILD /project/build/libs/* /opt/ 15 | WORKDIR /opt/ 16 | RUN ls -l 17 | CMD ["/bin/bash", "-c", "find -type f -name '*SNAPSHOT.jar' | xargs java -jar"] -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/java/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | target/ 4 | work/ 5 | .git/ 6 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/java/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM maven:3 as BUILD 2 | 3 | COPY . /usr/src/app 4 | RUN mvn --batch-mode -f /usr/src/app/pom.xml clean package 5 | 6 | FROM eclipse-temurin:21-jre 7 | ENV PORT 80 8 | EXPOSE 80 9 | COPY --from=BUILD /usr/src/app/target /opt/target 10 | WORKDIR /opt/target 11 | 12 | CMD ["/bin/bash", "-c", "find -type f -name '*-SNAPSHOT.jar' | xargs java -jar"] 13 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/javascript/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/javascript/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14.15.4 2 | ENV PORT 80 3 | EXPOSE 80 4 | 5 | RUN mkdir -p /usr/src/app 6 | WORKDIR /usr/src/app 7 | COPY package.json . 8 | RUN npm install 9 | COPY . . 10 | 11 | CMD ["npm", "start"] 12 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/php/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/php/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM composer:1 AS build-env 2 | COPY . /app 3 | RUN cd /app && composer install 4 | 5 | FROM php:7.1-apache 6 | ENV PORT 80 7 | EXPOSE 80 8 | COPY --from=build-env /app /var/www/html 9 | RUN usermod -u 1000 www-data; \ 10 | a2enmod rewrite; \ 11 | chown -R www-data:www-data /var/www/html 12 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/python/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/python/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.9 2 | ENV PORT 80 3 | EXPOSE 80 4 | WORKDIR /usr/src/app 5 | 6 | COPY requirements.txt ./ 7 | RUN pip install --no-cache-dir -r requirements.txt 8 | 9 | COPY . . 10 | 11 | ENTRYPOINT ["python"] 12 | CMD ["app.py"] -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/ruby/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | tmp/ 4 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/ruby/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:3.1.2 2 | ENV PORT 80 3 | EXPOSE 80 4 | RUN bundle config --global frozen 1 5 | 6 | WORKDIR /usr/src/app 7 | 8 | COPY Gemfile Gemfile.lock ./ 9 | RUN bundle install 10 | 11 | COPY . . 12 | CMD ["ruby", "app.rb"] 13 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/rust/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | target 4 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/rust/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.70.0 2 | 3 | WORKDIR /usr/src/app 4 | COPY . /usr/src/app 5 | RUN cargo build 6 | 7 | ENV PORT 80 8 | EXPOSE 80 9 | 10 | CMD ["cargo", "run", "-q"] 11 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/swift/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | charts/ 3 | -------------------------------------------------------------------------------- /pkg/fixtures/dockerfiles/swift/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM swift:5.5 2 | 3 | WORKDIR /src 4 | COPY . /src 5 | RUN apt-get update && apt-get install -y sudo openssl libssl-dev libcurl4-openssl-dev 6 | RUN swift build -c release 7 | 8 | ENV PORT 80 9 | EXPOSE 80 10 | 11 | CMD ["swift", "run"] 12 | -------------------------------------------------------------------------------- /pkg/fixtures/manifests/hpa/hpa-memory.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v2 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: test-app 5 | labels: 6 | app.kubernetes.io/name: test-app 7 | app.kubernetes.io/part-of: test-app-project 8 | kubernetes.azure.com/generator: draft 9 | spec: 10 | scaleTargetRef: 11 | apiVersion: apps/v1 12 | kind: Deployment 13 | name: test-app 14 | minReplicas: 2 15 | maxReplicas: 5 16 | metrics: 17 | - type: Resource 18 | resource: 19 | name: memory 20 | target: 21 | type: Utilization 22 | averageUtilization: 80 -------------------------------------------------------------------------------- /pkg/fixtures/manifests/hpa/hpa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v2 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: test-app 5 | labels: 6 | app.kubernetes.io/name: test-app 7 | app.kubernetes.io/part-of: test-app-project 8 | kubernetes.azure.com/generator: draft 9 | spec: 10 | scaleTargetRef: 11 | apiVersion: apps/v1 12 | kind: Deployment 13 | name: test-app 14 | minReplicas: 2 15 | maxReplicas: 5 16 | metrics: 17 | - type: Resource 18 | resource: 19 | name: cpu 20 | target: 21 | type: Utilization 22 | averageUtilization: 80 -------------------------------------------------------------------------------- /pkg/fixtures/manifests/ingress/ingress-simple.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | annotations: 5 | name: "test-ingress" 6 | namespace: "default" 7 | labels: 8 | app.kubernetes.io/name: test-ingress 9 | app.kubernetes.io/part-of: test-app 10 | kubernetes.azure.com/generator: draft 11 | spec: 12 | ingressClassName: nginx 13 | rules: 14 | - host: "test-host.com" 15 | http: 16 | paths: 17 | - backend: 18 | service: 19 | name: "test-service" 20 | port: 21 | number: 80 22 | path: "/" 23 | pathType: Prefix -------------------------------------------------------------------------------- /pkg/fixtures/manifests/ingress/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | annotations: 5 | kubernetes.azure.com/tls-cert-keyvault-managed: "true" 6 | kubernetes.azure.com/tls-cert-keyvault-uri: "test.uri" 7 | name: "test-ingress" 8 | namespace: "default" 9 | labels: 10 | app.kubernetes.io/name: test-ingress 11 | app.kubernetes.io/part-of: test-app 12 | kubernetes.azure.com/generator: draft 13 | spec: 14 | ingressClassName: webapprouting.kubernetes.azure.com 15 | rules: 16 | - host: "test-host.com" 17 | http: 18 | paths: 19 | - backend: 20 | service: 21 | name: "test-service" 22 | port: 23 | number: 80 24 | path: "/test/path" 25 | pathType: Prefix 26 | tls: 27 | - hosts: 28 | - "test-host.com" 29 | secretName: "keyvault-test-ingress" 30 | -------------------------------------------------------------------------------- /pkg/fixtures/manifests/pdb/pdb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: test-app 5 | labels: 6 | app.kubernetes.io/name: test-app 7 | app.kubernetes.io/part-of: test-app-project 8 | kubernetes.azure.com/generator: draft 9 | spec: 10 | maxUnavailable: 1 11 | selector: 12 | matchLabels: 13 | app: test-app -------------------------------------------------------------------------------- /pkg/fixtures/manifests/service/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: test-app 5 | labels: 6 | app.kubernetes.io/name: test-app 7 | app.kubernetes.io/part-of: test-app-project 8 | kubernetes.azure.com/generator: draft 9 | spec: 10 | type: ClusterIP 11 | selector: 12 | app: test-app 13 | ports: 14 | - protocol: TCP 15 | port: 80 16 | targetPort: 80 -------------------------------------------------------------------------------- /pkg/fixtures/validatetemplate.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "regexp" 7 | "strings" 8 | 9 | "github.com/google/go-cmp/cmp" 10 | ) 11 | 12 | func ValidateContentAgainstFixture(generatedContent []byte, fixturePath string) error { 13 | got := generatedContent 14 | // Read the fixture content 15 | want, err := os.ReadFile(fixturePath) 16 | if err != nil { 17 | return fmt.Errorf("failed to read fixture: %w", err) 18 | } 19 | 20 | if normalizeWhitespace(want) != normalizeWhitespace(got) { 21 | if diff := cmp.Diff(string(want), string(got)); diff != "" { 22 | fmt.Println("Diff for file ", fixturePath, " (-want +got)") 23 | fmt.Printf(diff) 24 | return fmt.Errorf("generated content does not match fixture for file %s, check above for rich diff", fixturePath) 25 | } 26 | 27 | } 28 | 29 | return nil 30 | } 31 | 32 | func normalizeWhitespace(content []byte) string { 33 | s := string(content) 34 | re := regexp.MustCompile(`\r?\n`) 35 | s = re.ReplaceAllString(s, "\n") 36 | re = regexp.MustCompile(`\s+`) 37 | return strings.TrimSpace(re.ReplaceAllString(s, " ")) 38 | } 39 | -------------------------------------------------------------------------------- /pkg/handlers/template_test.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | 7 | "github.com/Azure/draft/pkg/templatewriter/writers" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestDeepCopy(t *testing.T) { 12 | // This will fail on adding a new field to the undelying structs that arent handled in DeepCopy 13 | testTemplate, err := GetTemplate("deployment-manifests", "0.0.1", ".", &writers.FileMapWriter{}) 14 | assert.Nil(t, err) 15 | 16 | deepCopy := testTemplate.DeepCopy() 17 | 18 | assert.True(t, reflect.DeepEqual(deepCopy, testTemplate)) 19 | } 20 | -------------------------------------------------------------------------------- /pkg/handlers/template_utils_test.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestGetTemplate(t *testing.T) { 10 | loadedTemplates := GetTemplates() 11 | assert.Positive(t, len(loadedTemplates)) 12 | } 13 | 14 | func TestLoadTemplates(t *testing.T) { 15 | templateConfigs = nil 16 | err := loadTemplates() 17 | assert.Nil(t, err) 18 | loadedTemplates := GetTemplates() 19 | assert.Positive(t, len(loadedTemplates)) 20 | } 21 | -------------------------------------------------------------------------------- /pkg/handlers/templatetests/deployment_helm_test.go: -------------------------------------------------------------------------------- 1 | package templatetests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Azure/draft/pkg/templatewriter/writers" 7 | ) 8 | 9 | func TestDeploymentHelmTemplates(t *testing.T) { 10 | tests := []TestInput{ 11 | { 12 | Name: "valid helm deployment", 13 | TemplateName: "deployment-helm", 14 | FixturesBaseDir: "../../fixtures/deployments/helm", 15 | Version: "0.0.1", 16 | Dest: ".", 17 | TemplateWriter: &writers.FileMapWriter{}, 18 | VarMap: map[string]string{ 19 | "APPNAME": "testapp", 20 | "NAMESPACE": "default", 21 | "PORT": "80", 22 | "IMAGENAME": "testimage", 23 | "IMAGETAG": "latest", 24 | "GENERATORLABEL": "draft", 25 | "SERVICEPORT": "80", 26 | }, 27 | }, 28 | } 29 | 30 | for _, test := range tests { 31 | RunTemplateTest(t, test) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pkg/handlers/templatetests/manifests_pdb_test.go: -------------------------------------------------------------------------------- 1 | package templatetests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Azure/draft/pkg/templatewriter/writers" 7 | ) 8 | 9 | func TestManifestsPDBTemplates(t *testing.T) { 10 | tests := []TestInput{ 11 | { 12 | Name: "valid pdb manifest", 13 | TemplateName: "podDisruptionBudget-manifests", 14 | FixturesBaseDir: "../../fixtures/manifests/pdb", 15 | Version: "0.0.1", 16 | Dest: ".", 17 | TemplateWriter: &writers.FileMapWriter{}, 18 | VarMap: map[string]string{ 19 | "APPNAME": "test-app", 20 | "PARTOF": "test-app-project", 21 | }, 22 | }, 23 | } 24 | 25 | for _, test := range tests { 26 | RunTemplateTest(t, test) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pkg/handlers/templatetests/manifests_service_test.go: -------------------------------------------------------------------------------- 1 | package templatetests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Azure/draft/pkg/templatewriter/writers" 7 | ) 8 | 9 | func TestManifestsServiceTemplates(t *testing.T) { 10 | tests := []TestInput{ 11 | { 12 | Name: "valid service manifest", 13 | TemplateName: "service-manifests", 14 | FixturesBaseDir: "../../fixtures/manifests/service", 15 | Version: "0.0.1", 16 | Dest: ".", 17 | TemplateWriter: &writers.FileMapWriter{}, 18 | VarMap: map[string]string{ 19 | "APPNAME": "test-app", 20 | "PARTOF": "test-app-project", 21 | }, 22 | }, 23 | } 24 | 25 | for _, test := range tests { 26 | RunTemplateTest(t, test) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pkg/handlers/templatetests/workflows_azure_kustomize_test.go: -------------------------------------------------------------------------------- 1 | package templatetests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Azure/draft/pkg/templatewriter/writers" 7 | ) 8 | 9 | func TestAzureWorkflowKustomizeTemplates(t *testing.T) { 10 | tests := []TestInput{ 11 | { 12 | Name: "valid azpipeline manifests deployment", 13 | TemplateName: "azure-pipeline-kustomize", 14 | FixturesBaseDir: "../../fixtures/workflows/azurepipelines/kustomize", 15 | Version: "0.0.1", 16 | Dest: ".", 17 | TemplateWriter: &writers.FileMapWriter{}, 18 | VarMap: map[string]string{ 19 | "ARMSERVICECONNECTION": "testserviceconnection", 20 | "AZURECONTAINERREGISTRY": "myacr.acr.io", 21 | "CONTAINERNAME": "myapp", 22 | "CLUSTERRESOURCEGROUP": "myrg", 23 | "ACRRESOURCEGROUP": "myrg", 24 | "CLUSTERNAME": "testcluster", 25 | }, 26 | }, 27 | } 28 | 29 | for _, test := range tests { 30 | RunTemplateTest(t, test) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pkg/handlers/templatetests/workflows_azure_manifest_test.go: -------------------------------------------------------------------------------- 1 | package templatetests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Azure/draft/pkg/templatewriter/writers" 7 | ) 8 | 9 | func TestAzureWorkflowManifestTemplates(t *testing.T) { 10 | tests := []TestInput{ 11 | { 12 | Name: "valid azpipeline manifests deployment", 13 | TemplateName: "azure-pipeline-manifests", 14 | FixturesBaseDir: "../../fixtures/workflows/azurepipelines/manifests", 15 | Version: "0.0.1", 16 | Dest: ".", 17 | TemplateWriter: &writers.FileMapWriter{}, 18 | VarMap: map[string]string{ 19 | "ARMSERVICECONNECTION": "testserviceconnection", 20 | "AZURECONTAINERREGISTRY": "myacr.acr.io", 21 | "CONTAINERNAME": "myapp", 22 | "CLUSTERRESOURCEGROUP": "myrg", 23 | "ACRRESOURCEGROUP": "myrg", 24 | "CLUSTERNAME": "testcluster", 25 | }, 26 | }, 27 | } 28 | 29 | for _, test := range tests { 30 | RunTemplateTest(t, test) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pkg/handlers/templatetests/workflows_github_helm_test.go: -------------------------------------------------------------------------------- 1 | package templatetests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Azure/draft/pkg/templatewriter/writers" 7 | ) 8 | 9 | func TestGitHubWorkflowHelmTemplates(t *testing.T) { 10 | tests := []TestInput{ 11 | { 12 | Name: "valid helm workflow", 13 | TemplateName: "github-workflow-helm", 14 | FixturesBaseDir: "../../fixtures/workflows/github/helm", 15 | Version: "0.0.1", 16 | Dest: ".", 17 | TemplateWriter: &writers.FileMapWriter{}, 18 | VarMap: map[string]string{ 19 | "WORKFLOWNAME": "testWorkflow", 20 | "BRANCHNAME": "testBranch", 21 | "ACRRESOURCEGROUP": "testAcrRG", 22 | "AZURECONTAINERREGISTRY": "testAcr", 23 | "CONTAINERNAME": "testContainer", 24 | "CLUSTERRESOURCEGROUP": "testClusterRG", 25 | "CLUSTERRESOURCETYPE": "Microsoft.ContainerService/managedClusters", 26 | "CLUSTERNAME": "testCluster", 27 | "KUSTOMIZEPATH": "./overlays/production", 28 | "DEPLOYMENTMANIFESTPATH": "./manifests", 29 | "DOCKERFILE": "./Dockerfile", 30 | "BUILDCONTEXTPATH": "test", 31 | "CHARTPATH": "testPath", 32 | "CHARTOVERRIDEPATH": "testOverridePath", 33 | "CHARTOVERRIDES": "replicas:2", 34 | "NAMESPACE": "default", 35 | }, 36 | }, 37 | } 38 | 39 | for _, test := range tests { 40 | RunTemplateTest(t, test) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pkg/handlers/templatetests/workflows_github_kustomize_test.go: -------------------------------------------------------------------------------- 1 | package templatetests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Azure/draft/pkg/templatewriter/writers" 7 | ) 8 | 9 | func TestGitHubWorkflowKustomizeTemplates(t *testing.T) { 10 | tests := []TestInput{ 11 | { 12 | Name: "valid kustomize workflow", 13 | TemplateName: "github-workflow-kustomize", 14 | FixturesBaseDir: "../../fixtures/workflows/github/kustomize", 15 | Version: "0.0.1", 16 | Dest: ".", 17 | TemplateWriter: &writers.FileMapWriter{}, 18 | VarMap: map[string]string{ 19 | "WORKFLOWNAME": "testWorkflow", 20 | "BRANCHNAME": "testBranch", 21 | "ACRRESOURCEGROUP": "testAcrRG", 22 | "AZURECONTAINERREGISTRY": "testAcr", 23 | "CONTAINERNAME": "testContainer", 24 | "CLUSTERRESOURCEGROUP": "testClusterRG", 25 | "CLUSTERRESOURCETYPE": "Microsoft.ContainerService/managedClusters", 26 | "CLUSTERNAME": "testCluster", 27 | "DEPLOYMENTMANIFESTPATH": "./manifests", 28 | "DOCKERFILE": "./Dockerfile", 29 | "BUILDCONTEXTPATH": "test", 30 | "NAMESPACE": "default", 31 | }, 32 | }, 33 | } 34 | 35 | for _, test := range tests { 36 | RunTemplateTest(t, test) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pkg/handlers/variableextractors/defaults/testdata/sample.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.6.3' 3 | id 'io.spring.dependency-management' version '1.0.11.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'com.example' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = "11" 10 | targetCompatibility = '11' 11 | 12 | configurations { 13 | compileOnly { 14 | extendsFrom annotationProcessor 15 | } 16 | } 17 | 18 | repositories { 19 | mavenCentral() 20 | } 21 | 22 | bootRun { 23 | args = ['--server.port=8081'] 24 | } 25 | 26 | dependencies { 27 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 28 | implementation 'org.springframework.boot:spring-boot-starter-web' 29 | implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml' 30 | implementation 'com.networknt:json-schema-validator:1.0.66' 31 | compileOnly 'org.projectlombok:lombok' 32 | runtimeOnly 'com.h2database:h2' 33 | annotationProcessor 'org.projectlombok:lombok' 34 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 35 | } 36 | 37 | tasks.named('test') { 38 | useJUnitPlatform() 39 | } -------------------------------------------------------------------------------- /pkg/linguist/README.md: -------------------------------------------------------------------------------- 1 | # linguist 2 | 3 | Go port of github linguist. 4 | 5 | ## Updating linguist 6 | 7 | To update to the latest version of linguist, run 8 | 9 | ``` 10 | git clone https://github.com/github/linguist data/linguist 11 | GO111MODULE=off go generate . 12 | GO111MODULE=off go generate ./data 13 | rm -rf data/linguist 14 | ``` 15 | -------------------------------------------------------------------------------- /pkg/linguist/data/classifier: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/draft/9e9240a6a0cce34ad92a09634b0fe2edc4bc0145/pkg/linguist/data/classifier -------------------------------------------------------------------------------- /pkg/linguist/data/documentation.yml: -------------------------------------------------------------------------------- 1 | # Documentation files and directories are excluded from language 2 | # statistics. 3 | # 4 | # Lines in this file are Regexps that are matched against the file 5 | # pathname. 6 | # 7 | # Please add additional test coverage to 8 | # `test/test_blob.rb#test_documentation` if you make any changes. 9 | 10 | ## Documentation directories ## 11 | 12 | - ^[Dd]ocs?/ 13 | - (^|/)[Dd]ocumentation/ 14 | - (^|/)[Gg]roovydoc/ 15 | - (^|/)[Jj]avadoc/ 16 | - ^[Mm]an/ 17 | - ^[Ee]xamples/ 18 | - ^[Dd]emos?/ 19 | - (^|/)inst/doc/ 20 | 21 | ## Documentation files ## 22 | 23 | - (^|/)CITATION(\.cff|(S)?(\.(bib|md))?)$ 24 | - (^|/)CHANGE(S|LOG)?(\.|$) 25 | - (^|/)CONTRIBUTING(\.|$) 26 | - (^|/)COPYING(\.|$) 27 | - (^|/)INSTALL(\.|$) 28 | - (^|/)LICEN[CS]E(\.|$) 29 | - (^|/)[Ll]icen[cs]e(\.|$) 30 | - (^|/)README(\.|$) 31 | - (^|/)[Rr]eadme(\.|$) 32 | 33 | # Samples folders 34 | - ^[Ss]amples?/ 35 | -------------------------------------------------------------------------------- /pkg/linguist/data/generate.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | //go:generate go run generate_classifier.go 4 | //go:generate go-bindata -pkg data -o data.go classifier 5 | -------------------------------------------------------------------------------- /pkg/linguist/generate.go: -------------------------------------------------------------------------------- 1 | package linguist 2 | 3 | //go:generate cp data/linguist/lib/linguist/languages.yml data/ 4 | //go:generate cp data/linguist/lib/linguist/documentation.yml data/ 5 | //go:generate cp data/linguist/lib/linguist/vendor.yml data/ 6 | //go:generate go run generate_static.go data/languages.yml data/vendor.yml data/documentation.yml 7 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-documentation/.gitattributes: -------------------------------------------------------------------------------- 1 | docs/ linguist-documentation=true 2 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-documentation/app.py: -------------------------------------------------------------------------------- 1 | print("Hello, World!") 2 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-duck/.gitattributes: -------------------------------------------------------------------------------- 1 | *.duck linguist-language=Duck 2 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-duck/main.duck: -------------------------------------------------------------------------------- 1 | #!/bin/quack 2 | 3 | quack! 4 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-emptydir/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/draft/9e9240a6a0cce34ad92a09634b0fe2edc4bc0145/pkg/linguist/testdirs/app-emptydir/.gitkeep -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-generated/.gitattributes: -------------------------------------------------------------------------------- 1 | man1/ linguist-generated 2 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-generated/src/app.py: -------------------------------------------------------------------------------- 1 | print("Hello, World!") 2 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-not-vendored/.gitattributes: -------------------------------------------------------------------------------- 1 | vendor.html linguist-vendored=FaLsE 2 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-not-vendored/app.py: -------------------------------------------------------------------------------- 1 | print("Hello, World!") 2 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-not-vendored/vendor.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | This is title 4 |
5 | 6 |

Hello, World!

7 | 8 | 9 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-python/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route('/') 5 | def hello_world(): 6 | return "Hello, World!\n" 7 | 8 | if __name__ == '__main__': 9 | app.run(host='0.0.0.0', port=8080) 10 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-python/requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-vendored/.gitattributes: -------------------------------------------------------------------------------- 1 | vendor.html linguist-vendored 2 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-vendored/app.py: -------------------------------------------------------------------------------- 1 | print("Hello, World!") 2 | -------------------------------------------------------------------------------- /pkg/linguist/testdirs/app-vendored/vendor.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | This is title 4 |
5 | 6 |

Hello, World!

7 | 8 | 9 | -------------------------------------------------------------------------------- /pkg/logger/logger.go: -------------------------------------------------------------------------------- 1 | package logger 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "os" 7 | "strings" 8 | 9 | "github.com/fatih/color" 10 | log "github.com/sirupsen/logrus" 11 | ) 12 | 13 | type CustomFormatter struct {} 14 | 15 | func (f *CustomFormatter) Format(entry *log.Entry) ([]byte, error) { 16 | cyan := color.New(color.Bold, color.FgCyan).SprintFunc() 17 | red := color.New(color.Bold, color.FgRed).SprintFunc() 18 | level := strings.Title(entry.Level.String()) 19 | if (level == "Error" || level == "Fatal" || level == "Panic") { 20 | return []byte(fmt.Sprintf("%s: %s\n",red(level), entry.Message)), nil 21 | } 22 | return []byte(fmt.Sprintf("%s %s\n",cyan("[Draft]"), entry.Message)), nil 23 | } 24 | 25 | type OutputSplitter struct{} 26 | 27 | func (splitter *OutputSplitter) Write(p []byte) (n int, err error) { 28 | if bytes.Contains(p, []byte("Error")) || bytes.Contains(p, []byte("Fatal")) || bytes.Contains(p, []byte("Panic")) { 29 | return os.Stderr.Write(p) 30 | } 31 | return os.Stdout.Write(p) 32 | } -------------------------------------------------------------------------------- /pkg/providers/azcli_test.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestCheckAzCliInstalled(t *testing.T) { 10 | az := &AzClient{CommandRunner: &FakeCommandRunner{Output: `{ 11 | "azure-cli": "2.65.0", 12 | "azure-cli-core": "2.65.0", 13 | "azure-cli-telemetry": "1.1.0", 14 | "extensions": {} 15 | }`}} 16 | err := az.ValidateAzCliInstalled() 17 | assert.Nil(t, err) 18 | } 19 | func TestCheckAzCliInstalledError(t *testing.T) { 20 | az := &AzClient{CommandRunner: &FakeCommandRunner{Output: "az", ErrStr: "error"}} 21 | err := az.ValidateAzCliInstalled() 22 | assert.NotNil(t, err) 23 | } 24 | -------------------------------------------------------------------------------- /pkg/providers/commandrunner.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "errors" 5 | "os/exec" 6 | 7 | log "github.com/sirupsen/logrus" 8 | ) 9 | 10 | // CommandRunner is an interface for executing commands and getting the output/error 11 | type CommandRunner interface { 12 | RunCommand(...string) (string, error) 13 | } 14 | 15 | type DefaultCommandRunner struct{} 16 | 17 | var _ CommandRunner = &DefaultCommandRunner{} 18 | 19 | func (d *DefaultCommandRunner) RunCommand(args ...string) (string, error) { 20 | log.Debug("Running command: ", args) 21 | cmd := exec.Command(args[0], args[1:]...) 22 | out, err := cmd.CombinedOutput() 23 | return string(out), err 24 | } 25 | 26 | type FakeCommandRunner struct { 27 | Output string 28 | ErrStr string 29 | } 30 | 31 | var _ CommandRunner = &FakeCommandRunner{} 32 | 33 | func (f *FakeCommandRunner) RunCommand(args ...string) (string, error) { 34 | if f.ErrStr != "" { 35 | return f.Output, errors.New(f.ErrStr) 36 | } 37 | return f.Output, nil 38 | } 39 | -------------------------------------------------------------------------------- /pkg/providers/ghcli_test.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestHasGhCli(t *testing.T) { 8 | cr := &FakeCommandRunner{ 9 | Output: "gh version 1.0.0", 10 | } 11 | gh := &GhCliClient{ 12 | CommandRunner: cr, 13 | } 14 | gh.EnsureGhCliInstalled() 15 | } 16 | -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v1.0.0/container-allowed-images/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV2ContainerAllowedImages 3 | metadata: 4 | name: v2-container-allowed-images 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Pod"] 10 | parameters: 11 | imageRegex: .* 12 | excludedContainers: [] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v1.0.0/container-enforce-probes/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV2ContainerEnforceProbes 3 | metadata: 4 | name: v2-container-enforce-probes 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Pod"] 10 | parameters: 11 | enforceProbes : ["readinessProbe","livenessProbe"] 12 | excludedContainers: [] 13 | excludedImages: [] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v1.0.0/container-resource-limits/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV3ContainerLimits 3 | metadata: 4 | name: v3-container-limits 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Pod"] 10 | parameters: 11 | cpuLimit : "200m" 12 | memoryLimit: "1Gi" 13 | excludedContainers: [] 14 | excludedImages: [] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v1.0.0/container-restricted-image-pulls/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1ContainerRestrictedImagePulls 3 | metadata: 4 | name: v1-container-restricted-image-pulls 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Pod"] 10 | parameters: 11 | excludedImages: [] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v1.0.0/disallowed-bad-pod-disruption-budgets/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1DisallowedBadPodDisruptionBudgets 3 | metadata: 4 | name: v1-disallowed-bad-pod-disruption-budgets 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: ["apps"] 9 | kinds: ["Deployment", "ReplicaSet", "StatefulSet"] 10 | - apiGroups: ["policy"] 11 | kinds: ["PodDisruptionBudget"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v1.0.0/pod-enforce-antiaffinity/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1AntiAffinityRules 3 | metadata: 4 | name: v1-multiple-replicas-need-anti-affinity 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: ["apps"] 9 | kinds: ["Deployment","StatefulSet","ReplicationController","ReplicaSet"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v1.0.0/pod-enforce-antiaffinity/template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: templates.gatekeeper.sh/v1beta1 2 | kind: ConstraintTemplate 3 | metadata: 4 | name: k8sazurev1antiaffinityrules 5 | annotations: 6 | description: Requires deployments with multiple replicas have pod anti affinity rules 7 | spec: 8 | crd: 9 | spec: 10 | names: 11 | kind: K8sAzureV1AntiAffinityRules 12 | targets: 13 | - target: admission.k8s.gatekeeper.sh 14 | rego: | 15 | package k8sazurev1antiaffinityrules 16 | 17 | missing_affinity(obj) { 18 | not obj.affinity.podAntiAffinity 19 | } 20 | 21 | violation[{"msg": msg}] { 22 | input.review.object.spec.replicas > 1 23 | missing_affinity(input.review.object.spec.template.spec) 24 | msg := sprintf("%s with %d replicas should have pod anti-affinity rules set to avoid disruptions due to nodes crashing", [input.review.kind.kind, input.review.object.spec.replicas]) 25 | } -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v1.0.0/restricted-taints/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1ReservedTaints 3 | metadata: 4 | name: v1-system-reserved-taints 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Node"] 10 | parameters: 11 | reservedTaints: ["CriticalAddonsOnly"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v1.0.0/unique-service-selectors/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1UniqueServiceSelector 3 | metadata: 4 | name: v1-unique-service-selector 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Service"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v2.0.0/container-allowed-images/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV2ContainerAllowedImages 3 | metadata: 4 | name: v2-container-allowed-images 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Pod"] 10 | parameters: 11 | imageRegex: .* 12 | excludedContainers: [] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v2.0.0/container-enforce-probes/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV2ContainerEnforceProbes 3 | metadata: 4 | name: v2-container-enforce-probes 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Pod"] 10 | parameters: 11 | enforceProbes : ["readinessProbe","livenessProbe"] 12 | excludedContainers: [] 13 | excludedImages: [] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v2.0.0/container-resource-limits/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV3ContainerLimits 3 | metadata: 4 | name: v3-container-limits 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Pod"] 10 | parameters: 11 | cpuLimit : "2" 12 | memoryLimit: "1Gi" 13 | excludedContainers: [] 14 | excludedImages: [] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v2.0.0/container-restricted-image-pulls/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1ContainerRestrictedImagePulls 3 | metadata: 4 | name: v1-container-restricted-image-pulls 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Pod"] 10 | parameters: 11 | excludedImages: [] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v2.0.0/disallowed-bad-pod-disruption-budgets/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1DisallowedBadPodDisruptionBudgets 3 | metadata: 4 | name: v1-disallowed-bad-pod-disruption-budgets 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: ["apps"] 9 | kinds: ["Deployment", "ReplicaSet", "StatefulSet"] 10 | - apiGroups: ["policy"] 11 | kinds: ["PodDisruptionBudget"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v2.0.0/pod-enforce-antiaffinity/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1AntiAffinityRules 3 | metadata: 4 | name: v1-multiple-replicas-need-anti-affinity 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: ["apps"] 9 | kinds: ["Deployment","StatefulSet","ReplicationController","ReplicaSet"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v2.0.0/pod-enforce-antiaffinity/template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: templates.gatekeeper.sh/v1beta1 2 | kind: ConstraintTemplate 3 | metadata: 4 | name: k8sazurev1antiaffinityrules 5 | annotations: 6 | description: Requires deployments with multiple replicas have pod anti affinity rules 7 | spec: 8 | crd: 9 | spec: 10 | names: 11 | kind: K8sAzureV1AntiAffinityRules 12 | targets: 13 | - target: admission.k8s.gatekeeper.sh 14 | rego: | 15 | package k8sazurev1antiaffinityrules 16 | 17 | missing_affinity(obj) { 18 | not obj.affinity.podAntiAffinity 19 | } 20 | 21 | violation[{"msg": msg}] { 22 | input.review.object.spec.replicas > 1 23 | missing_affinity(input.review.object.spec.template.spec) 24 | msg := sprintf("%s with %d replicas should have pod anti-affinity rules set to avoid disruptions due to nodes crashing", [input.review.kind.kind, input.review.object.spec.replicas]) 25 | } -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v2.0.0/restricted-taints/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1ReservedTaints 3 | metadata: 4 | name: v1-system-reserved-taints 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Node"] 10 | parameters: 11 | reservedTaints: ["CriticalAddonsOnly"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/manifests/v2.0.0/unique-service-selectors/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1UniqueServiceSelector 3 | metadata: 4 | name: v1-unique-service-selector 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Service"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/v1.0.0/container-allowed-images/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV2ContainerAllowedImages 3 | metadata: 4 | name: v2-container-allowed-images 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: ["apps"] 9 | kinds: ["Deployment"] 10 | parameters: 11 | imageRegex: ".*" 12 | excludedContainers: [] -------------------------------------------------------------------------------- /pkg/safeguards/lib/v1.0.0/container-enforce-probes/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV2ContainerEnforceProbes 3 | metadata: 4 | name: v2-container-enforce-probes 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: ["apps"] 9 | kinds: ["Deployment"] 10 | - apiGroups: [""] 11 | kinds: ["Pod"] 12 | parameters: 13 | enforceProbes : ["livenessProbe", "readinessProbe"] 14 | excludedContainers: [] 15 | excludedImages: [] 16 | -------------------------------------------------------------------------------- /pkg/safeguards/lib/v1.0.0/container-resource-limits/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV3ContainerLimits 3 | metadata: 4 | name: v3-container-limits 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Pod"] 10 | parameters: 11 | cpuLimit : "200m" 12 | memoryLimit: "1Gi" 13 | excludedContainers: [] 14 | excludedImages: [] 15 | -------------------------------------------------------------------------------- /pkg/safeguards/lib/v1.0.0/container-restricted-image-pulls/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1ContainerRestrictedImagePulls 3 | metadata: 4 | name: v1-container-restricted-image-pulls 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Pod"] 10 | - apiGroups: ["apps"] 11 | kinds: ["Deployment"] 12 | parameters: 13 | excludedImages: [] 14 | -------------------------------------------------------------------------------- /pkg/safeguards/lib/v1.0.0/disallowed-bad-pod-disruption-budgets/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1DisallowedBadPodDisruptionBudgets 3 | metadata: 4 | name: v1-disallowed-bad-pod-disruption-budgets 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: ["apps"] 9 | kinds: ["Deployment", "ReplicaSet", "StatefulSet"] 10 | - apiGroups: ["policy"] 11 | kinds: ["PodDisruptionBudget"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/v1.0.0/pod-enforce-antiaffinity/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1AntiAffinityRules 3 | metadata: 4 | name: v1-multiple-replicas-need-anti-affinity 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: ["apps"] 9 | kinds: ["Deployment","StatefulSet","ReplicationController","ReplicaSet"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/v1.0.0/pod-enforce-antiaffinity/template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: templates.gatekeeper.sh/v1beta1 2 | kind: ConstraintTemplate 3 | metadata: 4 | name: k8sazurev1antiaffinityrules 5 | annotations: 6 | description: Requires deployments with multiple replicas have pod anti affinity rules 7 | spec: 8 | crd: 9 | spec: 10 | names: 11 | kind: K8sAzureV1AntiAffinityRules 12 | targets: 13 | - target: admission.k8s.gatekeeper.sh 14 | rego: | 15 | package k8sazurev1antiaffinityrules 16 | 17 | missing_affinity(obj) { 18 | not obj.affinity.podAntiAffinity 19 | } 20 | 21 | violation[{"msg": msg}] { 22 | input.review.object.spec.replicas > 1 23 | missing_affinity(input.review.object.spec.template.spec) 24 | msg := sprintf("%s with %d replicas should have pod anti-affinity rules set to avoid disruptions due to nodes crashing", [input.review.kind.kind, input.review.object.spec.replicas]) 25 | } -------------------------------------------------------------------------------- /pkg/safeguards/lib/v1.0.0/restricted-taints/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1ReservedTaints 3 | metadata: 4 | name: v1-system-reserved-taints 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Node"] 10 | parameters: 11 | reservedTaints: ["CriticalAddonsOnly"] -------------------------------------------------------------------------------- /pkg/safeguards/lib/v1.0.0/unique-service-selectors/constraint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAzureV1UniqueServiceSelector 3 | metadata: 4 | name: v1-unique-service-selector 5 | spec: 6 | match: 7 | kinds: 8 | - apiGroups: [""] 9 | kinds: ["Service"] -------------------------------------------------------------------------------- /pkg/safeguards/preprocessing/preprocessing_test_helpers.go: -------------------------------------------------------------------------------- 1 | package preprocessing 2 | 3 | import ( 4 | "os" 5 | "regexp" 6 | "strings" 7 | "testing" 8 | ) 9 | 10 | // Returns the content of a manifest file as bytes 11 | func getManifestAsBytes(t *testing.T, filePath string) []byte { 12 | yamlFileContent, err := os.ReadFile(filePath) 13 | if err != nil { 14 | t.Fatalf("Failed to read YAML file: %s", err) 15 | } 16 | 17 | return yamlFileContent 18 | } 19 | 20 | // Normalize returns, newlines, extra characters with strings for easy .yaml byte comparison 21 | func normalizeNewlines(data []byte) []byte { 22 | str := string(data) 23 | 24 | // Replace various newline characters with a single newline 25 | str = strings.ReplaceAll(str, "\r\n", "\n") 26 | str = strings.ReplaceAll(str, "\r", "\n") 27 | 28 | // Replace YAML block scalars' indicators and multiple spaces 29 | str = regexp.MustCompile(`(\s*\|\s*)`).ReplaceAllString(str, " ") 30 | str = strings.Join(strings.Fields(str), " ") 31 | 32 | // Normalize empty mappings and fields 33 | str = regexp.MustCompile(`\{\s*\}`).ReplaceAllString(str, "{}") 34 | str = regexp.MustCompile(`\s*:\s*`).ReplaceAllString(str, ": ") 35 | 36 | return []byte(str) 37 | } 38 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/all/error/all-error-manifest-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-deployment-1 5 | labels: 6 | app: my-app 7 | environment: production 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | app: my-app 13 | template: 14 | metadata: 15 | labels: 16 | app: my-app 17 | spec: 18 | containers: 19 | - name: badcontainer 20 | image: badimage -------------------------------------------------------------------------------- /pkg/safeguards/tests/all/error/all-error-manifest-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-deployment-2 5 | labels: 6 | app: my-app 7 | environment: production 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | app: my-app 13 | template: 14 | metadata: 15 | labels: 16 | app: my-app 17 | spec: 18 | containers: 19 | - name: badcontainer 20 | image: badimage -------------------------------------------------------------------------------- /pkg/safeguards/tests/all/success/all-success-manifest-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-deployment-1 5 | labels: 6 | app: my-app 7 | environment: production 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | app: my-app 13 | template: 14 | metadata: 15 | labels: 16 | app: my-app 17 | spec: 18 | affinity: 19 | podAntiAffinity: 20 | requiredDuringSchedulingIgnoredDuringExecution: 21 | - labelSelector: 22 | matchExpressions: 23 | - key: app 24 | operator: In 25 | values: 26 | - store 27 | topologyKey: "kubernetes.io/hostname" 28 | containers: 29 | - name: my-container 30 | image: nginx:latest 31 | resources: 32 | limits: 33 | cpu: "200m" 34 | memory: "1Gi" 35 | livenessProbe: 36 | httpGet: 37 | path: /healthz 38 | port: 8080 39 | httpHeaders: 40 | - name: my-liveness-probe 41 | value: awesome 42 | initialDelaySeconds: 3 43 | periodSeconds: 3 44 | readinessProbe: 45 | httpGet: 46 | path: /healthz 47 | port: 8080 48 | httpHeaders: 49 | - name: my-readiness-probe 50 | value: awesome 51 | initialDelaySeconds: 3 52 | periodSeconds: 3 -------------------------------------------------------------------------------- /pkg/safeguards/tests/container-allowed-images/CAI-error-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: cai-error-manifest 5 | labels: 6 | app: my-app 7 | environment: production 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | app: my-app 13 | template: 14 | metadata: 15 | labels: 16 | app: my-app 17 | spec: 18 | containers: 19 | - name: badcontainer 20 | image: badimage -------------------------------------------------------------------------------- /pkg/safeguards/tests/container-allowed-images/CAI-success-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: cai-success-manifest 5 | labels: 6 | app: my-app 7 | environment: production 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | app: my-app 13 | template: 14 | metadata: 15 | labels: 16 | app: my-app 17 | spec: 18 | containers: 19 | - name: my-container 20 | image: nginx:latest -------------------------------------------------------------------------------- /pkg/safeguards/tests/container-enforce-probes/CEP-error-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-deployment 5 | labels: 6 | app: my-app 7 | environment: production 8 | testLabel3: randomlabel 9 | spec: 10 | replicas: 3 11 | selector: 12 | matchLabels: 13 | app: my-app 14 | template: 15 | metadata: 16 | labels: 17 | app: my-app 18 | spec: 19 | containers: 20 | - name: badcontainer 21 | image: badimage 22 | livenessProbe: 23 | httpGet: 24 | path: /healthz 25 | port: 8080 26 | httpHeaders: 27 | - name: badprobe 28 | value: awesome 29 | initialDelaySeconds: 3 30 | periodSeconds: 3 -------------------------------------------------------------------------------- /pkg/safeguards/tests/container-enforce-probes/CEP-success-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-deployment 5 | labels: 6 | app: my-app 7 | environment: production 8 | testLabel3: randomlabel 9 | spec: 10 | replicas: 3 11 | selector: 12 | matchLabels: 13 | app: my-app 14 | template: 15 | metadata: 16 | labels: 17 | app: my-app 18 | spec: 19 | containers: 20 | - name: my-container 21 | image: nginx:latest 22 | livenessProbe: 23 | httpGet: 24 | path: /healthz 25 | port: 8080 26 | httpHeaders: 27 | - name: my-liveness-probe 28 | value: awesome 29 | initialDelaySeconds: 3 30 | periodSeconds: 3 31 | readinessProbe: 32 | httpGet: 33 | path: /healthz 34 | port: 8080 35 | httpHeaders: 36 | - name: my-readiness-probe 37 | value: awesome 38 | initialDelaySeconds: 3 39 | periodSeconds: 3 -------------------------------------------------------------------------------- /pkg/safeguards/tests/container-resource-limits/CRL-error-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: crl-error-manifest 5 | spec: 6 | containers: 7 | - name: badcontainer 8 | image: badimage 9 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/container-resource-limits/CRL-success-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: crl-success-manifest 5 | spec: 6 | containers: 7 | - name: my-container 8 | image: nginx:latest 9 | resources: 10 | limits: 11 | cpu: "200m" 12 | memory: "1Gi" 13 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/container-restricted-image-pulls/CRIP-error-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: violation-example 5 | namespace: default 6 | labels: 7 | app: scenario-container-allowed-images-violation 8 | spec: 9 | nodeSelector: 10 | kubernetes.io/os: linux 11 | containers: 12 | - name: container1 13 | image: mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine 14 | ports: 15 | - containerPort: 8080 16 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/container-restricted-image-pulls/CRIP-success-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: pass-example 5 | namespace: default 6 | labels: 7 | app: scenario-container-allowed-images 8 | spec: 9 | nodeSelector: 10 | kubernetes.io/os: linux 11 | containers: 12 | - name: container1 13 | image: mcr.microsoft.com/aks/policy/allowed:v1.0.0 # detects this field 14 | ports: 15 | - containerPort: 8080 16 | imagePullSecrets: 17 | - name: my-secret 18 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/disallowed-bad-pod-disruption-budgets/DBPDB-error-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: error-pdb 5 | labels: 6 | app: my-error-pdb 7 | environment: production 8 | spec: 9 | minAvailable: 0 10 | maxUnavailable: 0 11 | selector: 12 | matchLabels: 13 | app: my-error-pdb -------------------------------------------------------------------------------- /pkg/safeguards/tests/disallowed-bad-pod-disruption-budgets/DBPDB-success-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: success-pdb 5 | labels: 6 | app: my-success-pdb 7 | environment: production 8 | spec: 9 | minAvailable: 5 10 | maxUnavailable: 1 11 | selector: 12 | matchLabels: 13 | app: my-success-pdb 14 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/kustomize/base/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-app 5 | labels: 6 | app: my-app 7 | namespace: my-namespace 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: my-app 13 | template: 14 | metadata: 15 | labels: 16 | app: my-app 17 | spec: 18 | containers: 19 | - name: my-app 20 | image: nginx:latest 21 | imagePullPolicy: Always 22 | ports: 23 | - containerPort: 80 24 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/kustomize/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - deployment.yaml 5 | - service.yaml 6 | - namespace.yaml 7 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/kustomize/base/namespace.yaml: -------------------------------------------------------------------------------- 1 | kind: Namespace 2 | apiVersion: v1 3 | metadata: 4 | name: my-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/kustomize/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-service 5 | namespace: my-namespace 6 | spec: 7 | type: LoadBalancer 8 | selector: 9 | app: my-app 10 | ports: 11 | - protocol: TCP 12 | port: 4040 13 | targetPort: 80 -------------------------------------------------------------------------------- /pkg/safeguards/tests/kustomize/overlays/production/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-app 5 | labels: 6 | app: my-app 7 | namespace: my-namespace 8 | spec: 9 | selector: 10 | matchLabels: 11 | app: my-app 12 | template: 13 | spec: 14 | containers: 15 | - name: my-app 16 | image: nginx:latest -------------------------------------------------------------------------------- /pkg/safeguards/tests/kustomize/overlays/production/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namePrefix: production- 2 | namespace: my-namespace 3 | resources: 4 | - ../../base 5 | apiVersion: kustomize.config.k8s.io/v1beta1 6 | kind: Kustomization 7 | patches: 8 | - path: deployment.yaml 9 | - path: service.yaml 10 | - path: namespace.yaml 11 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/kustomize/overlays/production/namespace.yaml: -------------------------------------------------------------------------------- 1 | kind: Namespace 2 | apiVersion: v1 3 | metadata: 4 | name: my-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/kustomize/overlays/production/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-service 5 | namespace: my-namespace 6 | spec: 7 | type: LoadBalancer 8 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/not-yaml/readme.md: -------------------------------------------------------------------------------- 1 | this is a test file -------------------------------------------------------------------------------- /pkg/safeguards/tests/pod-enforce-antiaffinity/PEA-error-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-deployment 5 | labels: 6 | app: my-app 7 | environment: production 8 | testLabel3: randomlabel 9 | spec: 10 | replicas: 3 11 | selector: 12 | matchLabels: 13 | app: my-app 14 | template: 15 | metadata: 16 | labels: 17 | app: my-app 18 | spec: 19 | containers: 20 | - name: my-container 21 | image: nginx:latest -------------------------------------------------------------------------------- /pkg/safeguards/tests/pod-enforce-antiaffinity/PEA-success-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-deployment 5 | labels: 6 | app: my-app 7 | environment: production 8 | testLabel3: randomlabel 9 | spec: 10 | replicas: 3 11 | selector: 12 | matchLabels: 13 | app: my-app 14 | template: 15 | metadata: 16 | labels: 17 | app: my-app 18 | spec: 19 | affinity: 20 | podAntiAffinity: 21 | requiredDuringSchedulingIgnoredDuringExecution: 22 | - labelSelector: 23 | matchExpressions: 24 | - key: app 25 | operator: In 26 | values: 27 | - store 28 | topologyKey: "kubernetes.io/hostname" 29 | containers: 30 | - name: my-container 31 | image: nginx:latest 32 | livenessProbe: 33 | httpGet: 34 | path: /healthz 35 | port: 8080 36 | httpHeaders: 37 | - name: my-liveness-probe 38 | value: awesome 39 | initialDelaySeconds: 3 40 | periodSeconds: 3 41 | readinessProbe: 42 | httpGet: 43 | path: /healthz 44 | port: 8080 45 | httpHeaders: 46 | - name: my-readiness-probe 47 | value: awesome 48 | initialDelaySeconds: 3 49 | periodSeconds: 3 -------------------------------------------------------------------------------- /pkg/safeguards/tests/restricted-taints/RT-error-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Node 3 | metadata: 4 | name: my-error-node 5 | labels: 6 | app: my-error-node 7 | kubernetes.azure.com/mode: "User" 8 | environment: production 9 | spec: 10 | taints: 11 | - key: "CriticalAddonsOnly" 12 | effect: "NoSchedule" 13 | value: "value" -------------------------------------------------------------------------------- /pkg/safeguards/tests/restricted-taints/RT-success-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Node 3 | metadata: 4 | name: my-success-node 5 | labels: 6 | app: my-success-node 7 | kubernetes.azure.com/mode: "User" 8 | environment: production 9 | spec: 10 | taints: 11 | - key: "UserDefinedKey" 12 | effect: "NoSchedule" 13 | value: "value" -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/different-structure/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: mychart 3 | description: A simple Helm chart for Kubernetes 4 | version: 0.1.0 5 | appVersion: "1.16.0" 6 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/different-structure/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{- define "mychart.fullname" -}} 2 | {{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" -}} 3 | {{- end -}} 4 | 5 | {{- define "mychart.labels" -}} 6 | helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 7 | {{ include "mychart.fullname" . }}: {{ .Release.Name }} 8 | app.kubernetes.io/managed-by: {{ .Release.Service }} 9 | app.kubernetes.io/instance: {{ .Release.Name }} 10 | app.kubernetes.io/version: {{ .Chart.AppVersion }} 11 | app.kubernetes.io/component: {{ .Chart.Name }} 12 | {{- end -}} 13 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/different-structure/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "mychart.fullname" . }} 5 | labels: 6 | {{ include "mychart.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | app: {{ include "mychart.fullname" . }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ include "mychart.fullname" . }} 16 | spec: 17 | containers: 18 | - name: nginx 19 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 20 | imagePullPolicy: {{ .Values.image.pullPolicy }} 21 | ports: 22 | - containerPort: 80 23 | resources: 24 | {{- toYaml .Values.resources | nindent 12 }} 25 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/different-structure/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "mychart.fullname" . }} 5 | labels: 6 | {{ include "mychart.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: 80 12 | selector: 13 | app: {{ include "mychart.fullname" . }} 14 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/different-structure/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | 3 | image: 4 | repository: nginx 5 | tag: "1.16.0" 6 | pullPolicy: IfNotPresent 7 | 8 | service: 9 | type: ClusterIP 10 | port: 80 11 | 12 | releaseName: test-release 13 | 14 | releaseNamespace: test-namespace 15 | 16 | resources: {} 17 | 18 | nodeSelector: {} 19 | 20 | tolerations: [] 21 | 22 | affinity: {} 23 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expected-helpers-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-release-mychart 5 | labels: 6 | 7 | helm.sh/chart: mychart-0.1.0 8 | test-release-mychart: test-release 9 | app.kubernetes.io/managed-by: Helm 10 | app.kubernetes.io/instance: test-release 11 | app.kubernetes.io/version: 1.16.0 12 | app.kubernetes.io/component: mychart 13 | spec: 14 | replicas: 1 15 | selector: 16 | matchLabels: 17 | app: test-release-mychart 18 | template: 19 | metadata: 20 | labels: 21 | app: test-release-mychart 22 | spec: 23 | containers: 24 | - name: nginx 25 | image: "nginx:1.16.0" 26 | imagePullPolicy: IfNotPresent 27 | ports: 28 | - containerPort: 80 29 | resources: 30 | {} 31 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expected-helpers-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: test-release-mychart 5 | labels: 6 | 7 | helm.sh/chart: mychart-0.1.0 8 | test-release-mychart: test-release 9 | app.kubernetes.io/managed-by: Helm 10 | app.kubernetes.io/instance: test-release 11 | app.kubernetes.io/version: 1.16.0 12 | app.kubernetes.io/component: mychart 13 | spec: 14 | type: ClusterIP 15 | ports: 16 | - port: 80 17 | targetPort: 80 18 | selector: 19 | app: test-release-mychart 20 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expected-mainchart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-release-main 5 | labels: 6 | app: mainchart 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: mainchart 12 | template: 13 | metadata: 14 | labels: 15 | app: mainchart 16 | spec: 17 | containers: 18 | - name: mainchart 19 | image: nginx:stable -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expected-resources.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-release-deployment 5 | namespace: test-namespace 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | app: my-web-app 11 | template: 12 | metadata: 13 | labels: 14 | app: my-web-app 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: nginx:stable 19 | --- 20 | apiVersion: v1 21 | kind: ConfigMap 22 | metadata: 23 | name: test-release-configmap 24 | namespace: test-namespace 25 | data: 26 | config.yaml: | 27 | replicaCount: 1 28 | image: 29 | repository: nginx 30 | tag: stable 31 | pullPolicy: IfNotPresent 32 | service: 33 | type: ClusterIP 34 | port: 80 35 | ingress: 36 | enabled: true 37 | hostname: example.com 38 | annotations: 39 | tls: false 40 | tlsSecret: -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expected-subchart1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-release-subchart1 5 | labels: 6 | app: my-web-app 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | app: my-web-app 12 | template: 13 | metadata: 14 | labels: 15 | app: my-web-app 16 | spec: 17 | containers: 18 | - name: nginx 19 | image: nginx:stable -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expected-subchart2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-release-subchart2 5 | labels: 6 | app: my-web-app 7 | spec: 8 | replicas: 3 9 | selector: 10 | matchLabels: 11 | app: my-web-app 12 | template: 13 | metadata: 14 | labels: 15 | app: my-web-app 16 | spec: 17 | containers: 18 | - name: nginx 19 | image: nginx:stable -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expecteddeployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-release-deployment 5 | namespace: test-namespace 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | app: my-web-app 11 | template: 12 | metadata: 13 | labels: 14 | app: my-web-app 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: nginx:stable -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expecteddeployment_flags.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-flags-name-deployment 5 | namespace: test-flags-namespace 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | app: my-web-app 11 | template: 12 | metadata: 13 | labels: 14 | app: my-web-app 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: nginx:stable -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expectedingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: test-release-ingress 5 | namespace: test-namespace 6 | spec: 7 | rules: 8 | - host: example.com 9 | http: 10 | paths: 11 | - path: / 12 | pathType: Prefix 13 | backend: 14 | service: 15 | name: test-release-service 16 | port: 17 | number: 80 -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expectedingress_flags.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: test-flags-name-ingress 5 | namespace: test-flags-namespace 6 | spec: 7 | rules: 8 | - host: example.com 9 | http: 10 | paths: 11 | - path: / 12 | pathType: Prefix 13 | backend: 14 | service: 15 | name: test-flags-name-service 16 | port: 17 | number: 80 -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expectedservice.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: test-release-service 5 | namespace: test-namespace 6 | spec: 7 | type: ClusterIP 8 | ports: 9 | - port: 80 10 | selector: 11 | app: my-web-app -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expectedservice2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: test-release-service2 5 | namespace: test-namespace 6 | spec: 7 | type: ClusterIP 8 | ports: 9 | - port: 80 10 | selector: 11 | app: my-web-app -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/expectedservice_flags.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: test-flags-name-service 5 | namespace: test-flags-namespace 6 | spec: 7 | type: ClusterIP 8 | ports: 9 | - port: 80 10 | selector: 11 | app: my-web-app -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invalidchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | version: 0.1.0 -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invalidchart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }}-deployment 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | replicas: {{ .Values.replicaCount }} 8 | selector: 9 | matchLabels: 10 | app: my-web-app 11 | template: 12 | metadata: 13 | labels: 14 | app: my-web-app 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: {{ .Values.image.repository }}:{{ .Values.image.tag }} 19 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invalidchart/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | image: 3 | repository: nginx 4 | tag: stable 5 | service: 6 | type: ClusterIP 7 | port: 80 8 | ingress: 9 | enabled: true 10 | hostname: example.com 11 | releaseName: test-release 12 | releaseNamespace: test-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: my-web-app 3 | description: A Helm chart for Kubernetes 4 | version: 0.1.0 -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/templates/invaliddeploymentsyntax.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }}-deployment 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | replicas: {{ .Values.replicaCount 8 | selector: 9 | matchLabels: 10 | app: my-web-app 11 | template: 12 | metadata: 13 | labels: 14 | app: my-web-ap 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: {{ .Values.image.repository }}:{{ .Values.image.tag -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | image: 3 | repository: nginx 4 | tag: stable 5 | service: 6 | type: ClusterIP 7 | port: 80 8 | ingress: 9 | enabled: true 10 | hostname: example.com 11 | releaseName: test-release 12 | releaseNamespace: test-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invaliddeployment-values/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: my-web-app 3 | description: A Helm chart for Kubernetes 4 | version: 0.1.0 -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invaliddeployment-values/templates/invaliddeploymentvalues.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }}-deployment 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | replicas: {{ .Values.nonExistentField }} 8 | selector: 9 | matchLabels: 10 | app: my-web-app 11 | template: 12 | metadata: 13 | labels: 14 | app: my-web-app 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: {{ .Values.image.invalidField }}:{{ .Values.image.tag }} -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invaliddeployment-values/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | image: 3 | repository: nginx 4 | tag: stable 5 | service: 6 | type: ClusterIP 7 | port: 80 8 | ingress: 9 | enabled: true 10 | hostname: example.com 11 | releaseName: test-release 12 | releaseNamespace: test-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invalidvalues/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: my-web-app 3 | description: A Helm chart for Kubernetes 4 | version: 0.1.0 -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invalidvalues/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Release.Name }}-service 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | type: {{ .Values.service.type }} 8 | ports: 9 | - port: {{ .Values.service.port }} 10 | selector: 11 | app: my-web-app -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/invalidvalues/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | image: 3 | repository: nginx 4 | tag: stable 5 | ingress: 6 | enabled: true 7 | hostname: example.com 8 | releaseName: test-release 9 | releaseNamespace: test-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-charts/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: mainchart 3 | description: A Helm chart with subcharts 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: subchart1 3 | description: Subchart 1 for mainchart 4 | version: 0.1.0 5 | dependencies: 6 | - name: subchart2 7 | version: 0.1.0 8 | repository: "file://../subchart2" # Relative path to subchart2 directory 9 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/templates/deployment1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }}-subchart1 5 | labels: 6 | app: my-web-app 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | app: my-web-app 12 | template: 13 | metadata: 14 | labels: 15 | app: my-web-app 16 | spec: 17 | containers: 18 | - name: nginx 19 | image: {{ .Values.image.repository }}:{{ .Values.image.tag }} 20 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 2 2 | image: 3 | repository: nginx 4 | tag: stable 5 | releaseName: test-release 6 | releaseNamespace: test-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: subchart2 3 | description: Subchart 2 for mainchart 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/templates/deployment2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }}-subchart2 5 | labels: 6 | app: my-web-app 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | app: my-web-app 12 | template: 13 | metadata: 14 | labels: 15 | app: my-web-app 16 | spec: 17 | containers: 18 | - name: nginx 19 | image: {{ .Values.image.repository }}:{{ .Values.image.tag }} 20 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 3 2 | image: 3 | repository: nginx 4 | tag: stable 5 | releaseName: test-release 6 | releaseNamespace: test-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-charts/templates/maindeployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }}-main 5 | labels: 6 | app: mainchart 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | app: mainchart 12 | template: 13 | metadata: 14 | labels: 15 | app: mainchart 16 | spec: 17 | containers: 18 | - name: mainchart 19 | image: {{ .Values.image.repository }}:{{ .Values.image.tag }} 20 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-charts/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | image: 3 | repository: nginx 4 | tag: stable 5 | releaseName: test-release 6 | releaseNamespace: test-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-templates/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: my-web-app 3 | description: A Helm chart for Kubernetes 4 | version: 0.1.0 -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-templates/templates/resources.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }}-deployment 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | replicas: {{ .Values.replicaCount }} 8 | selector: 9 | matchLabels: 10 | app: my-web-app 11 | template: 12 | metadata: 13 | labels: 14 | app: my-web-app 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: {{ .Values.image.repository }}:{{ .Values.image.tag }} 19 | --- 20 | apiVersion: v1 21 | kind: ConfigMap 22 | metadata: 23 | name: {{ .Release.Name }}-configmap 24 | namespace: {{ .Release.Namespace }} 25 | data: 26 | config.yaml: | 27 | replicaCount: {{ .Values.replicaCount }} 28 | image: 29 | repository: {{ .Values.image.repository }} 30 | tag: {{ .Values.image.tag }} 31 | pullPolicy: {{ .Values.image.pullPolicy }} 32 | service: 33 | type: {{ .Values.service.type }} 34 | port: {{ .Values.service.port }} 35 | ingress: 36 | enabled: {{ .Values.ingress.enabled }} 37 | hostname: {{ .Values.ingress.hostname }} 38 | annotations: 39 | {{- range $key, $value := .Values.ingress.annotations }} 40 | {{ $key }}: {{ $value | quote }} 41 | {{- end }} 42 | tls: {{ .Values.ingress.tls }} 43 | tlsSecret: {{ .Values.ingress.tlsSecret }} 44 | 45 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-templates/templates/services/service-1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Release.Name }}-service 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | type: {{ .Values.service.type }} 8 | ports: 9 | - port: {{ .Values.service.port }} 10 | selector: 11 | app: my-web-app -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-templates/templates/services/service-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Release.Name }}-service2 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | type: {{ .Values.service.type }} 8 | ports: 9 | - port: {{ .Values.service.port }} 10 | selector: 11 | app: my-web-app -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/multiple-templates/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | image: 3 | repository: nginx 4 | tag: stable 5 | pullPolicy: IfNotPresent 6 | service: 7 | type: ClusterIP 8 | port: 80 9 | ingress: 10 | enabled: true 11 | hostname: example.com 12 | annotations: {} 13 | tls: false 14 | tlsSecret: "" 15 | releaseName: test-release 16 | releaseNamespace: test-namespace 17 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/nochart-invalid/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }}-deployment 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | replicas: {{ .Values.replicaCount }} 8 | selector: 9 | matchLabels: 10 | app: my-web-app 11 | template: 12 | metadata: 13 | labels: 14 | app: my-web-app 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: {{ .Values.image.repository }}:{{ .Values.image.tag }} 19 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/nochart-invalid/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | image: 3 | repository: nginx 4 | tag: stable 5 | service: 6 | type: ClusterIP 7 | port: 80 8 | ingress: 9 | enabled: true 10 | hostname: example.com 11 | releaseName: test-release 12 | releaseNamespace: test-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/validchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: my-web-app 3 | description: A Helm chart for Kubernetes 4 | version: 0.1.0 -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/validchart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }}-deployment 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | replicas: {{ .Values.replicaCount }} 8 | selector: 9 | matchLabels: 10 | app: my-web-app 11 | template: 12 | metadata: 13 | labels: 14 | app: my-web-app 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: {{ .Values.image.repository }}:{{ .Values.image.tag }} 19 | -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/validchart/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled }} 2 | apiVersion: networking.k8s.io/v1 3 | kind: Ingress 4 | metadata: 5 | name: {{ .Release.Name }}-ingress 6 | namespace: {{ .Release.Namespace }} 7 | spec: 8 | rules: 9 | - host: {{ .Values.ingress.hostname }} 10 | http: 11 | paths: 12 | - path: / 13 | pathType: Prefix 14 | backend: 15 | service: 16 | name: {{ .Release.Name }}-service 17 | port: 18 | number: {{ .Values.service.port }} 19 | {{- end }} -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/validchart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Release.Name }}-service 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | type: {{ .Values.service.type }} 8 | ports: 9 | - port: {{ .Values.service.port }} 10 | selector: 11 | app: my-web-app -------------------------------------------------------------------------------- /pkg/safeguards/tests/testmanifests/validchart/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | image: 3 | repository: nginx 4 | tag: stable 5 | service: 6 | type: ClusterIP 7 | port: 80 8 | ingress: 9 | enabled: true 10 | hostname: example.com 11 | releaseName: test-release 12 | releaseNamespace: test-namespace -------------------------------------------------------------------------------- /pkg/safeguards/tests/unique-service-selectors/USS-error-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-service-1 5 | namespace: prod 6 | spec: 7 | selector: 8 | app.kubernetes.io/name: MyApp 9 | ports: 10 | - protocol: TCP 11 | port: 80 12 | targetPort: 9376 13 | --- 14 | apiVersion: v1 15 | kind: Service 16 | metadata: 17 | name: my-service-2 18 | namespace: prod 19 | spec: 20 | selector: 21 | app.kubernetes.io/name: MyApp 22 | ports: 23 | - protocol: TCP 24 | port: 220 25 | targetPort: 9423 -------------------------------------------------------------------------------- /pkg/safeguards/tests/unique-service-selectors/USS-success-manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-service-1 5 | namespace: prod 6 | spec: 7 | selector: 8 | app.kubernetes.io/name: MyApp1 9 | ports: 10 | - protocol: TCP 11 | port: 80 12 | targetPort: 9376 13 | --- 14 | apiVersion: v1 15 | kind: Service 16 | metadata: 17 | name: my-service-2 18 | namespace: prod 19 | spec: 20 | selector: 21 | app.kubernetes.io/name: MyApp2 22 | ports: 23 | - protocol: TCP 24 | port: 220 25 | targetPort: 9423 -------------------------------------------------------------------------------- /pkg/spinner/spinner.go: -------------------------------------------------------------------------------- 1 | package spinner 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/fatih/color" 8 | "github.com/briandowns/spinner" 9 | ) 10 | 11 | type Spinner interface { 12 | Start() 13 | Stop() 14 | } 15 | 16 | func CreateSpinner(msg string) *spinner.Spinner { 17 | cyan := color.New(color.Bold, color.FgCyan).SprintFunc() 18 | s := spinner.New(spinner.CharSets[11], 100*time.Millisecond) 19 | s.Prefix = fmt.Sprintf("%s %s ", cyan("[Draft]"), msg) 20 | s.Suffix = " " 21 | return s 22 | } 23 | -------------------------------------------------------------------------------- /pkg/templatewriter/templatewriter.go: -------------------------------------------------------------------------------- 1 | package templatewriter 2 | 3 | type TemplateWriter interface { 4 | WriteFile(string, []byte) error 5 | EnsureDirectory(string) error 6 | } 7 | -------------------------------------------------------------------------------- /pkg/templatewriter/writers/filemapwriter.go: -------------------------------------------------------------------------------- 1 | package writers 2 | 3 | type FileMapWriter struct { 4 | FileMap map[string][]byte 5 | } 6 | 7 | func (w *FileMapWriter) WriteFile(path string, data []byte) error { 8 | if w.FileMap == nil { 9 | w.FileMap = map[string][]byte{} 10 | } 11 | 12 | w.FileMap[path] = data 13 | return nil 14 | } 15 | 16 | func (w *FileMapWriter) EnsureDirectory(path string) error { 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /pkg/templatewriter/writers/filemapwriter_test.go: -------------------------------------------------------------------------------- 1 | package writers 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | 8 | "github.com/Azure/draft/pkg/config" 9 | "github.com/Azure/draft/pkg/osutil" 10 | "github.com/Azure/draft/template" 11 | ) 12 | 13 | func TestCopyDirToFileMap(t *testing.T) { 14 | 15 | templatewriter := &FileMapWriter{} 16 | err := osutil.CopyDir(template.Templates, "addons/azure/webapp_routing", "/test/dir", &config.DraftConfig{ 17 | Variables: []*config.BuilderVar{ 18 | { 19 | Name: "ingress-tls-cert-keyvault-uri", 20 | Value: "https://test.vault.azure.net/secrets/test-secret", 21 | }, 22 | { 23 | Name: "ingress-use-osm-mtls", 24 | Value: "true", 25 | }, 26 | { 27 | Name: "ingress-host", 28 | Value: "testhost.com", 29 | }, 30 | }, 31 | }, templatewriter) 32 | assert.Nil(t, err) 33 | assert.NotNil(t, templatewriter.FileMap) 34 | assert.NotNil(t, templatewriter.FileMap["/test/dir/ingress.yaml"]) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/templatewriter/writers/localfswriter.go: -------------------------------------------------------------------------------- 1 | package writers 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/Azure/draft/pkg/osutil" 7 | ) 8 | 9 | type LocalFSWriter struct { 10 | WriteMode os.FileMode 11 | } 12 | 13 | func (w *LocalFSWriter) WriteFile(path string, data []byte) error { 14 | mode := w.WriteMode 15 | if w.WriteMode == 0 { 16 | mode = 0644 17 | } 18 | 19 | return os.WriteFile(path, data, mode) 20 | } 21 | func (w *LocalFSWriter) EnsureDirectory(path string) error { 22 | return osutil.EnsureDirectory(path) 23 | } 24 | -------------------------------------------------------------------------------- /template/deployments/helm/charts/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /template/deployments/helm/charts/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: {{ .Config.GetVariableValue "APPNAME" }} 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.16.0" 25 | -------------------------------------------------------------------------------- /template/deployments/helm/charts/production.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: "{{ .Config.GetVariableValue "IMAGENAME" }}" 3 | tag: "{{ .Config.GetVariableValue "IMAGETAG" }}" 4 | pullPolicy: "{{ .Config.GetVariableValue "IMAGEPULLPOLICY" }}" 5 | service: 6 | annotations: {} 7 | type: LoadBalancer 8 | port: "{{ .Config.GetVariableValue "SERVICEPORT" }}" 9 | -------------------------------------------------------------------------------- /template/deployments/helm/charts/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ .Config.GetVariableValue "APPNAME" | printf "{{ include \"%s.fullname\" . }}-config" }} 5 | labels: 6 | {{ .Config.GetVariableValue "APPNAME" | printf "{{- include \"%s.labels\" . | nindent 4 }}" }} 7 | {{- ` 8 | namespace: {{ .Values.namespace }} 9 | ` -}} 10 | data: 11 | {{- ` 12 | {{- range $key, $value := .Values.envVars }} 13 | {{ $key }}: {{ $value }} 14 | {{- end }} 15 | ` -}} -------------------------------------------------------------------------------- /template/deployments/helm/charts/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Config.GetVariableValue "APPNAME" | printf "{{ include \"%s.fullname\" . }}" }} 5 | labels: 6 | {{ .Config.GetVariableValue "APPNAME" | printf "{{- include \"%s.labels\" . | nindent 4 }}" }} 7 | {{- ` 8 | annotations: 9 | {{ toYaml .Values.service.annotations | nindent 4 }} 10 | namespace: {{ .Values.namespace }} 11 | ` -}} 12 | spec: 13 | {{- ` 14 | type: {{ .Values.service.type }} 15 | ports: 16 | - port: {{ .Values.service.port }} 17 | targetPort: {{ .Values.containerPort }} 18 | protocol: TCP 19 | name: svchttp 20 | ` -}} 21 | selector: 22 | {{ .Config.GetVariableValue "APPNAME" | printf "{{- include \"%s.selectorLabels\" . | nindent 6 }}" }} 23 | -------------------------------------------------------------------------------- /template/deployments/kustomize/base/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ .Config.GetVariableValue "APPNAME" | printf "%s-config" }} 5 | namespace: {{ .Config.GetVariableValue "NAMESPACE" }} 6 | labels: 7 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 8 | kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} 9 | data: 10 | {{- range $key, $value := .Config.GetVariableValue "ENVVARS" }} 11 | {{ $key }}: {{ $value }} 12 | {{- end }} -------------------------------------------------------------------------------- /template/deployments/kustomize/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - deployment.yaml 5 | - service.yaml 6 | - configmap.yaml -------------------------------------------------------------------------------- /template/deployments/kustomize/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Config.GetVariableValue "APPNAME" }} 5 | namespace: {{ .Config.GetVariableValue "NAMESPACE" }} 6 | labels: 7 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 8 | kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} 9 | spec: 10 | type: LoadBalancer 11 | selector: 12 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 13 | ports: 14 | - protocol: TCP 15 | port: {{ .Config.GetVariableValue "SERVICEPORT" }} 16 | targetPort: {{ .Config.GetVariableValue "PORT" }} -------------------------------------------------------------------------------- /template/deployments/kustomize/overlays/production/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Config.GetVariableValue "APPNAME" }} 5 | labels: 6 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 7 | kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL"}} 8 | namespace: {{ .Config.GetVariableValue "NAMESPACE" }} 9 | spec: 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 13 | template: 14 | spec: 15 | containers: 16 | - name: {{ .Config.GetVariableValue "APPNAME" }} 17 | image: {{ .Config.GetVariableValue "IMAGENAME" }}:{{ .Config.GetVariableValue "IMAGETAG" }} -------------------------------------------------------------------------------- /template/deployments/kustomize/overlays/production/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namePrefix: production- 2 | namespace: {{ .Config.GetVariableValue "NAMESPACE" }} 3 | resources: 4 | - ../../base 5 | patchesStrategicMerge: 6 | - deployment.yaml 7 | - service.yaml -------------------------------------------------------------------------------- /template/deployments/kustomize/overlays/production/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Config.GetVariableValue "APPNAME"}} 5 | namespace: {{ .Config.GetVariableValue "NAMESPACE" }} 6 | labels: 7 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 8 | kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} 9 | spec: 10 | type: LoadBalancer -------------------------------------------------------------------------------- /template/deployments/manifests/manifests/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ .Config.GetVariableValue "APPNAME" | printf "%s-config" }} 5 | namespace: {{ .Config.GetVariableValue "NAMESPACE" }} 6 | labels: 7 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 8 | kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} 9 | data: 10 | {{- range $key, $value := .Config.GetVariableValue "ENVVARS" }} 11 | {{ $key }}: {{ $value }} 12 | {{- end }} -------------------------------------------------------------------------------- /template/deployments/manifests/manifests/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Config.GetVariableValue "APPNAME" }} 5 | namespace: {{ .Config.GetVariableValue "NAMESPACE" }} 6 | labels: 7 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 8 | kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} 9 | spec: 10 | type: LoadBalancer 11 | selector: 12 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 13 | ports: 14 | - protocol: TCP 15 | port: {{ .Config.GetVariableValue "SERVICEPORT" }} 16 | targetPort: {{ .Config.GetVariableValue "PORT" }} -------------------------------------------------------------------------------- /template/dockerfiles/clojure/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | resources/ 4 | target/ 5 | test/ 6 | -------------------------------------------------------------------------------- /template/dockerfiles/clojure/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM clojure as BUILD 2 | COPY . /usr/src/app 3 | WORKDIR /usr/src/app 4 | RUN lein ring uberjar 5 | 6 | FROM eclipse-temurin:{{ .Config.GetVariableValue "VERSION" }} 7 | 8 | RUN apk update && apk upgrade && apk add bash 9 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 10 | EXPOSE {{ .Config.GetVariableValue "PORT"}} 11 | COPY --from=BUILD /usr/src/app/target/*.jar /opt/ 12 | WORKDIR /opt 13 | CMD ["/bin/bash", "-c", "find -type f -name '*standalone.jar' | xargs java -jar"] 14 | -------------------------------------------------------------------------------- /template/dockerfiles/clojure/draft.yaml: -------------------------------------------------------------------------------- 1 | language: clojure 2 | displayName: Clojure 3 | templateName: "dockerfile-clojure" 4 | description: "This template is used to create a Dockerfile for a Clojure application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "VERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "8-jdk-alpine" 21 | description: "the version of openjdk that the application uses" 22 | exampleValues: 23 | ["8-jdk-alpine", "11-jdk-alpine", "17-jdk-alpine", "19-jdk-alpine"] 24 | versions: ">=0.0.1" 25 | - name: "DOCKERFILENAME" 26 | type: "string" 27 | kind: "dockerFileName" 28 | default: 29 | value: "Dockerfile" 30 | disablePrompt: true 31 | description: "the name of the Dockerfile" 32 | versions: ">=0.0.1" 33 | -------------------------------------------------------------------------------- /template/dockerfiles/csharp/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | bin/ 4 | obj/ 5 | -------------------------------------------------------------------------------- /template/dockerfiles/csharp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/sdk:{{ .Config.GetVariableValue "VERSION" }} AS builder 2 | WORKDIR /app 3 | 4 | # caches restore result by copying csproj file separately 5 | COPY *.csproj . 6 | RUN dotnet restore 7 | 8 | COPY . . 9 | RUN dotnet publish --output /app/ --configuration Release --no-restore 10 | RUN sed -n 's:.*\(.*\).*:\1:p' *.csproj > __assemblyname 11 | RUN if [ ! -s __assemblyname ]; then filename=$(ls *.csproj); echo ${filename%.*} > __assemblyname; fi 12 | 13 | # Stage 2 14 | FROM mcr.microsoft.com/dotnet/aspnet:{{ .Config.GetVariableValue "VERSION" }} 15 | WORKDIR /app 16 | COPY --from=builder /app . 17 | 18 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 19 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 20 | 21 | ENTRYPOINT dotnet $(cat /app/__assemblyname).dll --urls "http://*:{{ .Config.GetVariableValue "PORT" }}" 22 | -------------------------------------------------------------------------------- /template/dockerfiles/csharp/draft.yaml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | displayName: C# 3 | templateName: "dockerfile-csharp" 4 | description: "This template is used to create a Dockerfile for a C# application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "VERSION" 17 | type: "float" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "5.0" 21 | description: "the dotnet SDK version" 22 | exampleValues: ["3.1", "4.0", "5.0", "6.0"] 23 | versions: ">=0.0.1" 24 | - name: "DOCKERFILENAME" 25 | type: "string" 26 | kind: "dockerFileName" 27 | default: 28 | value: "Dockerfile" 29 | disablePrompt: true 30 | description: "the name of the Dockerfile" 31 | versions: ">=0.0.1" 32 | -------------------------------------------------------------------------------- /template/dockerfiles/erlang/.dockerignore: -------------------------------------------------------------------------------- 1 | # files and directories to exclude from context 2 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 3 | _build -------------------------------------------------------------------------------- /template/dockerfiles/erlang/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM erlang:{{ .Config.GetVariableValue "BUILDERVERSION" }} as builder 2 | 3 | RUN apk add --update tar curl git bash make libc-dev gcc g++ && \ 4 | rm -rf /var/cache/apk/* 5 | 6 | RUN set -xe \ 7 | && curl -fSL -o rebar3 "https://s3.amazonaws.com/rebar3/rebar3" \ 8 | && chmod +x ./rebar3 \ 9 | && ./rebar3 local install \ 10 | && rm ./rebar3 11 | 12 | WORKDIR /usr/src/app 13 | COPY . /usr/src/app 14 | 15 | ENV PATH "$PATH:/root/.cache/rebar3/bin" 16 | RUN rebar3 as prod tar 17 | 18 | RUN mkdir -p /opt/rel 19 | RUN tar -zxvf /usr/src/app/_build/prod/rel/*/*.tar.gz -C /opt/rel 20 | 21 | RUN relname=$(ls _build/prod/rel) ; echo $relname > /opt/rel/__relname 22 | 23 | FROM alpine:{{ .Config.GetVariableValue "VERSION" }} 24 | 25 | RUN apk add --no-cache openssl-dev ncurses libstdc++ libgcc 26 | 27 | WORKDIR /opt/rel 28 | 29 | ENV RELX_REPLACE_OS_VARS true 30 | ENV HTTP_PORT {{ .Config.GetVariableValue "PORT" }} 31 | 32 | COPY --from=builder /opt/rel /opt/rel 33 | 34 | EXPOSE {{ .Config.GetVariableValue "PORT" }} {{ .Config.GetVariableValue "PORT" }} 35 | 36 | RUN ln -s /opt/rel/bin/$(cat /opt/rel/__relname) /opt/rel/bin/start_script 37 | ENTRYPOINT ["/opt/rel/bin/start_script"] 38 | 39 | CMD ["foreground"] 40 | 41 | -------------------------------------------------------------------------------- /template/dockerfiles/erlang/draft.yaml: -------------------------------------------------------------------------------- 1 | language: erlang 2 | displayName: Erlang 3 | templateName: "dockerfile-erlang" 4 | description: "This template is used to create a Dockerfile for an Erlang application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "BUILDERVERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "27.0-alpine" 21 | description: "the version of erlang used during the builder stage to generate the executable" 22 | exampleValues: ["27.0-alpine"] 23 | versions: ">=0.0.1" 24 | - name: "VERSION" 25 | type: "string" 26 | kind: "containerImageVersion" 27 | default: 28 | value: "3.17" 29 | description: "the version of alpine used by the application" 30 | exampleValues: ["3.17"] 31 | versions: ">=0.0.1" 32 | - name: "DOCKERFILENAME" 33 | type: "string" 34 | kind: "dockerFileName" 35 | default: 36 | value: "Dockerfile" 37 | disablePrompt: true 38 | description: "the name of the Dockerfile" 39 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/go/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | -------------------------------------------------------------------------------- /template/dockerfiles/go/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:{{ .Config.GetVariableValue "VERSION" }} 2 | ENV PORT={{ .Config.GetVariableValue "PORT" }} 3 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 4 | 5 | WORKDIR /go/src/app 6 | COPY . . 7 | 8 | ARG GO111MODULE=off 9 | RUN go build -v -o app ./main.go 10 | RUN mv ./app /go/bin/ 11 | 12 | CMD ["app"] -------------------------------------------------------------------------------- /template/dockerfiles/go/draft.yaml: -------------------------------------------------------------------------------- 1 | language: go 2 | displayName: Go 3 | templateName: "dockerfile-go" 4 | description: "This template is used to create a Dockerfile for a Go application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "VERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "1.23" 21 | description: "the version of go used by the application" 22 | exampleValues: ["1.20", "1.21", "1.22", "1.23"] 23 | versions: ">=0.0.1" 24 | - name: "DOCKERFILENAME" 25 | type: "string" 26 | kind: "dockerFileName" 27 | default: 28 | value: "Dockerfile" 29 | disablePrompt: true 30 | description: "the name of the Dockerfile" 31 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/gomodule/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | -------------------------------------------------------------------------------- /template/dockerfiles/gomodule/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:{{ .Config.GetVariableValue "VERSION" }} AS builder 2 | 3 | WORKDIR /build 4 | COPY go.mod go.sum ./ 5 | RUN go mod download && go mod verify 6 | COPY . . 7 | RUN CGO_ENABLED=0 GOOS=linux go build -v -o app-binary 8 | 9 | FROM gcr.io/distroless/static-debian12 10 | 11 | ENV PORT={{ .Config.GetVariableValue "PORT" }} 12 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 13 | 14 | WORKDIR /app 15 | COPY --from=builder /build/app-binary . 16 | CMD ["/app/app-binary"] 17 | -------------------------------------------------------------------------------- /template/dockerfiles/gomodule/draft.yaml: -------------------------------------------------------------------------------- 1 | language: gomodule 2 | displayName: Go Module 3 | templateName: "dockerfile-gomodule" 4 | description: "This template is used to create a Dockerfile for a Go Module application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "VERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "1.23" 21 | description: "the version of go used by the application" 22 | exampleValues: ["1.20", "1.21", "1.22", "1.23"] 23 | versions: ">=0.0.1" 24 | - name: "DOCKERFILENAME" 25 | type: "string" 26 | kind: "dockerFileName" 27 | default: 28 | value: "Dockerfile" 29 | disablePrompt: true 30 | description: "the name of the Dockerfile" 31 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/gradle/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | -------------------------------------------------------------------------------- /template/dockerfiles/gradle/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gradle:{{ .Config.GetVariableValue "BUILDERVERSION" }} as BUILD 2 | 3 | COPY --chown=gradle:gradle . /project 4 | RUN gradle -i -s -b /project/build.gradle clean build 5 | 6 | FROM eclipse-temurin:{{ .Config.GetVariableValue "VERSION" }} 7 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 8 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 9 | 10 | COPY --from=BUILD /project/build/libs/* /opt/ 11 | WORKDIR /opt/ 12 | RUN ls -l 13 | CMD ["/bin/bash", "-c", "find -type f -name '*SNAPSHOT.jar' | xargs java -jar"] 14 | -------------------------------------------------------------------------------- /template/dockerfiles/gradle/draft.yaml: -------------------------------------------------------------------------------- 1 | language: gradle 2 | displayName: Gradle 3 | templateName: "dockerfile-gradle" 4 | description: "This template is used to create a Dockerfile for a Gradle application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "BUILDERVERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "jdk21" 21 | description: "the version of gradle used during the builder stage to generate the executable" 22 | exampleValues: ["jdk8", "jdk11", "jdk17", "jdk19", "jdk21"] 23 | versions: ">=0.0.1" 24 | - name: "VERSION" 25 | type: "string" 26 | kind: "containerImageVersion" 27 | default: 28 | value: "21-jre" 29 | description: "the java version used by the application" 30 | exampleValues: ["11-jre", "17-jre", "19-jre", "21-jre"] 31 | versions: ">=0.0.1" 32 | - name: "DOCKERFILENAME" 33 | type: "string" 34 | kind: "dockerFileName" 35 | default: 36 | value: "Dockerfile" 37 | disablePrompt: true 38 | description: "the name of the Dockerfile" 39 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/gradlew/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | -------------------------------------------------------------------------------- /template/dockerfiles/gradlew/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gradle:{{ .Config.GetVariableValue "BUILDERVERSION" }} as BUILD 2 | 3 | COPY --chown=gradle:gradle . /project 4 | COPY gradlew gradlew 5 | COPY gradle/wrapper gradle/wrapper 6 | RUN chmod +x gradle/wrapper 7 | RUN chmod +x gradlew 8 | RUN ./gradlew -i -s -b /project/build.gradle clean build 9 | 10 | FROM eclipse-temurin:{{ .Config.GetVariableValue "VERSION" }} 11 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 12 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 13 | 14 | COPY --from=BUILD /project/build/libs/* /opt/ 15 | WORKDIR /opt/ 16 | RUN ls -l 17 | CMD ["/bin/bash", "-c", "find -type f -name '*SNAPSHOT.jar' | xargs java -jar"] -------------------------------------------------------------------------------- /template/dockerfiles/gradlew/draft.yaml: -------------------------------------------------------------------------------- 1 | language: gradle 2 | displayName: Gradle 3 | templateName: "dockerfile-gradlew" 4 | description: "This template is used to create a Dockerfile for a Gradle application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "BUILDERVERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "jdk21" 21 | description: "the version of gradle used during the builder stage to generate the executable" 22 | exampleValues: ["jdk8", "jdk11", "jdk17", "jdk19", "jdk21"] 23 | versions: ">=0.0.1" 24 | - name: "VERSION" 25 | type: "string" 26 | kind: "containerImageVersion" 27 | default: 28 | value: "21-jre" 29 | description: "the java version used by the application" 30 | exampleValues: ["11-jre", "17-jre", "19-jre", "21-jre"] 31 | versions: ">=0.0.1" 32 | - name: "DOCKERFILENAME" 33 | type: "string" 34 | kind: "dockerFileName" 35 | default: 36 | value: "Dockerfile" 37 | disablePrompt: true 38 | description: "the name of the Dockerfile" 39 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/java/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | target/ 4 | work/ 5 | .git/ 6 | -------------------------------------------------------------------------------- /template/dockerfiles/java/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM maven:{{ .Config.GetVariableValue "BUILDERVERSION" }} as BUILD 2 | 3 | COPY . /usr/src/app 4 | RUN mvn --batch-mode -f /usr/src/app/pom.xml clean package 5 | 6 | FROM eclipse-temurin:{{ .Config.GetVariableValue "VERSION" }} 7 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 8 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 9 | COPY --from=BUILD /usr/src/app/target /opt/target 10 | WORKDIR /opt/target 11 | 12 | CMD ["/bin/bash", "-c", "find -type f -name '*-SNAPSHOT.jar' | xargs java -jar"] 13 | -------------------------------------------------------------------------------- /template/dockerfiles/java/draft.yaml: -------------------------------------------------------------------------------- 1 | language: java 2 | displayName: Java 3 | templateName: "dockerfile-java" 4 | description: "This template is used to create a Dockerfile for a Java application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "BUILDERVERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "3" 21 | description: "the version of maven used during the builder stage to generate the executable" 22 | exampleValues: 23 | ["3-eclipse-temurin-17", "3-eclipse-temurin-21", "3 (jdk-21)"] 24 | versions: ">=0.0.1" 25 | - name: "VERSION" 26 | type: "string" 27 | kind: "containerImageVersion" 28 | default: 29 | value: "21-jre" 30 | description: "the java version used by the application" 31 | exampleValues: ["11-jre", "17-jre", "19-jre", "21-jre"] 32 | versions: ">=0.0.1" 33 | - name: "DOCKERFILENAME" 34 | type: "string" 35 | kind: "dockerFileName" 36 | default: 37 | value: "Dockerfile" 38 | disablePrompt: true 39 | description: "the name of the Dockerfile" 40 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/javascript/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | -------------------------------------------------------------------------------- /template/dockerfiles/javascript/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:{{ .Config.GetVariableValue "VERSION" }} 2 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 3 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 4 | 5 | RUN mkdir -p /usr/src/app 6 | WORKDIR /usr/src/app 7 | COPY package.json . 8 | RUN npm install 9 | COPY . . 10 | 11 | CMD ["npm", "start"] 12 | -------------------------------------------------------------------------------- /template/dockerfiles/javascript/draft.yaml: -------------------------------------------------------------------------------- 1 | language: javascript 2 | displayName: JavaScript 3 | templateName: "dockerfile-javascript" 4 | description: "This template is used to create a Dockerfile for a JavaScript application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "VERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "14" 21 | description: "the version of node used in the application" 22 | exampleValues: ["10.16.3", "12.16.3", "14.15.4"] 23 | versions: ">=0.0.1" 24 | - name: "DOCKERFILENAME" 25 | type: "string" 26 | kind: "dockerFileName" 27 | default: 28 | value: "Dockerfile" 29 | disablePrompt: true 30 | description: "the name of the Dockerfile" 31 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/php/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | -------------------------------------------------------------------------------- /template/dockerfiles/php/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM composer:{{ .Config.GetVariableValue "BUILDERVERSION" }} AS build-env 2 | COPY . /app 3 | RUN cd /app && composer install 4 | 5 | FROM php:{{ .Config.GetVariableValue "VERSION" }} 6 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 7 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 8 | COPY --from=build-env /app /var/www/html 9 | RUN usermod -u 1000 www-data; \ 10 | a2enmod rewrite; \ 11 | chown -R www-data:www-data /var/www/html 12 | -------------------------------------------------------------------------------- /template/dockerfiles/php/draft.yaml: -------------------------------------------------------------------------------- 1 | language: php 2 | displayName: PHP 3 | templateName: "dockerfile-php" 4 | description: "This template is used to create a Dockerfile for a PHP application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "BUILDERVERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "1" 21 | description: "the version of composer installed during the build stage to be used by the application" 22 | exampleValues: ["1"] 23 | versions: ">=0.0.1" 24 | - name: "VERSION" 25 | type: "string" 26 | kind: "containerImageVersion" 27 | default: 28 | value: "7.1-apache" 29 | description: "the version of php used by the application" 30 | exampleValues: ["7.1-apache"] 31 | versions: ">=0.0.1" 32 | - name: "DOCKERFILENAME" 33 | type: "string" 34 | kind: "dockerFileName" 35 | default: 36 | value: "Dockerfile" 37 | disablePrompt: true 38 | description: "the name of the Dockerfile" 39 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/python/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | -------------------------------------------------------------------------------- /template/dockerfiles/python/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:{{ .Config.GetVariableValue "VERSION" }} 2 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 3 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 4 | WORKDIR /usr/src/app 5 | 6 | COPY requirements.txt ./ 7 | RUN pip install --no-cache-dir -r requirements.txt 8 | 9 | COPY . . 10 | 11 | ENTRYPOINT ["python"] 12 | CMD ["{{ .Config.GetVariableValue "ENTRYPOINT" }}"] -------------------------------------------------------------------------------- /template/dockerfiles/python/draft.yaml: -------------------------------------------------------------------------------- 1 | language: python 2 | displayName: Python 3 | templateName: "dockerfile-python" 4 | description: "This template is used to create a Dockerfile for a Python application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | kind: "port" 11 | type: "int" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "VERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "3" 21 | description: "the version of python used by the application" 22 | exampleValues: ["3.9", "3.8", "3.7", "3.6"] 23 | versions: ">=0.0.1" 24 | - name: "ENTRYPOINT" 25 | type: "string" 26 | kind: "filePath" 27 | default: 28 | value: "app.py" 29 | description: "the entrypoint file of the repository" 30 | exampleValues: ["app.py", "main.py"] 31 | versions: ">=0.0.1" 32 | - name: "DOCKERFILENAME" 33 | type: "string" 34 | kind: "dockerFileName" 35 | default: 36 | value: "Dockerfile" 37 | disablePrompt: true 38 | description: "the name of the Dockerfile" 39 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/ruby/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | tmp/ 4 | -------------------------------------------------------------------------------- /template/dockerfiles/ruby/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:{{ .Config.GetVariableValue "VERSION" }} 2 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 3 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 4 | RUN bundle config --global frozen 1 5 | 6 | WORKDIR /usr/src/app 7 | 8 | COPY Gemfile Gemfile.lock ./ 9 | RUN bundle install 10 | 11 | COPY . . 12 | CMD ["ruby", "app.rb"] 13 | -------------------------------------------------------------------------------- /template/dockerfiles/ruby/draft.yaml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | displayName: Ruby 3 | templateName: "dockerfile-ruby" 4 | description: "This template is used to create a Dockerfile for a Ruby application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "VERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "3.1.2" 21 | description: "the version of ruby used by the application" 22 | exampleValues: ["3.1.2", "2.6", "2.5", "2.4"] 23 | versions: ">=0.0.1" 24 | - name: "DOCKERFILENAME" 25 | type: "string" 26 | kind: "dockerFileName" 27 | default: 28 | value: "Dockerfile" 29 | disablePrompt: true 30 | description: "the name of the Dockerfile" 31 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/rust/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | target 4 | -------------------------------------------------------------------------------- /template/dockerfiles/rust/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:{{ .Config.GetVariableValue "VERSION" }} 2 | 3 | WORKDIR /usr/src/app 4 | COPY . /usr/src/app 5 | RUN cargo build 6 | 7 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 8 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 9 | 10 | CMD ["cargo", "run", "-q"] 11 | -------------------------------------------------------------------------------- /template/dockerfiles/rust/draft.yaml: -------------------------------------------------------------------------------- 1 | language: rust 2 | displayName: Rust 3 | templateName: "dockerfile-rust" 4 | description: "This template is used to create a Dockerfile for a Rust application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "VERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "1.82.0" 21 | description: "the version of rust used by the application" 22 | exampleValues: ["1.70.0", "1.65.0", "1.60", "1.54", "1.53"] 23 | versions: ">=0.0.1" 24 | - name: "DOCKERFILENAME" 25 | type: "string" 26 | kind: "dockerFileName" 27 | default: 28 | value: "Dockerfile" 29 | disablePrompt: true 30 | description: "the name of the Dockerfile" 31 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/swift/.dockerignore: -------------------------------------------------------------------------------- 1 | {{ .Config.GetVariableValue "DOCKERFILENAME" }} 2 | charts/ 3 | -------------------------------------------------------------------------------- /template/dockerfiles/swift/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM swift:{{ .Config.GetVariableValue "VERSION" }} 2 | 3 | WORKDIR /src 4 | COPY . /src 5 | RUN apt-get update && apt-get install -y sudo openssl libssl-dev libcurl4-openssl-dev 6 | RUN swift build -c release 7 | 8 | ENV PORT {{ .Config.GetVariableValue "PORT" }} 9 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 10 | 11 | CMD ["swift", "run"] 12 | -------------------------------------------------------------------------------- /template/dockerfiles/swift/draft.yaml: -------------------------------------------------------------------------------- 1 | language: swift 2 | displayName: Swift 3 | templateName: "dockerfile-swift" 4 | description: "This template is used to create a Dockerfile for a Swift application" 5 | versions: ["0.0.1"] 6 | defaultVersion: "0.0.1" 7 | type: "dockerfile" 8 | variables: 9 | - name: "PORT" 10 | type: "int" 11 | kind: "port" 12 | default: 13 | value: "80" 14 | description: "the port exposed in the application" 15 | versions: ">=0.0.1" 16 | - name: "VERSION" 17 | type: "string" 18 | kind: "containerImageVersion" 19 | default: 20 | value: "5.5" 21 | description: "the version of swift used by the application" 22 | exampleValues: ["5.2", "5.5"] 23 | versions: ">=0.0.1" 24 | - name: "DOCKERFILENAME" 25 | type: "string" 26 | kind: "dockerFileName" 27 | default: 28 | value: "Dockerfile" 29 | disablePrompt: true 30 | description: "the name of the Dockerfile" 31 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/dockerfiles/tomcat/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM tomcat:{{ .Config.GetVariableValue "VERSION" }} 2 | 3 | ADD sample.war /usr/local/tomcat/webapps/ 4 | 5 | EXPOSE {{ .Config.GetVariableValue "PORT" }} 6 | 7 | CMD [“catalina.sh”, “run”] -------------------------------------------------------------------------------- /template/dockerfiles/tomcat/draft.yaml: -------------------------------------------------------------------------------- 1 | 2 | language: java-tomcat 3 | displayName: Java-Tomcat 4 | templateName: "dockerfile-java-tomcat" 5 | description: "This template is used to create a Dockerfile for a Java Tomcat application" 6 | versions: ["0.0.1"] 7 | defaultVersion: "0.0.1" 8 | type: "dockerfile" 9 | variables: 10 | - name: "PORT" 11 | type: "int" 12 | kind: "port" 13 | default: 14 | value: "80" 15 | description: "the port exposed in the application" 16 | versions: ">=0.0.1" 17 | - name: "VERSION" 18 | type: "string" 19 | kind: "containerImageVersion" 20 | default: 21 | value: "8.0-alpine" 22 | description: "the tomcat image version used by the application" 23 | exampleValues: ["8.0-alpine"] 24 | versions: ">=0.0.1" 25 | - name: "DOCKERFILENAME" 26 | type: "string" 27 | kind: "dockerFileName" 28 | default: 29 | value: "Dockerfile" 30 | disablePrompt: true 31 | description: "the name of the Dockerfile" 32 | versions: ">=0.0.1" -------------------------------------------------------------------------------- /template/manifests/HorizontalPodAutoscaler/manifests/hpa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v2 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: {{ .Config.GetVariableValue "APPNAME" }} 5 | labels: 6 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 7 | app.kubernetes.io/part-of: {{ .Config.GetVariableValue "PARTOF" }} 8 | kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} 9 | spec: 10 | scaleTargetRef: 11 | apiVersion: apps/v1 12 | kind: Deployment 13 | name: {{ .Config.GetVariableValue "APPNAME" }} 14 | minReplicas: {{ .Config.GetVariableValue "MINIMUMREPLICAS" }} 15 | maxReplicas: {{ .Config.GetVariableValue "MAXIMUMREPLICAS" }} 16 | metrics: 17 | - type: Resource 18 | resource: 19 | name: {{ .Config.GetVariableValue "RESOURCETYPE" }} 20 | target: 21 | type: Utilization 22 | averageUtilization: {{ .Config.GetVariableValue "AVGUTILIZATION"}} -------------------------------------------------------------------------------- /template/manifests/PodDisruptionBudget/manifests/draft.yaml: -------------------------------------------------------------------------------- 1 | templateName: "podDisruptionBudget-manifests" 2 | description: "This template is used to create a PodDisruptionBudget for an application" 3 | versions: ["0.0.1"] 4 | defaultVersions: "0.0.1" 5 | type: "manifest" 6 | variables: 7 | - name: "APPNAME" 8 | type: "string" 9 | kind: "kubernetesResourceName" 10 | description: "the name of the application" 11 | versions: ">=0.0.1" 12 | - name: "PARTOF" 13 | type: "string" 14 | kind: "label" 15 | description: "the label to identify which project the resource belong to" 16 | versions: ">=0.0.1" 17 | - name: "GENERATORLABEL" 18 | type: "string" 19 | kind: "label" 20 | description: "the label to identify who generated the resource" 21 | versions: ">=0.0.1" 22 | default: 23 | value: "draft" 24 | - name: "MAXUNAVAILABLE" 25 | type: "int" 26 | kind: "resourceLimit" 27 | description: "specifies the maximum number of pods that can be unavailable during a disruption, such as a pod eviction" 28 | versions: ">=0.0.1" 29 | default: 30 | value: 1 -------------------------------------------------------------------------------- /template/manifests/PodDisruptionBudget/manifests/pdb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: {{.Config.GetVariableValue "APPNAME" }} 5 | labels: 6 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME"}} 7 | app.kubernetes.io/part-of: {{ .Config.GetVariableValue "PARTOF" }} 8 | kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL"}} 9 | spec: 10 | maxUnavailable: {{ .Config.GetVariableValue "MAXUNAVAILABLE" }} 11 | selector: 12 | matchLabels: 13 | app: {{ .Config.GetVariableValue "APPNAME" }} -------------------------------------------------------------------------------- /template/manifests/Service/manifests/draft.yaml: -------------------------------------------------------------------------------- 1 | templateName: "service-manifests" 2 | description: "This template is used to create a generic Service for an application" 3 | versions: ["0.0.1"] 4 | defaultVersion: "0.0.1" 5 | type: "manifest" 6 | variables: 7 | - name: "PORT" 8 | type: "int" 9 | kind: "port" 10 | description: "the port the service uses to make the application accessible from outside the cluster" 11 | versions: ">=0.0.1" 12 | default: 13 | value: 80 14 | - name: "APPNAME" 15 | type: "string" 16 | kind: "kubernetesResourceName" 17 | description: "the name of the application" 18 | versions: ">=0.0.1" 19 | - name: "PARTOF" 20 | type: "string" 21 | kind: "label" 22 | description: "the label to identify which project the resource belong to" 23 | versions: ">=0.0.1" 24 | - name: "GENERATORLABEL" 25 | type: "string" 26 | kind: "label" 27 | description: "the label to identify who generated the resource" 28 | versions: ">=0.0.1" 29 | default: 30 | value: "draft" 31 | - name: "TARGETPORT" 32 | type: "int" 33 | kind: "port" 34 | description: "the port exposed in the application" 35 | versions: ">=0.0.1" 36 | default: 37 | referenceVar: "PORT" -------------------------------------------------------------------------------- /template/manifests/Service/manifests/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Config.GetVariableValue "APPNAME" }} 5 | labels: 6 | app.kubernetes.io/name: {{ .Config.GetVariableValue "APPNAME" }} 7 | app.kubernetes.io/part-of: {{ .Config.GetVariableValue "PARTOF" }} 8 | kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} 9 | spec: 10 | type: ClusterIP 11 | selector: 12 | app: {{ .Config.GetVariableValue "APPNAME" }} 13 | ports: 14 | - protocol: TCP 15 | port: {{ .Config.GetVariableValue "PORT" }} 16 | targetPort: {{ .Config.GetVariableValue "TARGETPORT" }} -------------------------------------------------------------------------------- /template/templates.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import "embed" 4 | 5 | var ( 6 | //go:embed all:* 7 | Templates embed.FS 8 | ) 9 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # Integration Test 2 | 3 | To generate integration tests put all relevant information in the `integration_config.json` file. Then run the `gen_integration.sh` script to autogenerate the workflow and configs. You must have jq installed to run this. 4 | 5 | Edit the `gen_integration.sh` script to make any changes to how integration tests are written. The `test/integration` folder and `.github/workflows/integration.yml` file are autogenerated so manual changes to them will be overwritten. 6 | -------------------------------------------------------------------------------- /test/check_info_schema.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | mkdir -p ./test/temp 4 | ./draft info > ./test/temp/info.json 5 | echo "Draft Info JSON schema:" 6 | cat ./test/info_schema.json 7 | echo "Draft Info JSON:" 8 | cat ./test/temp/info.json 9 | 10 | npm install -g ajv-cli 11 | echo "Validating Draft Info JSON against schema" 12 | ajv validate -s ./test/info_schema.json -d ./test/temp/info.json -------------------------------------------------------------------------------- /test/check_windows_addon_helm.ps1: -------------------------------------------------------------------------------- 1 | $filesExist=$true 2 | $filesExist=$filesExist -and (Test-Path -Path ./charts/templates/ingress.yaml -PathType Leaf) 3 | echo "$file exists: $filesExist" 4 | if (-not $filesExist) {Exit 1} 5 | -------------------------------------------------------------------------------- /test/check_windows_addon_kustomize.ps1: -------------------------------------------------------------------------------- 1 | $filesExist=$true 2 | $filesExist=$filesExist -and (Test-Path -Path ./overlays/production/ingress.yaml -PathType Leaf) 3 | echo "$file exists: $filesExist" 4 | if (-not $filesExist) {Exit 1} 5 | -------------------------------------------------------------------------------- /test/check_windows_helm.ps1: -------------------------------------------------------------------------------- 1 | $filesExist=$true 2 | $filesExist=$filesExist -and (Test-Path -Path ./charts/Chart.yaml -PathType Leaf) 3 | echo "$file exists: $filesExist" 4 | $filesExist=$filesExist -and (Test-Path -Path ./charts/production.yaml -PathType Leaf) 5 | echo "$file exists: $filesExist" 6 | $filesExist=$filesExist -and (Test-Path -Path ./charts/.helmignore -PathType Leaf) 7 | echo "$file exists: $filesExist" 8 | $filesExist=$filesExist -and (Test-Path -Path ./charts/templates/deployment.yaml -PathType Leaf) 9 | echo "$file exists: $filesExist" 10 | $filesExist=$filesExist -and (Test-Path -Path ./charts/templates/service.yaml -PathType Leaf) 11 | echo "$file exists: $filesExist" 12 | $filesExist=$filesExist -and (Test-Path -Path ./charts/templates/_helpers.tpl -PathType Leaf) 13 | echo "$file exists: $filesExist" 14 | $filesExist=$filesExist -and (Test-Path -Path ./charts/values.yaml -PathType Leaf) 15 | echo "$file exists: $filesExist" 16 | if (-not $filesExist) {Exit 1} 17 | -------------------------------------------------------------------------------- /test/check_windows_kustomize.ps1: -------------------------------------------------------------------------------- 1 | $filesExist=$true 2 | $filesExist=$filesExist -and (Test-Path -Path ./overlays/production/deployment.yaml -PathType Leaf) 3 | echo "$file exists: $filesExist" 4 | $filesExist=$filesExist -and (Test-Path -Path ./overlays/production/kustomization.yaml -PathType Leaf) 5 | echo "$file exists: $filesExist" 6 | $filesExist=$filesExist -and (Test-Path -Path ./overlays/production/service.yaml -PathType Leaf) 7 | echo "$file exists: $filesExist" 8 | $filesExist=$filesExist -and (Test-Path -Path ./base/deployment.yaml -PathType Leaf) 9 | echo "$file exists: $filesExist" 10 | $filesExist=$filesExist -and (Test-Path -Path ./base/kustomization.yaml -PathType Leaf) 11 | echo "$file exists: $filesExist" 12 | $filesExist=$filesExist -and (Test-Path -Path ./base/service.yaml -PathType Leaf) 13 | echo "$file exists: $filesExist" 14 | if (-not $filesExist) {Exit 1} 15 | -------------------------------------------------------------------------------- /test/gen_windows_check.sh: -------------------------------------------------------------------------------- 1 | deployDir="./deployTypes" 2 | 3 | 4 | deployTypes=("helm" "kustomize") 5 | 6 | ignoredFiles=("./draft.yaml" "./skaffold.yaml" "./charts/templates/helpers.tpl" "./charts/helmignore") 7 | let count=0 8 | for deploy in ${deployTypes[@]};do 9 | scriptName=./test/check_windows_$deploy.ps1 10 | echo "listing files for $deploy" 11 | cd $deployDir/$deploy 12 | files=$(find . -type f) 13 | cd ../.. 14 | 15 | rm $scriptName 16 | touch $scriptName 17 | echo "\$filesExist=\$true" >> $scriptName 18 | for file in $files 19 | do 20 | ignoreFile=0 21 | for ignore in ${ignoredFiles[@]};do 22 | echo "${ignore}" 23 | echo "${file}" 24 | if [[ "$ignore" == "$file" ]];then 25 | ignoreFile=1 26 | fi 27 | done 28 | 29 | if [[ $ignoreFile == 0 ]]; then 30 | 31 | echo "\$filesExist=\$filesExist -and (Test-Path -Path $file -PathType Leaf)" >> $scriptName 32 | echo 'echo "$file exists: $filesExist"' >> $scriptName 33 | 34 | fi 35 | done 36 | echo "if (-not \$filesExist) {Exit 1}" >> $scriptName 37 | 38 | done -------------------------------------------------------------------------------- /test/integration/clojure/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "clojure" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "8-jdk-alpine" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/clojure/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "clojure" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "8-jdk-alpine" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/clojure/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "clojure" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "8-jdk-alpine" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/csharp/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "csharp" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "80" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "5.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "80" 20 | -------------------------------------------------------------------------------- /test/integration/csharp/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "csharp" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "80" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "5.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "80" 20 | -------------------------------------------------------------------------------- /test/integration/csharp/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "csharp" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "80" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "5.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "80" 20 | -------------------------------------------------------------------------------- /test/integration/erlang/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "erlang" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "3.17" 16 | - name: "BUILDERVERSION" 17 | value: "27.0-alpine" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/erlang/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "erlang" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "3.17" 16 | - name: "BUILDERVERSION" 17 | value: "27.0-alpine" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/erlang/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "erlang" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "3.17" 16 | - name: "BUILDERVERSION" 17 | value: "27.0-alpine" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/go/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "go" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "1.22.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/go/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "go" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "1.22.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/go/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "go" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "1.22.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/gomodule/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "gomodule" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "1323" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "1.22.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "1323" 20 | -------------------------------------------------------------------------------- /test/integration/gomodule/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "gomodule" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "1323" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "1.22.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "1323" 20 | -------------------------------------------------------------------------------- /test/integration/gomodule/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "gomodule" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "1323" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "1.22.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "1323" 20 | -------------------------------------------------------------------------------- /test/integration/gradle/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "gradle" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "11-jre" 16 | - name: "BUILDERVERSION" 17 | value: "7-jdk11" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/gradle/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "gradle" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "11-jre" 16 | - name: "BUILDERVERSION" 17 | value: "7-jdk11" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/gradle/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "gradle" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "11-jre" 16 | - name: "BUILDERVERSION" 17 | value: "7-jdk11" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/java/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "java" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "11-jre" 16 | - name: "BUILDERVERSION" 17 | value: "3-jdk-11" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/java/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "java" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "11-jre" 16 | - name: "BUILDERVERSION" 17 | value: "3-jdk-11" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/java/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "java" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "11-jre" 16 | - name: "BUILDERVERSION" 17 | value: "3-jdk-11" 18 | - name: "PORT" 19 | value: "8080" 20 | -------------------------------------------------------------------------------- /test/integration/javascript/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "javascript" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "1313" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "14" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "1313" 20 | -------------------------------------------------------------------------------- /test/integration/javascript/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "javascript" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "1313" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "14" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "1313" 20 | -------------------------------------------------------------------------------- /test/integration/javascript/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "javascript" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "1313" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "14" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "1313" 20 | -------------------------------------------------------------------------------- /test/integration/python/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "python" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "5000" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "3" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "5000" 20 | -------------------------------------------------------------------------------- /test/integration/python/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "python" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "5000" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "3" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "5000" 20 | -------------------------------------------------------------------------------- /test/integration/python/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "python" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "5000" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "3" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "5000" 20 | -------------------------------------------------------------------------------- /test/integration/ruby/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "ruby" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "4567" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "3.1.2" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "4567" 20 | -------------------------------------------------------------------------------- /test/integration/ruby/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "ruby" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "4567" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "3.1.2" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "4567" 20 | -------------------------------------------------------------------------------- /test/integration/ruby/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "ruby" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "4567" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "3.1.2" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "4567" 20 | -------------------------------------------------------------------------------- /test/integration/rust/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "rust" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8000" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "1.82.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "8000" 20 | -------------------------------------------------------------------------------- /test/integration/rust/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "rust" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8000" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "1.82.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "8000" 20 | -------------------------------------------------------------------------------- /test/integration/rust/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "rust" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8000" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | languageVariables: 14 | - name: "VERSION" 15 | value: "1.82.0" 16 | - name: "BUILDERVERSION" 17 | value: "null" 18 | - name: "PORT" 19 | value: "8000" 20 | -------------------------------------------------------------------------------- /test/integration/swift/helm.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "Helm" 3 | languageType: "swift" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | - name: "CPULIMIT" 14 | value: "3" 15 | - name: "MEMLIMIT" 16 | value: "2Gi" 17 | - name: "STARTUPINITIALDELAY" 18 | value: 30 19 | languageVariables: 20 | - name: "VERSION" 21 | value: "5.5" 22 | - name: "BUILDERVERSION" 23 | value: "null" 24 | - name: "PORT" 25 | value: "8080" 26 | -------------------------------------------------------------------------------- /test/integration/swift/kustomize.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "kustomize" 3 | languageType: "swift" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | - name: "CPULIMIT" 14 | value: "3" 15 | - name: "MEMLIMIT" 16 | value: "2Gi" 17 | - name: "STARTUPINITIALDELAY" 18 | value: 30 19 | languageVariables: 20 | - name: "VERSION" 21 | value: "5.5" 22 | - name: "BUILDERVERSION" 23 | value: "null" 24 | - name: "PORT" 25 | value: "8080" 26 | -------------------------------------------------------------------------------- /test/integration/swift/manifest.yaml: -------------------------------------------------------------------------------- 1 | # this file is generated using gen_integration.sh 2 | deployType: "manifests" 3 | languageType: "swift" 4 | deployVariables: 5 | - name: "PORT" 6 | value: "8080" 7 | - name: "SERVICEPORT" 8 | value: "80" 9 | - name: "APPNAME" 10 | value: "testapp" 11 | - name: "IMAGENAME" 12 | value: "host.minikube.internal:5001/testapp" 13 | - name: "CPULIMIT" 14 | value: "3" 15 | - name: "MEMLIMIT" 16 | value: "2Gi" 17 | - name: "STARTUPINITIALDELAY" 18 | value: 30 19 | languageVariables: 20 | - name: "VERSION" 21 | value: "5.5" 22 | - name: "BUILDERVERSION" 23 | value: "null" 24 | - name: "PORT" 25 | value: "8080" 26 | -------------------------------------------------------------------------------- /test/skaffold.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skaffold/v2beta26 2 | kind: Config 3 | build: 4 | artifacts: 5 | - image: my-app 6 | local: 7 | useDockerCLI: true 8 | useBuildkit: false 9 | deploy: 10 | helm: 11 | releases: 12 | - name: my-chart 13 | chartPath: charts 14 | artifactOverrides: 15 | image: my-app 16 | imageStrategy: 17 | helm: {} 18 | -------------------------------------------------------------------------------- /test/templates/config.yaml: -------------------------------------------------------------------------------- 1 | DeployType: "kustomize" 2 | LanguageType: "go" 3 | DeployVariables: 4 | - Name: "PORT" 5 | Value: "8080" 6 | LanguageVariables: 7 | - Name: "PORT" 8 | Value: "8080" -------------------------------------------------------------------------------- /test/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-app 5 | labels: 6 | app: my-app 7 | kubernetes.azure.com/generator: draft 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: my-app 13 | template: 14 | metadata: 15 | labels: 16 | app: my-app 17 | spec: 18 | containers: 19 | - name: my-app 20 | image: my-app 21 | ports: 22 | - containerPort: 8000 -------------------------------------------------------------------------------- /test/templates/ensure_file.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/draft/9e9240a6a0cce34ad92a09634b0fe2edc4bc0145/test/templates/ensure_file.yaml -------------------------------------------------------------------------------- /test/templates/helm/charts/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /test/templates/helm/charts/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: test 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.16.0" 25 | -------------------------------------------------------------------------------- /test/templates/helm/charts/production.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: "test" 3 | pullPolicy: Always 4 | tag: "latest" 5 | service: 6 | annotations: {} 7 | type: LoadBalancer 8 | port: 80 9 | -------------------------------------------------------------------------------- /test/templates/helm/charts/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | kind: Namespace 2 | apiVersion: v1 3 | metadata: 4 | name: default 5 | labels: 6 | {{- include "test.labels" . | nindent 4 }} 7 | openservicemesh.io/monitored-by: osm 8 | kubernetes.azure.com/generator: draft 9 | annotations: 10 | openservicemesh.io/sidecar-injection: enabled 11 | 12 | -------------------------------------------------------------------------------- /test/templates/helm/charts/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "test.fullname" . }} 5 | labels: 6 | {{- include "test.labels" . | nindent 4 }} 7 | kubernetes.azure.com/generator: draft 8 | annotations: 9 | {{ toYaml .Values.service.annotations | nindent 4 }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | ports: 13 | - port: {{ .Values.service.port }} 14 | targetPort: {{ .Values.containerPort }} 15 | protocol: TCP 16 | name: svchttp 17 | selector: 18 | {{- include "test.selectorLabels" . | nindent 4 }} 19 | -------------------------------------------------------------------------------- /test/templates/helm_prod_values.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: "prodImage" 3 | pullPolicy: Always 4 | tag: "latest" 5 | -------------------------------------------------------------------------------- /test/templates/invalid_deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: my-app 5 | labels: 6 | app: my-app 7 | kubernetes.azure.com/generator: draft 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: my-app 13 | template: 14 | metadata: 15 | labels: 16 | app: my-app 17 | spec: 18 | containers: 19 | - name: my-app 20 | image: my-app 21 | ports: 22 | - containerPort: 8000 -------------------------------------------------------------------------------- /test/templates/kustomize/base/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test 5 | labels: 6 | app: test 7 | kubernetes.azure.com/generator: draft 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: test 13 | template: 14 | metadata: 15 | labels: 16 | app: test 17 | spec: 18 | containers: 19 | - name: test 20 | image: test:latest 21 | ports: 22 | - containerPort: 80 -------------------------------------------------------------------------------- /test/templates/kustomize/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - deployment.yaml 5 | - service.yaml -------------------------------------------------------------------------------- /test/templates/kustomize/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: test 5 | labels: 6 | kubernetes.azure.com/generator: draft 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: test 11 | ports: 12 | - protocol: TCP 13 | port: 80 14 | targetPort: 80 -------------------------------------------------------------------------------- /test/templates/kustomize/overlays/production/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test 5 | labels: 6 | kubernetes.azure.com/generator: draft 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: test 12 | image: acr.test:latest -------------------------------------------------------------------------------- /test/templates/kustomize/overlays/production/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namePrefix: production- 2 | resources: 3 | - ../../base 4 | patchesStrategicMerge: 5 | - deployment.yaml 6 | - service.yaml -------------------------------------------------------------------------------- /test/templates/kustomize/overlays/production/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: test 5 | labels: 6 | kubernetes.azure.com/generator: draft 7 | spec: 8 | type: LoadBalancer 9 | -------------------------------------------------------------------------------- /test/templates/manifests/manifests/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test 5 | labels: 6 | app: test 7 | kubernetes.azure.com/generator: draft 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: test 13 | template: 14 | metadata: 15 | labels: 16 | app: test 17 | spec: 18 | containers: 19 | - name: test 20 | image: test 21 | ports: 22 | - containerPort: 8000 -------------------------------------------------------------------------------- /test/templates/manifests/manifests/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: test 5 | labels: 6 | kubernetes.azure.com/generator: draft 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: test 11 | ports: 12 | - protocol: TCP 13 | port: 80 14 | targetPort: 80 -------------------------------------------------------------------------------- /test/templates/service_w_annotations.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-app 5 | labels: 6 | kubernetes.azure.com/generator: draft 7 | spec: 8 | type: LoadBalancer 9 | -------------------------------------------------------------------------------- /test/templates/unsupported_no_of_containers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: my-app 5 | labels: 6 | app: my-app 7 | kubernetes.azure.com/generator: draft 8 | spec: 9 | replicas: 2 10 | selector: 11 | matchLabels: 12 | app: my-app 13 | template: 14 | metadata: 15 | labels: 16 | app: my-app 17 | spec: 18 | containers: 19 | - name: my-app 20 | image: my-app 21 | ports: 22 | - containerPort: 8000 23 | - name: my-app-2 24 | image: my-app-2 25 | ports: 26 | - containerPort: 8080 --------------------------------------------------------------------------------