Documentation ¶
Index ¶
- Constants
- Variables
- func HasTemplate(template []byte, startDelim string, checkForEncrypted bool) bool
- func UsesEncryption(template []byte, startDelim string, stopDelim string) bool
- type ClusterScopedLookupRestrictedError
- type ClusterScopedObjectIdentifier
- type Config
- type EncryptionConfig
- type TemplateResolver
- type TemplateResult
Examples ¶
Constants ¶
const (
IVSize = 16 // Size in bytes
)
Variables ¶
var ( ErrAESKeyNotSet = errors.New("AESKey must be set to use this encryption mode") ErrInvalidAESKey = errors.New("the AES key is invalid") ErrInvalidB64OfEncrypted = errors.New("the encrypted string is invalid base64") ErrIVNotSet = errors.New("initialization vector must be set to use this encryption mode") ErrInvalidIV = errors.New("initialization vector must be 128 bits") ErrInvalidPKCS7Padding = errors.New("invalid PCKS7 padding") ErrMissingAPIResource = errors.New("one or more API resources are not installed on the API server") ErrMissingAPIResourceInvalidTemplate = errors.New( "one or more API resources are not installed on the API server which could have led to the templating error", ) ErrProtectNotEnabled = errors.New("the protect template function is not enabled in this mode") ErrNewLinesNotAllowed = errors.New("new lines are not allowed in the string passed to the toLiteral function") ErrInvalidContextType = errors.New( "the input context must be a struct, with either string fields or map[string]string fields", ) )
Functions ¶
func HasTemplate ¶
HasTemplate performs a simple check for the template start delimiter or the "$ocm_encrypted" prefix (checkForEncrypted must be set to true) to indicate if the input byte slice has a template. If the startDelim argument is an empty string, the default start delimiter of "{{" will be used.
Types ¶
type ClusterScopedLookupRestrictedError ¶ added in v3.3.0
type ClusterScopedLookupRestrictedError struct {
// contains filtered or unexported fields
}
func (ClusterScopedLookupRestrictedError) Error ¶ added in v3.3.0
func (e ClusterScopedLookupRestrictedError) Error() string
type ClusterScopedObjectIdentifier ¶ added in v3.3.0
type Config ¶
type Config struct { AdditionalIndentation uint DisabledFunctions []string EncryptionConfig KubeAPIResourceList []*metav1.APIResourceList LookupNamespace string ClusterScopedAllowList []ClusterScopedObjectIdentifier StartDelim string StopDelim string InputIsYAML bool }
Config is a struct containing configuration for the API. Some are required.
- AdditionalIndentation sets the number of additional spaces to be added to the input number to the indent method. This is useful in situations when the indentation should be relative to a logical starting point in a YAML file.
- DisabledFunctions is a slice of default template function names that should be disabled. - KubeAPIResourceList sets the cache for the Kubernetes API resources. If this is set, template processing will not try to rediscover the Kubernetes API resources needed for dynamic client/ GVK lookups.
- EncryptionConfig is the configuration for template encryption/decryption functionality.
- InitializationVector is the initialization vector (IV) used in the AES-CBC encryption/decryption. Note that it must be equal to the AES block size which is always 128 bits (16 bytes). This value must be random but does not need to be private. Its purpose is to make the same plaintext value, when encrypted with the same AES key, appear unique. When performing decryption, the IV must be the same as it was for the encryption of the data. Note that all values encrypted in the template will use this same IV, which means that duplicate plaintext values that are encrypted will yield the same encrypted value in the template.
- LookupNamespace is the namespace to restrict "lookup" template functions (e.g. fromConfigMap) to. If this is not set (i.e. an empty string), then all namespaces can be used.
- ClusterScopedAllowList is a list of cluster-scoped object identifiers (group, kind, name) which are allowed to be used in "lookup" calls even when LookupNamespace is set. A wildcard value `*` may be used in any or all of the fields. The default behavior when LookupNamespace is set is to deny all cluster-scoped lookups.
- StartDelim customizes the start delimiter used to distinguish a template action. This defaults to "{{". If StopDelim is set, this must also be set.
- StopDelim customizes the stop delimiter used to distinguish a template action. This defaults to "}}". If StartDelim is set, this must also be set.
- InputIsYAML can be set to true to indicate that the input to the template is already in YAML format and thus does not need to be converted from JSON to YAML before template processing occurs. This should be set to true when passing raw YAML directly to the template resolver.
type EncryptionConfig ¶
type EncryptionConfig struct { AESKey []byte AESKeyFallback []byte DecryptionConcurrency uint8 DecryptionEnabled bool EncryptionEnabled bool InitializationVector []byte }
EncryptionConfig is a struct containing configuration for template encryption/decryption functionality.
- AESKey is an AES key (e.g. AES-256) to use for the "protect" template function and decrypting such values.
- AESKeyFallback is an AES key to try if the decryption fails using AESKey.
- DecryptionConcurrency is the concurrency (i.e. number of Goroutines) limit when decrypting encrypted strings. Not setting this value is the equivalent of setting this to 1, which means no concurrency.
- DecryptionEnabled enables automatic decrypting of encrypted strings. AESKey and InitializationVector must also be set if this is enabled.
- EncryptionEnabled enables the "protect" template function and "fromSecret" returns encrypted content. AESKey and InitializationVector must also be set if this is enabled.
- InitializationVector is the initialization vector (IV) used in the AES-CBC encryption/decryption. Note that it must be equal to the AES block size which is always 128 bits (16 bytes). This value must be random but does not need to be private. Its purpose is to make the same plaintext value, when encrypted with the same AES key, appear unique. When performing decryption, the IV must be the same as it was for the encryption of the data. Note that all values encrypted in the template will use this same IV, which means that duplicate plaintext values that are encrypted will yield the same encrypted value in the template.
type TemplateResolver ¶
type TemplateResolver struct {
// contains filtered or unexported fields
}
TemplateResolver is the API for processing templates. It's better to use the NewResolver function instead of instantiating this directly so that configuration defaults and validation are applied.
func NewResolver ¶
func NewResolver(kubeClient *kubernetes.Interface, kubeConfig *rest.Config, config Config) (*TemplateResolver, error)
NewResolver creates a new TemplateResolver instance, which is the API for processing templates.
- kubeClient is the Kubernetes client to be used for the template lookup functions.
- config is the Config instance for configuration for template processing.
func (*TemplateResolver) ResolveTemplate ¶
func (t *TemplateResolver) ResolveTemplate(tmplRaw []byte, context interface{}) (TemplateResult, error)
ResolveTemplate accepts a map marshaled as JSON or YAML. It also accepts a struct with string fields that will be made available when the template is processed. For example, if the argument is `struct{ClusterName string}{"cluster1"}`, the value `cluster1` would be available with `{{ .ClusterName }}`. This can also be `nil` if no fields should be made available.
ResolveTemplate will process any template strings in the map and return the processed map. The ErrMissingAPIResource is returned when one or more "lookup" calls referenced an API resource which isn't installed on the Kubernetes API server. In this case, the resolved template is still returned. ErrMissingAPIResourceInvalidTemplate can also be returned in this case but it also means the template failed to resolve, so the resolved template will not be returned.
Example ¶
policyYAML := ` --- apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-sampleapp-config namespace: sampleapp spec: remediationAction: enforce namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: demo-sampleapp-config namespace: test data: message: '{{ "VGVtcGxhdGVzIHJvY2sh" | base64dec }}' b64-cluster-name: '{{ .ClusterName | base64enc }}' severity: high ` policyJSON, err := yamlToJSON([]byte(policyYAML)) if err != nil { fmt.Fprintf(os.Stderr, "Failed to convert the policy YAML to JSON: %v\n", err) panic(err) } resolver, err := NewResolver(&k8sClient, k8sConfig, Config{}) if err != nil { fmt.Fprintf(os.Stderr, "Failed to instantiate the templatesResolver struct: %v\n", err) panic(err) } templateContext := struct{ ClusterName string }{ClusterName: "cluster0001"} tmplResult, err := resolver.ResolveTemplate(policyJSON, templateContext) policyResolvedJSON := tmplResult.ResolvedJSON if err != nil { fmt.Fprintf(os.Stderr, "Failed to process the policy YAML: %v\n", err) panic(err) } var policyResolved interface{} err = yaml.Unmarshal(policyResolvedJSON, &policyResolved) objTmpls := policyResolved.(map[string]interface{})["spec"].(map[string]interface{})["object-templates"] objDef := objTmpls.([]interface{})[0].(map[string]interface{})["objectDefinition"] data, ok := objDef.(map[string]interface{})["data"].(map[string]interface{}) if !ok { fmt.Fprintf(os.Stderr, "Failed to process the policy YAML: %v\n", err) panic(err) } message, ok := data["message"].(string) if !ok { fmt.Fprintf(os.Stderr, "Failed to process the policy YAML: %v\n", err) panic(err) } b64ClusterName, ok := data["b64-cluster-name"].(string) if !ok { fmt.Fprintf(os.Stderr, "Failed to process the policy YAML: %v\n", err) panic(err) } fmt.Println(message) fmt.Println(b64ClusterName)
Output: Templates rock! Y2x1c3RlcjAwMDE=
func (*TemplateResolver) SetEncryptionConfig ¶
func (t *TemplateResolver) SetEncryptionConfig(encryptionConfig EncryptionConfig) error
SetEncryptionConfig accepts an EncryptionConfig struct and validates it to ensure that if encryption and/or decryption are enabled that the AES Key and Initialization Vector are valid. If validation passes, SetEncryptionConfig updates the EncryptionConfig in the TemplateResolver configuration. Otherwise, an error is returned and the configuration is unchanged.
func (*TemplateResolver) SetKubeAPIResourceList ¶
func (t *TemplateResolver) SetKubeAPIResourceList(resourceList []*metav1.APIResourceList)
SetKubeAPIResourceList overrides the KubeAPIResourceList value on the TemplateResolver configuration.
type TemplateResult ¶
type TemplateResult struct { ResolvedJSON []byte ReferencedObjects []client.ObjectIdentifier }