solutions/gatekeeper-policies/naming-rules/project/template.yaml (83 lines of code) (raw):

# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ######### apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: namingpolicyproject annotations: description: Project Naming Enforcement Policy spec: crd: spec: names: kind: NamingPolicyProject validation: openAPIV3Schema: type: object properties: client_code: description: client code REGEX Naming convention. type: string env_code: description: Environment code REGEX Naming convention. type: string region_code: description: Region Code REGEX Naming convention. type: string class_code: description: Classification code REGEX Naming convention. type: string user_defined_string: description: User Defined String REGEX Naming convention. type: string targets: - target: admission.k8s.gatekeeper.sh rego: |- package NamingPolicy # Standard Project Naming Restrictions # https://cloud.google.com/resource-manager/docs/creating-managing-projects#before_you_begin # Maximum Project Length violation[{"msg": message}] { asset := input.review.object asset.kind == "Project" object_length = count(asset.metadata.name) object_length > 30 message := sprintf("Project '%s' has a name that is '%s' chars long which is greater than the allowed '%s'", [asset.metadata.name, object_length]) } # Minimum Project Length violation[{"msg": message}] { asset := input.review.object asset.kind == "Project" object_length = count(asset.metadata.name) object_length < 12 message := sprintf("Project '%s' has a name that is '%s' chars long which is less than the required '%s'", [asset.metadata.name, object_length]) } # Project name must contain only letters, numbers, hyphens, spaces, or exclamation points. # Project name must start with the client code/shortname followed by the multi-region code (m), the classification code (u = Unclassified, a = Protected A, b = Protected B), the owner short name, and a descriptive project name. # We will no longer be able to support camel case - see https://cloud.google.com/anthos-config-management/docs/reference/errors#knv1036 # <dept code><CSP region><classification>-<owner>-<project>-[<scope>] # example: zzmu-pe-auditbunker # # client code validation (client_code) violation[{"msg": message}] { asset := input.review.object asset.kind == "Project" client_code = input.parameters.client_code not re_match(client_code, asset.metadata.name) message := sprintf("Project '%s' does not match meet naming requirements: The client code is incorrect.", [asset.metadata.name]) } # Environment code validation (env_code) violation[{"msg": message}] { asset := input.review.object asset.kind == "Project" env_code = input.parameters.env_code not re_match(env_code, asset.metadata.name) message := sprintf("Project '%s' does not match meet naming requirements: The env code is incorrect. It must be (d = dev, p = production, e = experimentation, u = preprod).", [asset.metadata.name]) } # Region code validation (region_code) violation[{"msg": message}] { asset := input.review.object asset.kind == "Project" region_code = input.parameters.region_code not re_match(region_code, asset.metadata.name) message := sprintf("Project '%s' does not match meet naming requirements: The region code is incorrect. It must be multi-region code (m).", [asset.metadata.name]) } # classification code validation (class_code) violation[{"msg": message}] { asset := input.review.object asset.kind == "Project" class_code = input.parameters.class_code not re_match(class_code, asset.metadata.name) message := sprintf("Project '%s' does not match meet naming requirements: The classification code is incorrect. (u = Unclassified, a = Protected A, b = Protected B).", [asset.metadata.name]) } # User defined string validation (user_defined_string) violation[{"msg": message}] { asset := input.review.object asset.kind == "Project" user_defined_string = input.parameters.user_defined_string not re_match(user_defined_string, asset.metadata.name) message := sprintf("Project '%s' does not match meet naming requirements: The user defined string can only contain lowercase letters, numbers, and hyphens.", [asset.metadata.name]) }