Skip to content

Commit 3a75e9f

Browse files
committed
Enable plugin to be run as a transformer
Signed-off-by: Justin Kulikauskas <[email protected]>
1 parent 51d7b6c commit 3a75e9f

File tree

6 files changed

+168
-10
lines changed

6 files changed

+168
-10
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ For more about Open Cluster Management and its Policy Framework:
5555
**NOTE:** This will default to placing the binary in `${HOME}/.config/kustomize/plugin/`. You can
5656
change this by exporting `KUSTOMIZE_PLUGIN_HOME` to a different path.
5757

58-
#### Configuration
58+
#### Configuration and use as a Generator
5959

6060
1. Create a `kustomization.yaml` file that points to `PolicyGenerator` manifest(s), with any
6161
additional desired patches or customizations (see
@@ -80,6 +80,14 @@ For more about Open Cluster Management and its Policy Framework:
8080
kustomize build --enable-alpha-plugins
8181
```
8282

83+
#### Configuration and use as a Transformer
84+
85+
The plugin can also be used as a transformer, to wrap all incoming `resources` from a
86+
`kustomization.yaml` file into one Policy. This feature is somewhat experimental.
87+
88+
An example configuration as a transformer (and its output) can be found in the
89+
[`examples/generator/`](./examples/generator/) folder.
90+
8391
### As a standalone binary
8492

8593
In order to bypass Kustomize and run the generator binary directly:
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
resources:
2+
- github.com/redhat-cop/gitops-catalog/advanced-cluster-management/operator/overlays/release-2.5?ref=main
3+
transformers:
4+
- ./policyTransformer.yaml

examples/transformer/output.yaml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
apiVersion: apps.open-cluster-management.io/v1
2+
kind: PlacementRule
3+
metadata:
4+
name: placement-transformed-policy
5+
namespace: default
6+
spec:
7+
clusterSelector:
8+
matchExpressions: []
9+
---
10+
apiVersion: policy.open-cluster-management.io/v1
11+
kind: PlacementBinding
12+
metadata:
13+
name: binding-transformed-policy
14+
namespace: default
15+
placementRef:
16+
apiGroup: apps.open-cluster-management.io
17+
kind: PlacementRule
18+
name: placement-transformed-policy
19+
subjects:
20+
- apiGroup: policy.open-cluster-management.io
21+
kind: Policy
22+
name: transformed-policy
23+
---
24+
apiVersion: policy.open-cluster-management.io/v1
25+
kind: Policy
26+
metadata:
27+
annotations:
28+
policy.open-cluster-management.io/categories: CM Configuration Management
29+
policy.open-cluster-management.io/controls: CM-2 Baseline Configuration
30+
policy.open-cluster-management.io/standards: NIST SP 800-53
31+
name: transformed-policy
32+
namespace: default
33+
spec:
34+
disabled: false
35+
policy-templates:
36+
- objectDefinition:
37+
apiVersion: policy.open-cluster-management.io/v1
38+
kind: ConfigurationPolicy
39+
metadata:
40+
name: transformed-policy
41+
spec:
42+
evaluationInterval:
43+
compliant: 30m
44+
noncompliant: 45s
45+
object-templates:
46+
- complianceType: musthave
47+
objectDefinition:
48+
apiVersion: v1
49+
kind: Namespace
50+
metadata:
51+
annotations: {}
52+
labels:
53+
openshift.io/cluster-monitoring: "true"
54+
name: open-cluster-management
55+
remediationAction: inform
56+
severity: low
57+
- objectDefinition:
58+
apiVersion: policy.open-cluster-management.io/v1
59+
kind: ConfigurationPolicy
60+
metadata:
61+
name: transformed-policy2
62+
spec:
63+
evaluationInterval:
64+
compliant: 30m
65+
noncompliant: 45s
66+
object-templates:
67+
- complianceType: musthave
68+
objectDefinition:
69+
apiVersion: operators.coreos.com/v1
70+
kind: OperatorGroup
71+
metadata:
72+
annotations: {}
73+
name: open-cluster-management
74+
namespace: open-cluster-management
75+
spec:
76+
targetNamespaces:
77+
- open-cluster-management
78+
remediationAction: inform
79+
severity: low
80+
- objectDefinition:
81+
apiVersion: policy.open-cluster-management.io/v1
82+
kind: ConfigurationPolicy
83+
metadata:
84+
name: transformed-policy3
85+
spec:
86+
evaluationInterval:
87+
compliant: 30m
88+
noncompliant: 45s
89+
object-templates:
90+
- complianceType: musthave
91+
objectDefinition:
92+
apiVersion: operators.coreos.com/v1alpha1
93+
kind: Subscription
94+
metadata:
95+
annotations: {}
96+
name: advanced-cluster-management
97+
namespace: open-cluster-management
98+
spec:
99+
channel: release-2.5
100+
installPlanApproval: Automatic
101+
name: advanced-cluster-management
102+
source: redhat-operators
103+
sourceNamespace: openshift-marketplace
104+
remediationAction: inform
105+
severity: low
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: policy.open-cluster-management.io/v1
2+
kind: PolicyGenerator
3+
metadata:
4+
name: policy-transformer
5+
6+
policyDefaults:
7+
namespace: default
8+
consolidateManifests: false
9+
evaluationInterval:
10+
compliant: 30m
11+
noncompliant: 45s
12+
13+
policies:
14+
- name: transformed-policy
15+
manifests:
16+
- path: stdin

internal/plugin.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -807,16 +807,18 @@ func (p *Plugin) assertValidConfig() error {
807807
)
808808
}
809809

810-
_, err := os.Stat(manifest.Path)
811-
if err != nil {
812-
return fmt.Errorf(
813-
"could not read the manifest path %s in policy %s", manifest.Path, policy.Name,
814-
)
815-
}
810+
if manifest.Path != "stdin" {
811+
_, err := os.Stat(manifest.Path)
812+
if err != nil {
813+
return fmt.Errorf(
814+
"could not read the manifest path %s in policy %s", manifest.Path, policy.Name,
815+
)
816+
}
816817

817-
err = verifyManifestPath(p.baseDirectory, manifest.Path)
818-
if err != nil {
819-
return err
818+
err = verifyManifestPath(p.baseDirectory, manifest.Path)
819+
if err != nil {
820+
return err
821+
}
820822
}
821823

822824
evalInterval := manifest.EvaluationInterval

internal/utils.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,13 @@ func getManifests(policyConf *types.PolicyConfig) ([][]map[string]interface{}, e
5555

5656
// Handle when a Kustomization directory is specified
5757
hasKustomize := false
58+
5859
for _, f := range files {
5960
_, filename := path.Split(f.Name())
6061
if filename == "kustomization.yml" || filename == "kustomization.yaml" {
6162
hasKustomize = true
6263
manifestFiles, err = processKustomizeDir(manifest.Path)
64+
6365
if err != nil {
6466
return nil, err
6567
}
@@ -187,6 +189,27 @@ func getPolicyTemplates(policyConf *types.PolicyConfig) ([]map[string]map[string
187189
continue
188190
}
189191

192+
// Annotations with these prefixes might be added to resources by kustomize,
193+
// and should be removed when the resource is wrapped in a policy.
194+
prefixesToDelete := []string{
195+
"config.kubernetes.io/path",
196+
"config.kubernetes.io/index",
197+
"config.k8s.io/id",
198+
"kustomize.config.k8s.io/id",
199+
"internal.config.kubernetes.io",
200+
}
201+
annotations, _, _ := unstructured.NestedStringMap(manifest, "metadata", "annotations")
202+
203+
for key := range annotations {
204+
for _, prefix := range prefixesToDelete {
205+
if strings.HasPrefix(key, prefix) {
206+
delete(annotations, key)
207+
}
208+
}
209+
}
210+
211+
_ = unstructured.SetNestedStringMap(manifest, annotations, "metadata", "annotations")
212+
190213
objTemplate := map[string]interface{}{
191214
"complianceType": complianceType,
192215
"objectDefinition": manifest,

0 commit comments

Comments
 (0)