From fd7c00949210208324709bc95fe1523d338a6554 Mon Sep 17 00:00:00 2001 From: Ales Verbic Date: Mon, 12 Feb 2024 13:58:28 -0500 Subject: [PATCH] feat: add support for PersistentVolume Signed-off-by: Ales Verbic --- README.md | 19 ++-- deploy_config_generator/output/kube_common.py | 91 +++++++++++++++++++ deploy_config_generator/output/kube_pv.py | 42 +++++++++ docs/plugin_kube_pv.md | 46 ++++++++++ setup.py | 2 +- .../integration/kube_basic/deploy/config.yml | 18 ++++ .../expected_output/kube_pv-001-test-pv.yaml | 18 ++++ 7 files changed, 226 insertions(+), 10 deletions(-) create mode 100644 deploy_config_generator/output/kube_pv.py create mode 100644 docs/plugin_kube_pv.md create mode 100644 tests/integration/kube_basic/expected_output/kube_pv-001-test-pv.yaml diff --git a/README.md b/README.md index ead6015..9289f4d 100644 --- a/README.md +++ b/README.md @@ -18,31 +18,31 @@ Utility for generating deployment configs for a service The below command will generate the required deployment config files for the specified service in the current directory. ```bash -$ deploy-config-generator path/to/service/repo +deploy-config-generator path/to/service/repo ``` You can specify the environment to generate configuration for. ```bash -$ deploy-config-generator path/to/service/repo -e stage +deploy-config-generator path/to/service/repo -e stage ``` You can specify the output directory using the `--output-dir` option. ```bash -$ deploy-config-generator path/to/service/repo --output-dir /tmp +deploy-config-generator path/to/service/repo --output-dir /tmp ``` You can increase the verbosity level to see what the script is doing. ```bash -$ deploy-config-generator path/to/service/repo -vvv +deploy-config-generator path/to/service/repo -vvv ``` You can specify the path to a site config file. ```bash -$ deploy-config-generator path/to/service/repo --config path/to/site/config.yml +deploy-config-generator path/to/service/repo --config path/to/site/config.yml ``` ## The dirty details @@ -134,6 +134,7 @@ The following output plugins are available: * [`kube_kong_plugin`](docs/plugin_kube_kong_plugin.md) * [`kube_namespace`](docs/plugin_kube_namespace.md) * [`kube_pdb`](docs/plugin_kube_pdb.md) +* [`kube_pv`](docs/plugin_kube_pv.md) * [`kube_pvc`](docs/plugin_kube_pvc.md) * [`kube_secret`](docs/plugin_kube_secret.md) * [`kube_service`](docs/plugin_kube_service.md) @@ -149,14 +150,14 @@ The following output plugins are available: This tool comes with unit and integration test suites, which can be run with the commands: ```bash -$ python setup.py test -$ python setup.py integration +python setup.py test +python setup.py integration ``` You can run the full test suite in multiple python versions using `tox` by running: ```bash -$ tox +tox ``` ### Regenerating plugin docs @@ -165,5 +166,5 @@ The docs for the individual plugins are generated from the code of the plugins. with the following command: ```bash -$ scripts/gen-plugin-docs.py +scripts/gen-plugin-docs.py ``` diff --git a/deploy_config_generator/output/kube_common.py b/deploy_config_generator/output/kube_common.py index 338c237..21fbc98 100644 --- a/deploy_config_generator/output/kube_common.py +++ b/deploy_config_generator/output/kube_common.py @@ -667,6 +667,97 @@ ), ) +PERSISTENT_VOLUME_FIELD_SPEC = dict( + access_modes=dict( + type='list', + required=True, + subtype='str', + ), + capacity=dict( + type='dict', + required=True, + fields=dict( + storage=dict( + type='str', + ), + ), + ), + persistent_volume_reclaim_policy=dict( + type='str', + ), + storage_class_name=dict( + type='str', + ), + volume_mode=dict( + type='str', + ), + mount_options=dict( + type='list', + subtype='str', + ), + claim_ref=dict( + type='dict', + fields=dict( + api_version=dict( + type='str', + ), + kind=dict( + type='str', + ), + namespace=dict( + type='str', + ), + name=dict( + type='str', + ), + ), + ), + node_affinity=dict( + type='dict', + fields=dict( + required=dict( + type='dict', + fields=dict( + node_selector_terms=dict( + type='list', + subtype='dict', + ), + ), + ), + ), + ), + csi=dict( + type='dict', + fields=dict( + driver=dict(type='str'), + volume_handle=dict(type='str'), + read_only=dict( + type='bool', + ), + fs_type=dict( + type='str', + ), + volume_attributes=dict( + type='dict', + subtype='str', + ), + ), + ), + nfs=dict( + type='dict', + fields=dict( + path=dict( + type='str', + required=True + ), + server=dict( + type='str', + required=True + ), + ), + ), +) + class OutputPlugin(OutputPluginBase): diff --git a/deploy_config_generator/output/kube_pv.py b/deploy_config_generator/output/kube_pv.py new file mode 100644 index 0000000..6d37054 --- /dev/null +++ b/deploy_config_generator/output/kube_pv.py @@ -0,0 +1,42 @@ +import copy + +from deploy_config_generator.utils import yaml_dump +from deploy_config_generator.output import kube_common + + +class OutputPlugin(kube_common.OutputPlugin): + + NAME = 'kube_pv' + DESCR = 'Kubernetes PersistentVolume output plugin' + FILE_EXT = '.yaml' + + DEFAULT_CONFIG = { + 'fields': { + 'kube_pvs': dict( + metadata=dict( + type='dict', + required=True, + fields=copy.deepcopy(kube_common.METADATA_FIELD_SPEC), + ), + spec=dict( + type='dict', + required=True, + fields=copy.deepcopy(kube_common.PERSISTENT_VOLUME_FIELD_SPEC), + ), + ), + } + } + + def generate_output(self, app_vars): + # Basic structure + data = { + 'apiVersion': 'v1', + 'kind': 'PersistentVolume', + 'spec': dict(), + } + data['metadata'] = self.build_metadata(app_vars['APP']['metadata']) + data['spec'] = self.build_generic(app_vars['APP']['spec'], self._plugin_config['fields']['kube_pvs']['spec']['fields']) + + data = self._template.render_template(data, app_vars) + output = yaml_dump(data) + return (output, self.get_output_filename_suffix(data)) diff --git a/docs/plugin_kube_pv.md b/docs/plugin_kube_pv.md new file mode 100644 index 0000000..62637d8 --- /dev/null +++ b/docs/plugin_kube_pv.md @@ -0,0 +1,46 @@ + +# kube_pv + +Kubernetes PersistentVolume output plugin + +### Parameters + + +#### Deploy config section: kube_pvs + +Name | Type | Required | Default | Description +--- | --- | --- | --- | --- +`metadata`|`dict`|yes|| +`metadata . annotations`|`dict`|no|| +`metadata . labels`|`dict`|no|| +`metadata . name`|`str`|no|| +`metadata . namespace`|`str`|no|| +`spec`|`dict`|yes|| +`spec . access_modes`|`list` (of `str`)|yes|| +`spec . capacity`|`dict`|yes|| +`spec . capacity . storage`|`str`|no|| +`spec . claim_ref`|`dict`|no|| +`spec . claim_ref . api_version`|`str`|no|| +`spec . claim_ref . kind`|`str`|no|| +`spec . claim_ref . name`|`str`|no|| +`spec . claim_ref . namespace`|`str`|no|| +`spec . csi`|`dict`|no|| +`spec . csi . driver`|`str`|no|| +`spec . csi . fs_type`|`str`|no|| +`spec . csi . read_only`|`bool`|no|| +`spec . csi . volume_attributes`|`dict` (of `str`)|no|| +`spec . csi . volume_handle`|`str`|no|| +`spec . mount_options`|`list` (of `str`)|no|| +`spec . nfs`|`dict`|no|| +`spec . nfs . path`|`str`|yes|| +`spec . nfs . server`|`str`|yes|| +`spec . node_affinity`|`dict`|no|| +`spec . node_affinity . required`|`dict`|no|| +`spec . node_affinity . required . node_selector_terms`|`list` (of `dict`)|no|| +`spec . persistent_volume_reclaim_policy`|`str`|no|| +`spec . storage_class_name`|`str`|no|| +`spec . volume_mode`|`str`|no|| + + diff --git a/setup.py b/setup.py index f57d7da..3ebece4 100644 --- a/setup.py +++ b/setup.py @@ -53,7 +53,7 @@ def run(self): setup( name='deploy-config-generator', - version='2.27.0', + version='2.28.0', url='https://github.com/ApplauseOSS/deploy-config-generator', license='MIT', description='Utility to generate service deploy configurations', diff --git a/tests/integration/kube_basic/deploy/config.yml b/tests/integration/kube_basic/deploy/config.yml index 02bce02..f5730d4 100644 --- a/tests/integration/kube_basic/deploy/config.yml +++ b/tests/integration/kube_basic/deploy/config.yml @@ -171,6 +171,24 @@ kube_pvcs: match_expressions: - {key: environment, operator: In, values: [dev]} +kube_pvs: + - metadata: + name: test-pv + spec: + capacity: + storage: 8Gi + volume_mode: Filesystem + access_modes: + - ReadWriteOnce + persistent_volume_reclaim_policy: Recycle + storage_class_name: slow + mount_options: + - hard + - nfsvers=4.1 + nfs: + path: /tmp + server: 172.17.0.2 + kube_configmaps: - metadata: name: test-configmap diff --git a/tests/integration/kube_basic/expected_output/kube_pv-001-test-pv.yaml b/tests/integration/kube_basic/expected_output/kube_pv-001-test-pv.yaml new file mode 100644 index 0000000..f345a5d --- /dev/null +++ b/tests/integration/kube_basic/expected_output/kube_pv-001-test-pv.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: test-pv +spec: + accessModes: + - ReadWriteOnce + capacity: + storage: 8Gi + mountOptions: + - hard + - nfsvers=4.1 + nfs: + path: /tmp + server: 172.17.0.2 + persistentVolumeReclaimPolicy: Recycle + storageClassName: slow + volumeMode: Filesystem