Skip to content

Commit ed0eb4c

Browse files
author
Patrick J. McNerthney
committed
Documentation of ConfigMap and Secret based packages
1 parent f8aba76 commit ed0eb4c

File tree

2 files changed

+144
-4
lines changed

2 files changed

+144
-4
lines changed

README.md

Lines changed: 142 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,12 @@ spec:
3535
vpc.spec.forProvider.cidrBlock = self.spec.cidr
3636
self.status.vpcId = vpc.status.atProvider.vpcId
3737
```
38+
3839
In addtion to an inline script, the python implementation can be specified
39-
as the complete path to a python class. See [Filing system Composites](#filing-system-composites).
40+
as the complete path to a python class. Python packages can be deployed using
41+
ConfigMaps or Secrets enabling the use of your IDE of choice for writting
42+
the code. See [ConfigMap and Secret Packages](#configmap-and-secret-packages)
43+
and [Filing System Packages](#filing-system-packages).
4044
4145
## Examples
4246
@@ -297,7 +301,143 @@ spec:
297301
self.status.composite = 'Hello, World!'
298302
```
299303

300-
## Filing system Composites
304+
## ConfigMap and Secret Packages
305+
306+
ConfigMap and Secret based python packages are enable using the `--packages`
307+
and `--packages-namespace` command line options. ConfigMaps and Secrets
308+
with the label `function-pythonic.package` will be incorporated in the python
309+
path at the location configured in the label value. For example, the following
310+
ConfigMap will enable python to use `import example.pythonic.features`
311+
```yaml
312+
apiVersion: v1
313+
kind: ConfigMap
314+
metadata:
315+
namespace: crossplane-system
316+
name: example-pythonic
317+
labels:
318+
function-pythonic.package: example.pythonic
319+
data:
320+
features.py: |
321+
def anything():
322+
return 'something'
323+
```
324+
Then, in your Composition:
325+
```yaml
326+
...
327+
- step: pythonic
328+
functionRef:
329+
name: function-pythonic
330+
input:
331+
apiVersion: pythonic.fn.fortra.com/v1alpha1
332+
kind: Composite
333+
composite: |
334+
from example.pythonic import features
335+
class Composite(BaseComposite):
336+
def compose(self):
337+
anything = features.anything()
338+
...
339+
```
340+
The entire function-pythonic Composite class can be coded in the ConfigMap and
341+
the only the complete path is needed in the step configuration.
342+
```yaml
343+
apiVersion: v1
344+
kind: ConfigMap
345+
metadata:
346+
namespace: crossplane-system
347+
name: example-pythonic
348+
labels:
349+
function-pythonic.package: example.pythonic
350+
data:
351+
features.py: |
352+
from crossplane.pythonic import BaseComposite
353+
class FeatureOneComposite(BaseComposite):
354+
def compose(self):
355+
# go at it!
356+
```
357+
```yaml
358+
...
359+
- step: pythonic
360+
functionRef:
361+
name: function-pythonic
362+
input:
363+
apiVersion: pythonic.fn.fortra.com/v1alpha1
364+
kind: Composite
365+
composite: example.pythonic.features.FeatureOneComposite
366+
...
367+
```
368+
This requires enabling the the packages support using the `--packages` command
369+
line option in the DeploymentRuntimeConfig and configuring the required
370+
Kubernetes RBAC permissions. For example:
371+
```yaml
372+
apiVersion: pkg.crossplane.io/v1
373+
kind: Function
374+
metadata:
375+
name: function-pythonic
376+
spec:
377+
package: ghcr.io/fortra/function-pythonic:v0.0.6
378+
runtimeConfigRef:
379+
name: function-pythonic
380+
---
381+
apiVersion: pkg.crossplane.io/v1beta1
382+
kind: DeploymentRuntimeConfig
383+
metadata:
384+
name: function-pythonic
385+
spec:
386+
deploymentTemplate:
387+
spec:
388+
selector: {}
389+
template:
390+
spec:
391+
containers:
392+
- name: package-runtime
393+
args:
394+
- --debug
395+
- --packages
396+
serviceAccountName: function-pythonic
397+
serviceAccountTemplate:
398+
metadata:
399+
name: function-pythonic
400+
---
401+
apiVersion: rbac.authorization.k8s.io/v1
402+
kind: ClusterRole
403+
metadata:
404+
name: function-pythonic
405+
rules:
406+
- apiGroups:
407+
- ''
408+
resources:
409+
- events
410+
verbs:
411+
- create
412+
- apiGroups:
413+
- ''
414+
resources:
415+
- configmaps
416+
- secrets
417+
verbs:
418+
- list
419+
- watch
420+
- patch
421+
---
422+
apiVersion: rbac.authorization.k8s.io/v1
423+
kind: ClusterRoleBinding
424+
metadata:
425+
name: function-pythonic
426+
roleRef:
427+
apiGroup: rbac.authorization.k8s.io
428+
kind: ClusterRole
429+
name: function-pythonic
430+
subjects:
431+
- kind: ServiceAccount
432+
namespace: crossplane-system
433+
name: function-pythonic
434+
```
435+
When enabled, labeled ConfigMaps and Secrets are obtained cluster wide,
436+
requiring the above ClusterRole permissions. The `--packages-name` command
437+
line option will restrict to only using the supplied namespaces. Per namespace
438+
RBAC permissions are then required.
439+
440+
## Filing System Packages
301441

302442
Composition Composite implementations can be coded in a stand alone python files
303443
by configuring the function-pythonic deployment with the code mounted into

crossplane/pythonic/packages.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ async def update(body, old, logger, **_):
5656
for name, text in body.get('data', {}).items():
5757
package_file = package_dir / name
5858
if package_dir == old_package_dir and text == old_data.get(name, None):
59-
action = 'Same'
59+
action = 'Unchanged'
6060
else:
6161
if secret:
6262
package_file.write_bytes(base64.b64decode(text.encode('utf-8')))
@@ -65,7 +65,7 @@ async def update(body, old, logger, **_):
6565
action = 'Updated' if package_dir == old_package_dir and name in old_names else 'Created'
6666
if package_file.suffixes == ['.py']:
6767
module = '.'.join(package + [package_file.stem])
68-
if action != 'Same':
68+
if action != 'Unchanged':
6969
GRPC_RUNNER.invalidate_module(module)
7070
logger.info(f"{action} module: {module}")
7171
else:

0 commit comments

Comments
 (0)