diff --git a/README.md b/README.md index a2bd2b0b..20165747 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ When you run `bazel run ///helloworld:mynamespace.apply`, it applies this file i | ***release_branch_prefix*** | `master` | A git branch name/prefix. Automatically run GitOps while building this branch. See [GitOps and Deployment](#gitops_and_deployment). | ***deployment_branch*** | `None` | Automatic GitOps output will appear in a branch and PR with this name. See [GitOps and Deployment](#gitops_and_deployment). | ***gitops_path*** | `cloud` | Path within the git repo where gitops files get generated into +| ***app_grp*** | `` | Optional folder for grouping apps after gitops_path in git repo | ***tags*** | `[]` | See [Bazel docs on tags](https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes). | ***visibility*** | [Default_visibility](https://docs.bazel.build/versions/master/be/functions.html#package.default_visibility) | Changes the visibility of all rules generated by this macro. See [Bazel docs on visibility](https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes). diff --git a/examples/e2e-test.sh b/examples/e2e-test.sh index b76c9d95..e4c6f7f1 100755 --- a/examples/e2e-test.sh +++ b/examples/e2e-test.sh @@ -40,6 +40,7 @@ rm -rf cloud bazel run //helloworld:canary.gitops bazel run //helloworld:release.gitops bazel run //helloworld:gitops_custom_path.gitops +bazel run //helloworld:gitops_with_app_grp.gitops #the result of .gitops operation goes into /cloud directory and should be submitted back to the repo #apply everything generated @@ -48,5 +49,8 @@ kubectl apply -f cloud -R #apply gitops_custom_path gen kubectl apply -f custom_cloud -R +#apply gitops_with_app_grp gen (should create cloud/backend/hwteam/kind-kind/ structure) +kubectl apply -f cloud/backend -R + #wait for readiness kubectl -n hwteam wait --timeout=60s --for=condition=Available deployment/helloworld deployment/helloworld-canary deployment/helloworld-gitops-custom-path diff --git a/examples/helloworld/BUILD b/examples/helloworld/BUILD index 2fff4c0c..5061532d 100644 --- a/examples/helloworld/BUILD +++ b/examples/helloworld/BUILD @@ -123,6 +123,26 @@ k8s_deploy( user = USER, ) +k8s_deploy( + name = "gitops_with_app_grp", + app_grp = "backend", # This will create path: cloud/backend/hwteam/kind-kind/gitops_with_app_grp.yaml + cluster = CLUSTER, + deployment_branch = "helloworld-gitops-app-grp", + # image_digest_tag = True, # test optional image tagging + # image_registry = REGISTRY, # override the default registry host for production + # image_repository_prefix = "k8s", + images = { + "helloworld-image": ":image", + }, + manifests = [ + "deployment.yaml", + "service.yaml", + ], + name_suffix = "-gitops-app-grp", + namespace = NAMESPACE, + user = USER, +) + sh_test( name = "k8s_deploy_test", srcs = ["k8s_deploy_test.sh"], diff --git a/skylib/k8s.bzl b/skylib/k8s.bzl index 8391fa94..134a1c51 100644 --- a/skylib/k8s.bzl +++ b/skylib/k8s.bzl @@ -111,6 +111,7 @@ def k8s_deploy( cluster = "dev", user = "{BUILD_USER}", namespace = None, + app_grp = None, # optional application group to insert between gitops_path and namespace in the file path configmaps_srcs = None, secrets_srcs = None, configmaps_renaming = None, # configmaps renaming policy. Could be None or 'hash'. @@ -279,6 +280,7 @@ def k8s_deploy( srcs = [name], cluster = cluster, namespace = namespace, + app_grp = app_grp, gitops_path = gitops_path, strip_prefixes = [ namespace + "-", diff --git a/skylib/kustomize/kustomize.bzl b/skylib/kustomize/kustomize.bzl index a6f13b75..2d61bd0e 100644 --- a/skylib/kustomize/kustomize.bzl +++ b/skylib/kustomize/kustomize.bzl @@ -440,19 +440,30 @@ fi """.format(push_statements) namespace = ctx.attr.namespace + app_grp = ctx.attr.app_grp + + # Construct the path with optional app_grp + if app_grp: + path_template = "{gitops_path}/{app_grp}/{namespace}/{cluster}/{file}" + mkdir_template = "{gitops_path}/{app_grp}/{namespace}/{cluster}" + else: + path_template = "{gitops_path}/{namespace}/{cluster}/{file}" + mkdir_template = "{gitops_path}/{namespace}/{cluster}" + for inattr in ctx.attr.srcs: if "{" in namespace: fail("unable to gitops namespace with placeholders %s" % inattr.label) #mynamespace should not be gitopsed for infile in inattr.files.to_list(): - statements += ("echo $TARGET_DIR/{gitops_path}/{namespace}/{cluster}/{file}\n" + - "mkdir -p $TARGET_DIR/{gitops_path}/{namespace}/{cluster}\n" + - "echo '# GENERATED BY {rulename} -> {gitopsrulename}' > $TARGET_DIR/{gitops_path}/{namespace}/{cluster}/{file}\n" + - "{template_engine} --template={infile} --variable=NAMESPACE={namespace} --stamp_info_file={info_file} >> $TARGET_DIR/{gitops_path}/{namespace}/{cluster}/{file}\n").format( + statements += ("echo $TARGET_DIR/" + path_template + "\n" + + "mkdir -p $TARGET_DIR/" + mkdir_template + "\n" + + "echo '# GENERATED BY {rulename} -> {gitopsrulename}' > $TARGET_DIR/" + path_template + "\n" + + "{template_engine} --template={infile} --variable=NAMESPACE={namespace} --stamp_info_file={info_file} >> $TARGET_DIR/" + path_template + "\n").format( infile = infile.path, rulename = inattr.label, gitopsrulename = ctx.label, namespace = namespace, gitops_path = ctx.attr.gitops_path, + app_grp = app_grp, cluster = cluster, file = _remove_prefixes(infile.path.split("/")[-1], strip_prefixes), template_engine = "${RUNFILES}/%s" % _get_runfile_path(ctx, ctx.executable._template_engine), @@ -485,6 +496,7 @@ gitops = rule( "srcs": attr.label_list(providers = (KustomizeInfo,)), "cluster": attr.string(mandatory = True), "namespace": attr.string(mandatory = True), + "app_grp": attr.string(doc = "optional application group to insert between gitops_path and namespace in the file path"), "deployment_branch": attr.string(), "gitops_path": attr.string(), "release_branch_prefix": attr.string(), diff --git a/skylib/kustomize/tests/BUILD b/skylib/kustomize/tests/BUILD index 27a96a17..2e2c6a93 100644 --- a/skylib/kustomize/tests/BUILD +++ b/skylib/kustomize/tests/BUILD @@ -270,6 +270,57 @@ gitops( namespace = "test", ) +# Test gitops with app_grp parameter +gitops( + name = "dev-something-with-app-grp.gitops", + testonly = True, + srcs = [":namespace_test"], + app_grp = "backend", + cluster = "dev", + gitops_path = "cloud", + namespace = "test", +) + +# Test gitops without app_grp (should behave like original) +gitops( + name = "dev-something-no-app-grp.gitops", + testonly = True, + srcs = [":namespace_test"], + cluster = "dev", + gitops_path = "cloud", + namespace = "test", + # app_grp intentionally omitted to test backward compatibility +) + +# Test rules to verify gitops output with app_grp +rule_test( + name = "gitops_with_app_grp_generates_executable", + generates = ["dev-something-with-app-grp.gitops"], + rule = "dev-something-with-app-grp.gitops", +) + +# Test rules to verify gitops output without app_grp (backward compatibility) +rule_test( + name = "gitops_no_app_grp_generates_executable", + generates = ["dev-something-no-app-grp.gitops"], + rule = "dev-something-no-app-grp.gitops", +) + +# File tests to verify gitops path generation +file_test( + name = "gitops_with_app_grp_path_test", + file = ":dev-something-with-app-grp.gitops", + matches = 4, # Should appear in echo, mkdir, echo comment, and template_engine commands + regexp = "cloud/backend", +) + +file_test( + name = "gitops_no_app_grp_path_test", + file = ":dev-something-no-app-grp.gitops", + matches = 4, # Should appear in echo, mkdir, echo comment, and template_engine commands + regexp = "cloud/test/dev", +) + #------------------- kustomize( name = "name_prefix",