Closed mcouthon closed 3 years ago
@mcouthon We currently opted for immutability on the generated L1 level constructs to provide a more predictable experience (think about another function possibly overriding your changes).
In contrast, the L2 level constructs do offer some mutation capabilities, for example, you can add containers to existing jobs:
But since these are hand-crafted, its easier to make them safer, since the author can hand pick what can and can't be modified.
Having said that, there is a distinction between spec classes (e.g k8s.Container
), which are mainly used as inputs, and resource classes (e.g k8s.KubePod
), which are mainly used as outputs. Inputs normally shouldn't be modified because it makes it too easy to cause unexpected behavior. Outputs are less susceptible to that, and we have an issue to reconsider this, as it creates some awkward authoring ergonomics.
If there's a good reason to disallow that, then what would be the canonical way to change only one value inside an already created object?
Currently the way to do this is by using escape hatches. But they are only available on resource classes. So for example, if those containers are eventually used to configure, say a KubeJob
, then you can do something like this:
from imports import k8s
from cdk8s import JsonPatch
def enforce_security_policies_on_job(self, job: k8s.KubeJob):
containers = job.to_json()['spec']['template']['spec']['containers']
for i, container in enumerate(containers):
if not container.get('securityContext'):
job.add_json_patch(JsonPatch.add(f'/spec/template/spec/containers/{i}/securityContext', {
'readOnlyRootFilesystem': True,
'privileged': False
}))
Another, possibly better but more boilerplaty approach, is to create your own SecureJob
, class that extends k8s.KubeJob
and passes a modified copy of the containers to super
.
This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.
I see that (at least in python) all the attributes of the auto generated k8s classes are decorated as properties. Why is that? Why not allow changing the values after creation?
If there's a good reason to disallow that, then what would be the canonical way to change only one value inside an already created object?
For example, my scenario is that I have a list of containers, and post hoc want to be able to enforce some security rules. So I wanted to be able to do something like:
But, of course,
security_context
is a read-only attribute (as areread_only_root_filesystem
andprivileged
).I can hack around that with direct access to the private
_values
dict, but I'm assuming this is frowned upon.Thanks!