Chapter 1. Governance Enterprises must meet internal standards for software engineering, secure engineering, resiliency, security, and regulatory compliance for workloads hosted on private, multi and hybrid clouds. Red Hat Advanced Cluster Management for Kubernetes governance provides an extensible policy framework for enterprises to introduce their own security policies. Continue reading the related topics of the Red Hat Advanced Cluster Management governance framework: Policy deployment Policy controllers Policy controller advanced configuration Configuring policy compliance history API (Technology Preview) Supported policies Policy dependencies Governance dashboard Securing the hub cluster Gatekeeper operator overview Integrating Policy Generator 1.1. Policy controllers Policy controllers monitor and report whether your cluster is compliant with a policy. Use the Red Hat Advanced Cluster Management for Kubernetes policy framework by using the supported policy templates to apply policies managed by these controllers. The policy controllers manage Kubernetes custom resource definition instances. Policy controllers check for policy violations, and can make the cluster status compliant if the controller supports the enforcement feature. View the following topics to learn more about the following Red Hat Advanced Cluster Management for Kubernetes policy controllers: Kubernetes configuration policy controller Certificate policy controller Policy set controller Operator policy controller Important: Only the configuration policy controller policies support the enforce feature. You must manually remediate policies, where the policy controller does not support the enforce feature. 1.1.1. Kubernetes configuration policy controller Use the configuration policy controller to configure any Kubernetes resource and apply security policies across your clusters. The configuration policy controller communicates with the local Kubernetes API server so that you can get a list of your configurations that are in your cluster. During installation, the configuration policy controller is created on the managed cluster. The configuration policy is provided in the policy-templates field of the policy on the hub cluster, and is propagated to the selected managed clusters by the governance framework. When the remediationAction for the configuration policy controller is set to InformOnly , the parent policy does not enforce the configuration policy, even if the remediationAction in the parent policy is set to enforce . If you have existing Kubernetes manifests that you want to put in a policy, the Policy Generator is a useful tool to accomplish this. 1.1.1.1. Configuration policy YAML structure You can find the description of a field on your managed cluster by running the oc explain --api-version=policy.open-cluster-management.io/v1 ConfigurationPolicy.<field-path> command. Replace <field-path> with the path to the field that you need. apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: policy-config spec: namespaceSelector: include: ["default"] exclude: [] matchExpressions: [] matchLabels: {} remediationAction: inform 1 customMessage: compliant: {} noncompliant: {} severity: low evaluationInterval: compliant: "" noncompliant: "" object-templates-raw: "" object-templates: 2 - complianceType: musthave metadataComplianceType: recordDiff: "" recreateOption: "" objectSelector: matchLabels: {} matchExpressions: [] objectDefinition: apiVersion: v1 kind: Pod metadata: name: pod spec: containers: - image: pod-image name: pod-name ports: - containerPort: 80 - complianceType: mustonlyhave objectDefinition: apiVersion: v1 kind: ConfigMap metadata: name: myconfig namespace: default data: testData: hello ... 1 Configuration policies that specify an object without a name can only be set to inform . When the remediationAction for the configuration policy is set to enforce , the controller applies the specified configuration to the target managed cluster. 2 A Kubernetes object is defined in the object-templates array in the configuration policy, where fields of the configuration policy controller is compared with objects on the managed cluster. You can also use templated values within configuration policies. For more advanced use cases, specify a string in object-templates-raw to create the object-templates that you want. For more information, see Template processing . 1.1.1.2. Configuration policy YAML table Table 1.1. Parameter table Field Optional or required Description apiVersion Required Set the value to policy.open-cluster-management.io/v1 . kind Required Set the value to ConfigurationPolicy to indicate the type of policy. metadata.name Required The name of the policy. spec.namespaceSelector Required for namespaced objects that do not have a namespace specified Determines namespaces in the managed cluster that the object is applied to. The include and exclude parameters accept file path expressions to include and exclude namespaces by name. The matchExpressions and matchLabels parameters specify namespaces to include by label. See the Kubernetes labels and selectors documentation. The resulting list is compiled by using the intersection of results from all parameters. spec.remediationAction Required Specifies the action to take when the policy is non-compliant. Use the following parameter values: inform , InformOnly , or enforce . spec.customMessage Optional Configure the compliance message sent by the configuration policy based on the current compliance. Each message configuration is a string that can contain Go templates. The .DefaultMessage and .Policy context variables are available for use in the templates. You can access the default message by using the .DefaultMessage parameter. The .Policy context variable contains the current policy object, including its status. For example, you can access the state of each related object by specifying the .Policy.status.relatedObjects[*].object field. If you set a value for the evaluationInterval field other than watch , only the kind, name, and namespace of the related objects are available. [source,yaml] ---- .Policy.status.relatedObjects[*].object ---- If you set an evaluationInterval , only identifiable information is available. spec.customMessage.compliant Optional Configure custom messages for configuration policies that are compliant. Go templates and UTF-8 encoded characters, including emoji and foreign characters, are supported values. spec.customMessage.noncompliant Optional Configure custom messages for configuration policies that are non-compliant. Go templates and UTF-8 encoded characters, including emoji and foreign characters, are supported values. spec.severity Required Specifies the severity when the policy is non-compliant. Use the following parameter values: low , medium , high , or critical . spec.evaluationInterval Optional Specifies the frequency for a policy to be evaluated when it is in a particular compliance state. Use the parameters compliant and noncompliant . The default value for the compliant and noncompliant parameters is watch to leverage Kubernetes API watches instead of polling the Kubernetes API server. When managed clusters have low resources, the evaluation interval can be set to long polling intervals to reduce CPU and memory usage on the Kubernetes API and policy controller. These are in the format of durations. For example, 1h25m3s represents 1 hour, 25 minutes, and 3 seconds. These can also be set to never to avoid evaluating the policy after it is in a particular compliance state. spec.evaluationInterval.compliant Optional Specifies the evaluation frequency for a compliant policy. To enable the polling behavior, set this parameter to 10s . spec.evaluationInterval.noncompliant Optional Specifies the evaluation frequency for a non-compliant policy. To enable the polling behavior, set this parameter to 10s . spec.object-templates Optional The array of Kubernetes objects (either fully defined or containing a subset of fields) for the controller to compare with objects on the managed cluster. Note: While spec.object-templates and spec.object-templates-raw are listed as optional, exactly one of the two parameter fields must be set. spec.object-templates-raw Optional Used to set object templates with a raw YAML string. Specify conditions for the object templates, where advanced functions like if-else statements and the range function are supported values. For example, add the following value to avoid duplication in your object-templates definition: {{- if eq .metadata.name "policy-grc-your-meta-data-name" }} replicas: 2 {{- else }} replicas: 1 {{- end }} Note: While spec.object-templates and spec.object-templates-raw are listed as optional, exactly one of the two parameter fields must be set. spec.object-templates[].complianceType Required Use this parameter to define the desired state of the Kubernetes object on your managed clusters. Use one of the following verbs as the parameter value: mustonlyhave : Indicates that an object must exist with the exact fields and values as defined in the objectDefinition . musthave : Indicates an object must exist with the same fields as specified in the objectDefinition . Any existing fields on the object that are not specified in the object-template are ignored. In general, array values are appended. The exception for the array to be patched is when the item contains a name key with a value that matches an existing item. Use a fully defined objectDefinition using the mustonlyhave compliance type, if you want to replace the array. mustnothave : Indicates that an object with the same fields as specified in the objectDefinition cannot exist. spec.object-templates[].metadataComplianceType Optional Overrides spec.object-templates[].complianceType when comparing the manifest's metadata section to objects on the cluster ("musthave", "mustonlyhave"). Default is unset to not override complianceType for metadata. spec.object-templates[].recordDiff Optional Use this parameter to specify if and where to display the difference between the object on the cluster and the objectDefinition in the policy. The following options are supported: Set to InStatus to store the difference in the ConfigurationPolicy status. Set to Log to log the difference in the controller logs. Set to None to not log the difference. By default, this parameter is set to InStatus if the controller does not detect sensitive data in the difference. Otherwise, the default is None . If sensitive data is detected, the ConfigurationPolicy status displays a message to set recordDiff to view the difference. spec.object-templates[].recreateOption Optional Describes when to delete and recreate an object when an update is required. When you set the object to IfRequired , the policy recreates the object when updating an immutable field. When you set the parameter to Always , the policy recreates the object on any update. When you set the remediationAction to inform , the parameter value, recreateOption , has no effect on the object. The IfRequired value has no effect on clusters without dry-run update support. The default value is None . spec.object-templates[].objectDefinition Required A Kubernetes object (either fully defined or containing a subset of fields) for the controller to compare with objects on the managed cluster. spec.pruneObjectBehavior Optional Determines whether to clean up resources related to the policy when the policy is removed from a managed cluster. 1.1.1.3. Additional resources See the following topics for more information: See Creating configuration policies . See the Hub cluster policy framework for more details on the hub cluster policy. See the policy samples that use NIST Special Publication 800-53 (Rev. 4) , and are supported by Red Hat Advanced Cluster Management from the CM-Configuration-Management folder . For information about dry-run support, see the Kubernetes documentation, Dry-run . Learn about how policies are applied on your hub cluster, see Supported policies for more details. Refer to Policy controllers for more details about controllers. Customize your policy controller configuration. See Policy controller advanced configuration . Learn about cleaning up resources and other topics in the Cleaning up resources that are created by policies documentation. Refer to Policy Generator . Learn about how to create and customize policies, see Governance dashboard . See Template processing . 1.1.2. Certificate policy controller You can use the certificate policy controller to detect certificates that are close to expiring, time durations (hours) that are too long, or contain DNS names that fail to match specified patterns. You can add the certificate policy to the policy-templates field of the policy on the hub cluster, which propagates to the selected managed clusters by using the governance framework. See the Hub cluster policy framework documentation for more details on the hub cluster policy. Configure and customize the certificate policy controller by updating the following parameters in your controller policy: minimumDuration minimumCADuration maximumDuration maximumCADuration allowedSANPattern disallowedSANPattern Your policy might become non-compliant due to either of the following scenarios: When a certificate expires in less than the minimum duration of time or exceeds the maximum time. When DNS names fail to match the specified pattern. The certificate policy controller is created on your managed cluster. The controller communicates with the local Kubernetes API server to get the list of secrets that contain certificates and determine all non-compliant certificates. Certificate policy controller does not support the enforce feature. Note: The certificate policy controller automatically looks for a certificate in a secret in only the tls.crt key. If a secret is stored under a different key, add a label named certificate_key_name with a value set to the key to let the certificate policy controller know to look in a different key. For example, if a secret contains a certificate stored in the key named sensor-cert.pem , add the following label to the secret: certificate_key_name: sensor-cert.pem . 1.1.2.1. Certificate policy controller YAML structure View the following example of a certificate policy and review the element in the YAML table: apiVersion: policy.open-cluster-management.io/v1 kind: CertificatePolicy metadata: name: certificate-policy-example spec: namespaceSelector: include: ["default"] exclude: [] matchExpressions: [] matchLabels: {} labelSelector: myLabelKey: myLabelValue remediationAction: severity: minimumDuration: minimumCADuration: maximumDuration: maximumCADuration: allowedSANPattern: disallowedSANPattern: 1.1.2.1.1. Certificate policy controller YAML table Table 1.2. Parameter table Field Optional or required Description apiVersion Required Set the value to policy.open-cluster-management.io/v1 . kind Required Set the value to CertificatePolicy to indicate the type of policy. metadata.name Required The name to identify the policy. metadata.labels Optional In a certificate policy, the category=system-and-information-integrity label categorizes the policy and facilitates querying the certificate policies. If there is a different value for the category key in your certificate policy, the value is overridden by the certificate controller. spec.namespaceSelector Required Determines namespaces in the managed cluster where secrets are monitored. The include and exclude parameters accept file path expressions to include and exclude namespaces by name. The matchExpressions and matchLabels parameters specify namespaces to be included by label. See the Kubernetes labels and selectors documentation. The resulting list is compiled by using the intersection of results from all parameters. Note: If the namespaceSelector for the certificate policy controller does not match any namespace, the policy is considered compliant. spec.labelSelector Optional Specifies identifying attributes of objects. See the Kubernetes labels and selectors documentation. spec.remediationAction Required Specifies the remediation of your policy. Set the parameter value to inform . Certificate policy controller only supports inform feature. spec.severity Optional Informs the user of the severity when the policy is non-compliant. Use the following parameter values: low , medium , high , or critical . spec.minimumDuration Required When a value is not specified, the default value is 100h . This parameter specifies the smallest duration (in hours) before a certificate is considered non-compliant. The parameter value uses the time duration format from Golang. See Golang Parse Duration for more information. spec.minimumCADuration Optional Set a value to identify signing certificates that might expire soon with a different value from other certificates. If the parameter value is not specified, the CA certificate expiration is the value used for the minimumDuration . See Golang Parse Duration for more information. spec.maximumDuration Optional Set a value to identify certificates that have been created with a duration that exceeds your desired limit. The parameter uses the time duration format from Golang. See Golang Parse Duration for more information. spec.maximumCADuration Optional Set a value to identify signing certificates that have been created with a duration that exceeds your defined limit. The parameter uses the time duration format from Golang. See Golang Parse Duration for more information. spec.allowedSANPattern Optional A regular expression that must match every SAN entry that you have defined in your certificates. This parameter checks DNS names against patterns. See the Golang Regular Expression syntax for more information. spec.disallowedSANPattern Optional A regular expression that must not match any SAN entries you have defined in your certificates. This parameter checks DNS names against patterns. Note: To detect wild-card certificate, use the following SAN pattern: disallowedSANPattern: "[\\*]" See the Golang Regular Expression syntax for more information. 1.1.2.2. Certificate policy sample When your certificate policy controller is created on your hub cluster, a replicated policy is created on your managed cluster. See policy-certificate.yaml to view the certificate policy sample. 1.1.2.3. Additional resources Learn how to manage a certificate policy, see Managing security policies for more details. Refer to Policy controllers introduction for more topics. Return to the Certificates introduction . 1.1.3. Policy set controller The policy set controller aggregates the policy status scoped to policies that are defined in the same namespace. Create a policy set ( PolicySet ) to group policies that are in the same namespace. All policies in the PolicySet are placed together in a selected cluster by creating a PlacementBinding to bind the PolicySet and Placement . The policy set is deployed to the hub cluster. Additionally, when a policy is a part of multiple policy sets, existing and new Placement resources remain in the policy. When a user removes a policy from the policy set, the policy is not applied to the cluster that is selected in the policy set, but the placements remain. The policy set controller only checks for violations in clusters that include the policy set placement. Notes: The Red Hat Advanced Cluster Management sample policy set uses cluster placement. If you use cluster placement, bind the namespace containing the policy to the managed cluster set. See Deploying policies to your cluster for more details on using cluster placement. In order to use a Placement resource, a ManagedClusterSet resource must be bound to the namespace of the Placement resource with a ManagedClusterSetBinding resource. Refer to Creating a ManagedClusterSetBinding resource for additional details. Learn more details about the policy set structure in the following sections: Policy set controller YAML structure Policy set controller YAML table Policy set sample 1.1.3.1. Policy set YAML structure Your policy set might resemble the following YAML file: apiVersion: policy.open-cluster-management.io/v1beta1 kind: PolicySet metadata: name: demo-policyset spec: policies: - policy-demo --- apiVersion: policy.open-cluster-management.io/v1 kind: PlacementBinding metadata: name: demo-policyset-pb placementRef: apiGroup: cluster.open-cluster-management.io kind: Placement name: demo-policyset-pr subjects: - apiGroup: policy.open-cluster-management.io kind: PolicySet name: demo-policyset --- apiVersion: cluster.open-cluster-management.io/v1beta1 kind: Placement metadata: name: demo-policyset-pr spec: predicates: - requiredClusterSelector: labelSelector: matchExpressions: - key: name operator: In values: - local-cluster tolerations: - key: cluster.open-cluster-management.io/unavailable operator: Exists - key: cluster.open-cluster-management.io/unreachable operator: Exists 1.1.3.2. Policy set table View the following parameter table for descriptions: Table 1.3. Parameter table Field Optional or required Description apiVersion Required Set the value to policy.open-cluster-management.io/v1beta1 . kind Required Set the value to PolicySet to indicate the type of policy. metadata.name Required The name for identifying the policy resource. spec Required Add configuration details for your policy. spec.policies Optional The list of policies that you want to group together in the policy set. 1.1.3.3. Policy set sample apiVersion: policy.open-cluster-management.io/v1beta1 kind: PolicySet metadata: name: pci namespace: default spec: description: Policies for PCI compliance policies: - policy-pod - policy-namespace status: compliant: NonCompliant placement: - placementBinding: binding1 placement: placement1 policySet: policyset-ps 1.1.3.4. Additional resources See Red Hat OpenShift Platform Plus policy set . See the Creating policy sets section in the Managing security policies topic. Also view the stable PolicySets , which require the Policy Generator for deployment, PolicySets-- Stable . 1.1.4. Operator policy controller The operator policy controller allows you to monitor and install Operator Lifecycle Manager operators across your clusters. Use the operator policy controller to monitor the health of various pieces of the operator and to specify how you want to automatically handle updates to the operator. You can also distribute an operator policy to managed clusters by using the governance framework and adding the policy to the policy-templates field of a policy on the hub cluster. You can also use template values within the operatorGroup and subscription fields of an operator policy. For more information, see Template processing . 1.1.4.1. Prerequisites Operator Lifecycle Manager must be available on your managed cluster. This is enabled by default on Red Hat OpenShift Container Platform. Required access: Cluster administrator 1.1.4.2. Operator policy YAML table Field Optional or required Description apiVersion Required Set the value to policy.open-cluster-management.io/v1beta1 . kind Required Set the value to OperatorPolicy to indicate the type of policy. metadata.name Required The name for identifying the policy resource. spec.remediationAction Required If the remediationAction for the operator policy is set to enforce , the controller creates resources on the target managed cluster to communicate to OLM to install the operator and approve updates based on the versions specified in the policy. + If the remediationAction set to inform , the controller only reports the status of the operator, including if any upgrades are available. spec.operatorGroup Optional By default, if the operatorGroup field is not specified, the controller generates an AllNamespaces type OperatorGroup in the same namespace as the subscription, if supported. This resource is generated by the operator policy controller. spec.complianceType Required Specifies the desired state of the operator on the cluster. If set to musthave , the policy is compliant when the operator is found. If set to mustnothave , the policy is compliant when the operator is not found. spec.removalBehavior Optional Determines which resource types need to be kept or removed when you enforce an OperatorPolicy resource with complianceType: mustnothave defined. There is no effect when complianceType is set to musthave . - operatorGroups can be set to Keep or DeleteIfUnused . The default value is DeleteIfUnusued which only removes the OperatorGroup resource if it is not used by any other operators. - subscriptions can be set to Keep or Delete . The default value is Delete . - clusterServiceVersions can be set to Keep or Delete . The default value is Delete . - customResourceDefinitions can be set to Keep or Delete . The default value is Keep . If you set this to Delete , the CustomResourceDefintion resources on the managed cluster are removed and can cause data loss. spec.subscription Required Define the configurations to create an operator subscription. Add information in the following fields to create an operator subscription. Default options are selected for a few items if there is no entry: channel : If not specified, the default channel is selected from the operator catalog. The default can be different on different OpenShift Container Platform versions. name : Specify the package name of the operator. namespace : If not specified, the default namespaced that is used for OpenShift Container Platform managed clusters is openshift-operators . source : If not specified, the catalog that contains the operator is chosen. sourceNamespace : If not specified, the namespace of the catalog that contains the operator is chosen. Note: If you define a value for upgradeApproval , your policy becomes non-compliant. spec.complianceConfig Optional Use this parameter to define the compliance behavior for specific scenarios that are associated with operators. You can set each of the following options individually, where the supported values are Compliant and NonCompliant : catalogSourceUnhealthy : Define the compliance when the catalog source for the operator is unhealthy. The default value is Compliant because this only affects possible upgrades. deploymentsUnavailable : Define the compliance when at least one deployment of the operator is not fully available. The default value is NonCompliant because this reflects the availability of the service that the operator provides. upgradesAvailable : Define the compliance when there is an upgrade available for the operator. The default value is Compliant because the existing operator installation might be running correctly. spec.upgradeApproval Required If the upgradeApproval field is set to Automatic , version upgrades on the cluster are approved by the policy when the policy is set to enforce . If you set the field to None , version upgrades to the specific operator are not approved when the policy is set to enforce . spec.versions Optional Declare which versions of the operator are compliant. If the field is empty, any version running on the cluster is considered compliant. If the field is not empty, the version on the managed cluster must match one of the versions in the list for the policy to be compliant. If the policy is set to enforce and the list is not empty, the versions listed here are approved by the controller on the cluster. 1.1.4.3. Additional resources See Template processing . See Installing an operator by using the OperatorPolicy resource for more details. See Managing operator policies in disconnected environments . See the Subscription topic in the OpenShift Container Platform documentation. See Operator Lifecycle Manager (OLM) for more details. See the Adding Operators to a cluster documentation for general information on OLM. 1.2. Template processing Configuration policies and operator policies support the inclusion of Golang text templates. These templates are resolved at runtime either on the hub cluster or the target managed cluster using configurations related to that cluster. This gives you the ability to define policies with dynamic content, and inform or enforce Kubernetes resources that are customized to the target cluster. A policy definition can contain both hub cluster and managed cluster templates. Hub cluster templates are processed first on the hub cluster, then the policy definition with resolved hub cluster templates is propagated to the target clusters. A controller on the managed cluster processes any managed cluster templates in the policy definition and then enforces or verifies the fully resolved object definition. The template must conform to the Golang template language specification, and the resource definition generated from the resolved template must be a valid YAML. See the Golang documentation about Package templates for more information. Any errors in template validation are recognized as policy violations. When you use a custom template function, the values are replaced at runtime. Important: If you use hub cluster templates to propagate secrets or other sensitive data, the sensitive data exists in the managed cluster namespace on the hub cluster and on the managed clusters where that policy is distributed. The template content is expanded in the policy, and policies are not encrypted by the OpenShift Container Platform ETCD encryption support. To address this, use fromSecret or copySecretData , which automatically encrypts the values from the secret, or protect to encrypt other values. When you add multiline string values such as, certificates, always add | toRawJson | toLiteral syntax at the end of the template pipeline to handle line breaks. For example, if you are copying a certificate from a Secret resource and including it in a ConfigMap resource, your template pipeline might be similar to the following syntax: The toRawJson template function converts the input value to a JSON string with new lines escaped to not affect the YAML structure. The toLiteral template function removes the outer single quotes from the output. For example, when templates are processed for the key: '{{ 'hello\nworld' | toRawJson }}' template pipeline, the output is key: '"hello\nworld"' . The output of the key: '{{ 'hello\nworld' | toRawJson | toLiteral }}' template pipeline is key: "hello\nworld" . See the following table for a comparison of hub cluster and managed cluster templates: 1.2.1. Comparison of hub cluster and managed cluster templates Table 1.4. Comparison table Templates Hub cluster Managed cluster Syntax Golang text template specification Golang text template specification Delimiter {{hub ... hub}} {{ ... }} Context A .ManagedClusterName variable is available, which at runtime, resolves to the name of the target cluster where the policy is propagated. The .ManagedClusterLabels variable is also available, which resolves to a map of keys and values of the labels on the managed cluster where the policy is propagated. No context variables Access control By default, you can only reference namespaced Kubernetes resources that are in the same namespace as the Policy object and the ManagedCluster object of the cluster that the policy propogates to. Alternatively, you can specify the spec.hubTemplateOptions.serviceAccountName field in the Policy object to a service account in the same namespace as the Policy resource. When you specify the field, the service account is used for all hub cluster template lookups. Note: The service account must have list and watch permissions on any resource that is looked up in a hub cluster template. You can reference any resource on the cluster. Functions A set of template functions that support dynamic access to Kubernetes resources and string manipulation. See Template functions for more information. See the Access control row for lookup restrictions. The fromSecret template function on the hub cluster stores the resulting value as an encrypted string on the replicated policy, in the managed cluster namespace. The equivalent call might use the following syntax: {{hub "(lookup "v1" "Secret" "default" "my-hub-secret").data.message | protect hub}} A set of template functions support dynamic access to Kubernetes resources and string manipulation. See Template functions for more information. Function output storage The output of template functions are stored in Policy resource objects in each applicable managed cluster namespace on the hub cluster, before it is synced to the managed cluster. This means that any sensitive results from template functions are readable by anyone with read access to the Policy resource objects on the hub cluster, and anyone with read access to the ConfigurationPolicy or OperatorPolicy resource objects on the managed clusters. Additionally, if etcd encryption is enabled, the policy resource objects are not encrypted. It is best to carefully consider this when using template functions that return sensitive output (e.g. from a secret). The output of template functions are not stored in policy related resource objects. Policy metadata The .PolicyMetadata variable resolves to a map with the name , namespace , labels , and annotations keys with values from the root policy. No context variables Processing Processing occurs at runtime on the hub cluster during propagation of replicated policies to clusters. Policies and the hub cluster templates within the policies are processed on the hub cluster only when templates are created or updated. Processing occurs on the managed cluster. Configuration policies are processed periodically, which automatically updates the resolved object definition with data in the referenced resources. Operator policies automatically update whenever a referenced resource changes. Processing errors Errors from the hub cluster templates are displayed as violations on the managed clusters the policy applies to. Errors from the managed cluster templates are displayed as violations on the specific target cluster where the violation occurred. Continue reading the following topics: Template functions Advanced template processing in configuration policies 1.2.2. Template functions Reference Kubernetes resources such as resource-specific and generic template functions on your hub cluster by using the {{hub ... hub}} delimiters, or on your managed cluster by using the {{ ... }} delimiters. You can use resource-specific functions for convenience and to make the content of your resources more accessible. 1.2.2.1. Template function descriptions If you use the generic function, lookup , which is more advanced, familiarize yourself with the YAML structure of the resource that is being looked up. In addition to these functions, utility functions such as base64enc , base64dec , indent , autoindent , toInt , toBool , and more are available. To conform templates with YAML syntax, you must define templates in the policy resource as strings using quotes or a block character ( | or > ). This causes the resolved template value to also be a string. To override this, use toInt or toBool as the final function in the template to initiate further processing that forces the value to be interpreted as an integer or boolean respectively. Continue reading to view the descriptions and examples for some of the custom template functions that are supported: fromSecret fromConfigMap fromClusterClaim lookup base64enc base64dec indent autoindent toInt toBool protect toLiteral copySecretData copyConfigMapData getNodesWithExactRoles hasNodesWithExactRoles Sprig open source 1.2.2.1.1. fromSecret The fromSecret function returns the value of the given data key in the secret. View the following syntax for the function: When you use this function, enter the namespace, name, and data key of a Kubernetes Secret resource. You must use the same namespace that is used for the policy when using the function in a hub cluster template. See Template processing for more details. View the following configuration policy that enforces a Secret resource on the target cluster: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: apiVersion: v1 data: 1 USER_NAME: YWRtaW4= PASSWORD: '{{ fromSecret "default" "localsecret" "PASSWORD" }}' 2 kind: Secret 3 metadata: name: demosecret namespace: test type: Opaque remediationAction: enforce severity: low 1 When you use this function with hub cluster templates, the output is automatically encrypted using the protect function. 2 The value for the PASSWORD data key is a template that references the secret on the target cluster. 3 You receive a policy violation if the Kubernetes Secret resource does not exist on the target cluster. If the data key does not exist on the target cluster, the value becomes an empty string. Important: When you add multiline string values such as, certificates, always add | toRawJson | toLiteral syntax at the end of the template pipeline to handle line breaks. For example, if you are copying a certificate from a Secret resource and including it in a ConfigMap resource, your template pipeline might be similar to the following syntax: The toRawJson template function converts the input value to a JSON string with new lines escaped to not affect the YAML structure. The toLiteral template function removes the outer single quotes from the output. For example, when templates are processed for the key: '{{ 'hello\nworld' | toRawJson }}' template pipeline, the output is key: '"hello\nworld"' . The output of the key: '{{ 'hello\nworld' | toRawJson | toLiteral }}' template pipeline is key: "hello\nworld" . 1.2.2.1.2. fromConfigmap The fromConfigMap function returns the value of the given data key in the config map. When you use this function, enter the namespace, name, and data key of a Kubernetes ConfigMap resource. You must use the same namespace that is used for the policy using the function in a hub cluster template. See Template processing for more details. View the following syntax for the function: View the following configuration policy that enforces a Kubernetes resource on the target managed cluster: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromcm-lookup namespace: test-templates spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: kind: ConfigMap 1 apiVersion: v1 metadata: name: demo-app-config namespace: test data: 2 app-name: sampleApp app-description: "this is a sample app" log-file: '{{ fromConfigMap "default" "logs-config" "log-file" }}' 3 log-level: '{{ fromConfigMap "default" "logs-config" "log-level" }}' 4 remediationAction: enforce severity: low 1 You receive a policy violation if the Kubernetes ConfigMap resource does not exist on the target cluster. 2 If the data key does not exist on the target cluster, the value becomes an empty string. 3 The value for the log-file data key is a template that retrieves the value of the log-file from the logs-config config map in the default namespace. 4 The log-level is a tempalte that retrieves the value of the log-level data key in the default namespace. 1.2.2.1.3. fromClusterClaim The fromClusterClaim function returns the value of the Spec.Value in the ClusterClaim resource. View the following syntax for the function: View the following example of the configuration policy that enforces a Kubernetes resource on the target managed cluster: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-clusterclaims 1 namespace: default spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: sample-app-config namespace: default data: 2 platform: '{{ fromClusterClaim "platform.open-cluster-management.io" }}' 3 product: '{{ fromClusterClaim "product.open-cluster-management.io" }}' version: '{{ fromClusterClaim "version.openshift.io" }}' remediationAction: enforce severity: low 1 When you use this function, enter the name of a Kubernetes ClusterClaim resource. You receive a policy violation if the ClusterClaim resource does not exist. 2 Configuration values can be set as key-value properties. 3 The value for the platform data key is a template that retrieves the value of the platform.open-cluster-management.io cluster claim. Similarly, it retrieves values for product and version from the ClusterClaim resource. 1.2.2.1.4. lookup The lookup function returns the Kubernetes resource as a JSON compatible map. When you use this function, enter the API version, kind, namespace, name, and optional label selectors of the Kubernetes resource. You must use the same namespace that is used for the policy within the hub cluster template. See Template processing for more details. If the requested resource does not exist, an empty map is returned. If the resource does not exist and the value is provided to another template function, you might get the following error: invalid value; expected string . Note: Use the default template function, so the correct type is provided to later template functions. See the Sprig open source section. View the following syntax for the function: For label selector examples, see the reference to the Kubernetes labels and selectors documentation, in the Additional resources section. View the following example of the configuration policy that enforces a Kubernetes resource on the target managed cluster: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-lookup namespace: test-templates spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: demo-app-config namespace: test data: 1 app-name: sampleApp app-description: "this is a sample app" metrics-url: | 2 http://{{ (lookup "v1" "Service" "default" "metrics").spec.clusterIP }}:8080 remediationAction: enforce severity: low 1 Configuration values can be set as key-value properties. 2 The value for the metrics-url data key is a template that retrieves the v1/Service Kubernetes resource metrics from the default namespace, and is set to the value of the Spec.ClusterIP in the queried resource. 1.2.2.1.5. base64enc The base64enc function returns a base64 encoded value of the input data string . When you use this function, enter a string value. View the following syntax for the function: View the following example of the configuration policy that uses the base64enc function: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... data: USER_NAME: '{{ fromConfigMap "default" "myconfigmap" "admin-user" | base64enc }}' 1.2.2.1.6. base64dec The base64dec function returns a base64 decoded value of the input enc-data string . When you use this function, enter a string value. View the following syntax for the function: View the following example of the configuration policy that uses the base64dec function: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... data: app-name: | "{{ ( lookup "v1" "Secret" "testns" "mytestsecret") .data.appname ) | base64dec }}" 1.2.2.1.7. indent The indent function returns the padded data string . When you use this function, enter a data string with the specific number of spaces. View the following syntax for the function: View the following example of the configuration policy that uses the indent function: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... data: Ca-cert: | {{ ( index ( lookup "v1" "Secret" "default" "mycert-tls" ).data "ca.pem" ) | base64dec | indent 4 }} 1.2.2.1.8. autoindent The autoindent function acts like the indent function that automatically determines the number of leading spaces based on the number of spaces before the template. View the following example of the configuration policy that uses the autoindent function: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... data: Ca-cert: | {{ ( index ( lookup "v1" "Secret" "default" "mycert-tls" ).data "ca.pem" ) | base64dec | autoindent }} 1.2.2.1.9. toInt The toInt function casts and returns the integer value of the input value. When this is the last function in the template, there is further processing of the source content. This is to ensure that the value is interpreted as an integer by the YAML. When you use this function, enter the data that needs to be casted as an integer. View the following syntax for the function: View the following example of the configuration policy that uses the toInt function: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-template-function namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... spec: vlanid: | {{ (fromConfigMap "site-config" "site1" "vlan") | toInt }} 1.2.2.1.10. toBool The toBool function converts the input string into a boolean, and returns the boolean. When this is the last function in the template, there is further processing of the source content. This is to ensure that the value is interpreted as a boolean by the YAML. When you use this function, enter the string data that needs to be converted to a boolean. View the following syntax for the function: View the following example of the configuration policy that uses the toBool function: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-template-function namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... spec: enabled: | {{ (fromConfigMap "site-config" "site1" "enabled") | toBool }} 1.2.2.1.11. protect The protect function enables you to encrypt a string in a hub cluster policy template. It is automatically decrypted on the managed cluster when the policy is evaluated. View the following example of the configuration policy that uses the protect function: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-template-function namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... spec: enabled: | {{hub (lookup "v1" "Secret" "default" "my-hub-secret").data.message | protect hub}} In the YAML example, there is an existing hub cluster policy template that is defined to use the lookup function. On the replicated policy in the managed cluster namespace, the value might resemble the following syntax: USDocm_encrypted:okrrBqt72oI+3WT/0vxeI3vGa+wpLD7Z0ZxFMLvL204= Each encryption algorithm used is AES-CBC using 256-bit keys. Each encryption key is unique per managed cluster and is automatically rotated every 30 days. This ensures that your decrypted value is to never be stored in the policy on the managed cluster. To force an immediate rotation, delete the policy.open-cluster-management.io/last-rotated annotation on the policy-encryption-key Secret in the managed cluster namespace on the hub cluster. Policies are then reprocessed to use the new encryption key. 1.2.2.1.12. toLiteral The toLiteral function removes any quotation marks around the template string after it is processed. You can use this function to convert a JSON string from a config map field to a JSON value in the manifest. Run the following function to remove quotation marks from the key parameter value: After using the toLiteral function, the following update is displayed: 1.2.2.1.13. copySecretData The copySecretData function copies all of the data contents of the specified secret. View the following sample of the function: complianceType: musthave objectDefinition: apiVersion: v1 kind: Secret metadata: name: my-secret-copy data: '{{ copySecretData "default" "my-secret" }}' 1 1 When you use this function with hub cluster templates, the output is automatically encrypted using the protect function. 1.2.2.1.14. copyConfigMapData The copyConfigMapData function copies all of the data content of the specified config map. View the following sample of the function: complianceType: musthave objectDefinition: apiVersion: v1 kind: ConfigMap metadata: name: my-secret-copy data: '{{ copyConfigMapData "default" "my-configmap" }}' 1.2.2.1.15. getNodesWithExactRoles The getNodesWithExactRoles function returns a list of nodes with only the roles that you specify, and ignores nodes that have any additional roles except the node-role.kubernetes.io/worker role. View the following sample function where you are selecting "infra" nodes and ignoring the storage nodes: complianceType: musthave objectDefinition: apiVersion: v1 kind: ConfigMap metadata: name: my-configmap data: infraNode: | {{- range USDi,USDnd := (getNodesWithExactRoles "infra").items }} node{{ USDi }}: {{ USDnd.metadata.name }} {{- end }} replicas: {{ len ((getNodesWithExactRoles "infra").items) | toInt }} 1.2.2.1.16. hasNodesWithExactRoles The hasNodesWithExactRoles function returns the true value if the cluster contains nodes with only the roles that you specify, and ignores nodes that have any additional roles except the node-role.kubernetes.io/worker role. View the following sample of the function: complianceType: musthave objectDefinition: apiVersion: v1 kind: ConfigMap metadata: name: my-configmap data: key: '{{ hasNodesWithExactRoles "infra" }}' 1.2.2.1.17. Sprig open source Red Hat Advanced Cluster Management supports the following template functions that are included from the sprig open source project: Table 1.5. Table of supported, community Sprig functions Sprig library Functions Cryptographic and security htpasswd Date date , mustToDate , now , toDate Default default , empty , fromJson , mustFromJson , ternary , toJson , toRawJson Dictionaries and dict dict , dig , get , hasKey , merge , mustMerge , set , unset Integer math add , mul , div , round , sub Integer slice until , untilStep , Lists append , concat , has , list , mustAppend , mustHas , mustPrepend , mustSlice , prepend , slice String functions cat , contains , hasPrefix , hasSuffix , join , lower , mustRegexFind , mustRegexFindAll , mustRegexMatch , quote , regexFind , regexFindAll , regexMatch , regexQuoteMeta , replace , split , splitn , substr , trim , trimAll , trunc , upper Version comparison semver , semverCompare 1.2.2.2. Additional resources See Template processing for more details. See Advanced template processing in configuration policies for use-cases. For label selector examples, see the Kubernetes labels and selectors documentation. Refer to the Golang documentation - Package templates . See the Sprig Function Documentation for more details. 1.2.3. Advanced template processing in configuration policies Use both managed cluster and hub cluster templates to reduce the need to create separate policies for each target cluster or hardcode configuration values in the policy definitions. For security, both resource-specific and the generic lookup functions in hub cluster templates are restricted to the namespace of the policy on the hub cluster. Important: If you use hub cluster templates to propagate secrets or other sensitive data, that causes sensitive data exposure in the managed cluster namespace on the hub cluster and on the managed clusters where that policy is distributed. The template content is expanded in the policy, and policies are not encrypted by the OpenShift Container Platform ETCD encryption support. To address this, use fromSecret or copySecretData , which automatically encrypts the values from the secret, or protect to encrypt other values. Continue reading for advanced template use-cases: Special annotation for reprocessing Object template processing Bypass template processing 1.2.3.1. Special annotation for reprocessing Hub cluster templates are resolved to the data in the referenced resources during policy creation, or when the referenced resources are updated. If you need to manually initiate an update, use the special annotation, policy.open-cluster-management.io/trigger-update , to indicate changes for the data referenced by the templates. Any change to the special annotation value automatically initiates template processing. Additionally, the latest contents of the referenced resource are read and updated in the policy definition that is propagated for processing on managed clusters. A way to use this annotation is to increment the value by one each time. 1.2.3.2. Object template processing Set object templates with a YAML string representation. The object-template-raw parameter is an optional parameter that supports advanced templating use-cases, such as if-else and the range function. The following example is defined to add the species-category: mammal label to any ConfigMap in the default namespace that has a name key equal to Sea Otter : object-templates-raw: | {{- range (lookup "v1" "ConfigMap" "default" "").items }} {{- if eq .data.name "Sea Otter" }} - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: {{ .metadata.name }} namespace: {{ .metadata.namespace }} labels: species-category: mammal {{- end }} {{- end }} Note: While spec.object-templates and spec.object-templates-raw are optional, exactly one of the two parameter fields must be set. View the following policy example that uses advanced templates to create and configure infrastructure MachineSet objects for your managed clusters. apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: create-infra-machineset spec: remediationAction: enforce severity: low object-templates-raw: | {{- /* Specify the parameters needed to create the MachineSet */ -}} {{- USDmachineset_role := "infra" }} {{- USDregion := "ap-southeast-1" }} {{- USDzones := list "ap-southeast-1a" "ap-southeast-1b" "ap-southeast-1c" }} {{- USDinfrastructure_id := (lookup "config.openshift.io/v1" "Infrastructure" "" "cluster").status.infrastructureName }} {{- USDworker_ms := (index (lookup "machine.openshift.io/v1beta1" "MachineSet" "openshift-machine-api" "").items 0) }} {{- /* Generate the MachineSet for each zone as specified */ -}} {{- range USDzone := USDzones }} - complianceType: musthave objectDefinition: apiVersion: machine.openshift.io/v1beta1 kind: MachineSet metadata: labels: machine.openshift.io/cluster-api-cluster: {{ USDinfrastructure_id }} name: {{ USDinfrastructure_id }}-{{ USDmachineset_role }}-{{ USDzone }} namespace: openshift-machine-api spec: replicas: 1 selector: matchLabels: machine.openshift.io/cluster-api-cluster: {{ USDinfrastructure_id }} machine.openshift.io/cluster-api-machineset: {{ USDinfrastructure_id }}-{{ USDmachineset_role }}-{{ USDzone }} template: metadata: labels: machine.openshift.io/cluster-api-cluster: {{ USDinfrastructure_id }} machine.openshift.io/cluster-api-machine-role: {{ USDmachineset_role }} machine.openshift.io/cluster-api-machine-type: {{ USDmachineset_role }} machine.openshift.io/cluster-api-machineset: {{ USDinfrastructure_id }}-{{ USDmachineset_role }}-{{ USDzone }} spec: metadata: labels: node-role.kubernetes.io/{{ USDmachineset_role }}: "" taints: - key: node-role.kubernetes.io/{{ USDmachineset_role }} effect: NoSchedule providerSpec: value: ami: id: {{ USDworker_ms.spec.template.spec.providerSpec.value.ami.id }} apiVersion: awsproviderconfig.openshift.io/v1beta1 blockDevices: - ebs: encrypted: true iops: 2000 kmsKey: arn: '' volumeSize: 500 volumeType: io1 credentialsSecret: name: aws-cloud-credentials deviceIndex: 0 instanceType: {{ USDworker_ms.spec.template.spec.providerSpec.value.instanceType }} iamInstanceProfile: id: {{ USDinfrastructure_id }}-worker-profile kind: AWSMachineProviderConfig placement: availabilityZone: {{ USDzone }} region: {{ USDregion }} securityGroups: - filters: - name: tag:Name values: - {{ USDinfrastructure_id }}-worker-sg subnet: filters: - name: tag:Name values: - {{ USDinfrastructure_id }}-private-{{ USDzone }} tags: - name: kubernetes.io/cluster/{{ USDinfrastructure_id }} value: owned userDataSecret: name: worker-user-data {{- end }} 1.2.3.3. Bypass template processing You might create a policy that contains a template that is not intended to be processed by Red Hat Advanced Cluster Management. By default, Red Hat Advanced Cluster Management processes all templates. To bypass template processing for your hub cluster, you must change {{ template content }} to {{ `{{ template content }}` }} . Alternatively, you can add the following annotation in the ConfigurationPolicy section of your Policy : policy.open-cluster-management.io/disable-templates: "true" . When this annotation is included, the workaround is not necessary. Template processing is bypassed for the ConfigurationPolicy . 1.2.3.4. Additional resources See Template functions for more details. Return to Template processing . See Kubernetes configuration policy controller for more details. Also refer to the Backing up etcd data .

Commands:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: policy-config spec: namespaceSelector: include: ["default"] exclude: [] matchExpressions: [] matchLabels: {} remediationAction: inform 1 customMessage: compliant: {} noncompliant: {} severity: low evaluationInterval: compliant: "" noncompliant: "" object-templates-raw: "" object-templates: 2 - complianceType: musthave metadataComplianceType: recordDiff: "" recreateOption: "" objectSelector: matchLabels: {} matchExpressions: [] objectDefinition: apiVersion: v1 kind: Pod metadata: name: pod spec: containers: - image: pod-image name: pod-name ports: - containerPort: 80 - complianceType: mustonlyhave objectDefinition: apiVersion: v1 kind: ConfigMap metadata: name: myconfig namespace: default data: testData: hello
{{- if eq .metadata.name "policy-grc-your-meta-data-name" }} replicas: 2 {{- else }} replicas: 1 {{- end }}
apiVersion: policy.open-cluster-management.io/v1 kind: CertificatePolicy metadata: name: certificate-policy-example spec: namespaceSelector: include: ["default"] exclude: [] matchExpressions: [] matchLabels: {} labelSelector: myLabelKey: myLabelValue remediationAction: severity: minimumDuration: minimumCADuration: maximumDuration: maximumCADuration: allowedSANPattern: disallowedSANPattern:
apiVersion: policy.open-cluster-management.io/v1beta1 kind: PolicySet metadata: name: demo-policyset spec: policies: - policy-demo --- apiVersion: policy.open-cluster-management.io/v1 kind: PlacementBinding metadata: name: demo-policyset-pb placementRef: apiGroup: cluster.open-cluster-management.io kind: Placement name: demo-policyset-pr subjects: - apiGroup: policy.open-cluster-management.io kind: PolicySet name: demo-policyset --- apiVersion: cluster.open-cluster-management.io/v1beta1 kind: Placement metadata: name: demo-policyset-pr spec: predicates: - requiredClusterSelector: labelSelector: matchExpressions: - key: name operator: In values: - local-cluster tolerations: - key: cluster.open-cluster-management.io/unavailable operator: Exists - key: cluster.open-cluster-management.io/unreachable operator: Exists
apiVersion: policy.open-cluster-management.io/v1beta1 kind: PolicySet metadata: name: pci namespace: default spec: description: Policies for PCI compliance policies: - policy-pod - policy-namespace status: compliant: NonCompliant placement: - placementBinding: binding1 placement: placement1 policySet: policyset-ps
ca.crt: '{{ fromSecret "openshift-config" "ca-config-map-secret" "ca.crt" | base64dec | toRawJson | toLiteral }}'
func fromSecret (ns string, secretName string, datakey string) (dataValue string, err error)
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: apiVersion: v1 data: 1 USER_NAME: YWRtaW4= PASSWORD: '{{ fromSecret "default" "localsecret" "PASSWORD" }}' 2 kind: Secret 3 metadata: name: demosecret namespace: test type: Opaque remediationAction: enforce severity: low
ca.crt: '{{ fromSecret "openshift-config" "ca-config-map-secret" "ca.crt" | base64dec | toRawJson | toLiteral }}'
func fromConfigMap (ns string, configmapName string, datakey string) (dataValue string, err Error)
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromcm-lookup namespace: test-templates spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: kind: ConfigMap 1 apiVersion: v1 metadata: name: demo-app-config namespace: test data: 2 app-name: sampleApp app-description: "this is a sample app" log-file: '{{ fromConfigMap "default" "logs-config" "log-file" }}' 3 log-level: '{{ fromConfigMap "default" "logs-config" "log-level" }}' 4 remediationAction: enforce severity: low
func fromClusterClaim (clusterclaimName string) (dataValue string, err Error)
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-clusterclaims 1 namespace: default spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: sample-app-config namespace: default data: 2 platform: '{{ fromClusterClaim "platform.open-cluster-management.io" }}' 3 product: '{{ fromClusterClaim "product.open-cluster-management.io" }}' version: '{{ fromClusterClaim "version.openshift.io" }}' remediationAction: enforce severity: low
func lookup (apiversion string, kind string, namespace string, name string, labelselector ...string) (value string, err Error)
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-lookup namespace: test-templates spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: demo-app-config namespace: test data: 1 app-name: sampleApp app-description: "this is a sample app" metrics-url: | 2 http://{{ (lookup "v1" "Service" "default" "metrics").spec.clusterIP }}:8080 remediationAction: enforce severity: low
func base64enc (data string) (enc-data string)
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: data: USER_NAME: '{{ fromConfigMap "default" "myconfigmap" "admin-user" | base64enc }}'
func base64dec (enc-data string) (data string)
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: data: app-name: | "{{ ( lookup "v1" "Secret" "testns" "mytestsecret") .data.appname ) | base64dec }}"
func indent (spaces int, data string) (padded-data string)
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: data: Ca-cert: | {{ ( index ( lookup "v1" "Secret" "default" "mycert-tls" ).data "ca.pem" ) | base64dec | indent 4 }}
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: data: Ca-cert: | {{ ( index ( lookup "v1" "Secret" "default" "mycert-tls" ).data "ca.pem" ) | base64dec | autoindent }}
func toInt (input interface{}) (output int)
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-template-function namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: spec: vlanid: | {{ (fromConfigMap "site-config" "site1" "vlan") | toInt }}
func toBool (input string) (output bool)
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-template-function namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: spec: enabled: | {{ (fromConfigMap "site-config" "site1" "enabled") | toBool }}
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-template-function namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: spec: enabled: | {{hub (lookup "v1" "Secret" "default" "my-hub-secret").data.message | protect hub}}
key: '{{ "[\"10.10.10.10\", \"1.1.1.1\"]" | toLiteral }}'
key: ["10.10.10.10", "1.1.1.1"]
complianceType: musthave objectDefinition: apiVersion: v1 kind: Secret metadata: name: my-secret-copy data: '{{ copySecretData "default" "my-secret" }}' 1
complianceType: musthave objectDefinition: apiVersion: v1 kind: ConfigMap metadata: name: my-secret-copy data: '{{ copyConfigMapData "default" "my-configmap" }}'
complianceType: musthave objectDefinition: apiVersion: v1 kind: ConfigMap metadata: name: my-configmap data: infraNode: | {{- range USDi,USDnd := (getNodesWithExactRoles "infra").items }} node{{ USDi }}: {{ USDnd.metadata.name }} {{- end }} replicas: {{ len ((getNodesWithExactRoles "infra").items) | toInt }}
complianceType: musthave objectDefinition: apiVersion: v1 kind: ConfigMap metadata: name: my-configmap data: key: '{{ hasNodesWithExactRoles "infra" }}'
object-templates-raw: | {{- range (lookup "v1" "ConfigMap" "default" "").items }} {{- if eq .data.name "Sea Otter" }} - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: {{ .metadata.name }} namespace: {{ .metadata.namespace }} labels: species-category: mammal {{- end }} {{- end }}
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: create-infra-machineset spec: remediationAction: enforce severity: low object-templates-raw: | {{- /* Specify the parameters needed to create the MachineSet */ -}} {{- USDmachineset_role := "infra" }} {{- USDregion := "ap-southeast-1" }} {{- USDzones := list "ap-southeast-1a" "ap-southeast-1b" "ap-southeast-1c" }} {{- USDinfrastructure_id := (lookup "config.openshift.io/v1" "Infrastructure" "" "cluster").status.infrastructureName }} {{- USDworker_ms := (index (lookup "machine.openshift.io/v1beta1" "MachineSet" "openshift-machine-api" "").items 0) }} {{- /* Generate the MachineSet for each zone as specified */ -}} {{- range USDzone := USDzones }} - complianceType: musthave objectDefinition: apiVersion: machine.openshift.io/v1beta1 kind: MachineSet metadata: labels: machine.openshift.io/cluster-api-cluster: {{ USDinfrastructure_id }} name: {{ USDinfrastructure_id }}-{{ USDmachineset_role }}-{{ USDzone }} namespace: openshift-machine-api spec: replicas: 1 selector: matchLabels: machine.openshift.io/cluster-api-cluster: {{ USDinfrastructure_id }} machine.openshift.io/cluster-api-machineset: {{ USDinfrastructure_id }}-{{ USDmachineset_role }}-{{ USDzone }} template: metadata: labels: machine.openshift.io/cluster-api-cluster: {{ USDinfrastructure_id }} machine.openshift.io/cluster-api-machine-role: {{ USDmachineset_role }} machine.openshift.io/cluster-api-machine-type: {{ USDmachineset_role }} machine.openshift.io/cluster-api-machineset: {{ USDinfrastructure_id }}-{{ USDmachineset_role }}-{{ USDzone }} spec: metadata: labels: node-role.kubernetes.io/{{ USDmachineset_role }}: "" taints: - key: node-role.kubernetes.io/{{ USDmachineset_role }} effect: NoSchedule providerSpec: value: ami: id: {{ USDworker_ms.spec.template.spec.providerSpec.value.ami.id }} apiVersion: awsproviderconfig.openshift.io/v1beta1 blockDevices: - ebs: encrypted: true iops: 2000 kmsKey: arn: '' volumeSize: 500 volumeType: io1 credentialsSecret: name: aws-cloud-credentials deviceIndex: 0 instanceType: {{ USDworker_ms.spec.template.spec.providerSpec.value.instanceType }} iamInstanceProfile: id: {{ USDinfrastructure_id }}-worker-profile kind: AWSMachineProviderConfig placement: availabilityZone: {{ USDzone }} region: {{ USDregion }} securityGroups: - filters: - name: tag:Name values: - {{ USDinfrastructure_id }}-worker-sg subnet: filters: - name: tag:Name values: - {{ USDinfrastructure_id }}-private-{{ USDzone }} tags: - name: kubernetes.io/cluster/{{ USDinfrastructure_id }} value: owned userDataSecret: name: worker-user-data {{- end }}