diff --git a/.github/workflows/kubernator.yml b/.github/workflows/kubernator.yml index ce1516b..21f3183 100644 --- a/.github/workflows/kubernator.yml +++ b/.github/workflows/kubernator.yml @@ -16,6 +16,7 @@ jobs: fail-fast: false matrix: python-version: + - '3.12' - '3.11' - '3.10' - '3.9' @@ -31,13 +32,28 @@ jobs: github.event_name == 'push' && contains(env.DEPLOY_OSES, runner.os) && contains(env.DEPLOY_PYTHONS, matrix.python-version) + shell: bash run: echo "PYB_EXTRA_ARGS=+upload" >> "$GITHUB_ENV" + + - name: Login to GitHub Container Registry for Upload + if: | + github.event_name == 'push' && + contains(env.DEPLOY_OSES, runner.os) && + contains(env.DEPLOY_PYTHONS, matrix.python-version) + + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build with PyBuilder uses: pybuilder/build@master with: python-version: ${{ matrix.python-version }} pyb-extra-args: ${{ env.PYB_EXTRA_ARGS }} + build-summary: if: success() || failure() runs-on: ubuntu-latest diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3532795 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3.11-slim-bookworm + +COPY target/dist/kubernator*/dist/*.whl /tmp + +RUN pip install --no-input --no-cache-dir /tmp/*.whl && \ + rm -rf /tmp/* + +WORKDIR /root +ENTRYPOINT ["/usr/local/bin/kubernator"] diff --git a/build.py b/build.py index 1b621b2..67e1ad2 100644 --- a/build.py +++ b/build.py @@ -18,14 +18,16 @@ import textwrap -from pybuilder.core import (use_plugin, init, Author) +from subprocess import check_call +from pybuilder.core import (use_plugin, init, Author, task) use_plugin("pypi:karellen_pyb_plugin", ">=0.0.1") use_plugin("python.coveralls") use_plugin("python.vendorize") +use_plugin("filter_resources") name = "kubernator" -version = "1.0.0" +version = "1.0.1" summary = "Kubernator is the a pluggable framework for K8S provisioning" authors = [Author("Express Systems USA, Inc.", "")] @@ -67,6 +69,8 @@ def set_properties(project): project.set_property("copy_resources_target", "$dir_dist/kubernator") project.get_property("copy_resources_glob").append("LICENSE") + project.set_property("filter_resources_target", "$dir_dist") + project.get_property("filter_resources_glob").append("kubernator/__init__.py") project.include_file("kubernator", "LICENSE") project.set_property("distutils_upload_sign", False) @@ -121,3 +125,15 @@ def set_properties(project): # limitations under the License. # """)) + + +@task +def publish(project): + image = f"ghcr.io/karellen/kubernator" + versioned_image = f"{image}:{project.dist_version}" + project.set_property("docker_image", image) + check_call(["docker", "build", "-t", versioned_image, "-t", f"{image}:latest", "."]) + +@task +def upload(project): + check_call(["docker", "push", project.get_property("docker_image"), "-a"]) diff --git a/src/main/python/kubernator/__init__.py b/src/main/python/kubernator/__init__.py index bba3ee3..df49659 100644 --- a/src/main/python/kubernator/__init__.py +++ b/src/main/python/kubernator/__init__.py @@ -16,6 +16,8 @@ # limitations under the License. # +__version__ = "${dist_version}" + def _main(): from kubernator import app diff --git a/src/main/python/kubernator/api.py b/src/main/python/kubernator/api.py index c57c225..957e00d 100644 --- a/src/main/python/kubernator/api.py +++ b/src/main/python/kubernator/api.py @@ -692,7 +692,7 @@ def cleanup(self): class KubernatorPlugin: - name = None + _name = None def set_context(self, context): raise NotImplementedError diff --git a/src/main/python/kubernator/app.py b/src/main/python/kubernator/app.py index ff18590..3754b83 100644 --- a/src/main/python/kubernator/app.py +++ b/src/main/python/kubernator/app.py @@ -57,6 +57,8 @@ def trace(self, msg, *args, **kwargs): def define_arg_parse(): parser = argparse.ArgumentParser(description="Kubernetes Provisioning Tool", formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument("--version", action="version", version=kubernator.__version__, + help="print version and exit") parser.add_argument("--log-format", choices=["human", "json"], default="human", help="whether to log for human or machine consumption") parser.add_argument("--log-file", type=argparse.FileType("w"), default=None, @@ -131,7 +133,7 @@ def json_record(self, message, extra, record: logging.LogRecord): class App(KubernatorPlugin): - name = "app" + _name = "app" def __init__(self, args): self.args = args @@ -161,6 +163,8 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.cleanup() def run(self): + logger.info("Starting Kubernator version %s", kubernator.__version__) + self.register_plugin(self) while True: @@ -206,14 +210,14 @@ def discover_plugins(self): pkgutil.iter_modules([search_path], "kubernator.plugins.")] for plugin in KubernatorPlugin.__subclasses__(): - if plugin.name in self._plugin_types: + if plugin._name in self._plugin_types: logger.warning("Plugin named %r in %r is already reserved by %r and will be ignored", - plugin.name, + plugin._name, plugin, - self._plugin_types[plugin.name]) + self._plugin_types[plugin._name]) else: - logger.info("Plugin %r discovered in %r", plugin.name, plugin) - self._plugin_types[plugin.name] = plugin + logger.info("Plugin %r discovered in %r", plugin._name, plugin) + self._plugin_types[plugin._name] = plugin def register_plugin(self, plugin: Union[KubernatorPlugin, type, str], **kwargs): context = self.context @@ -229,11 +233,11 @@ def register_plugin(self, plugin: Union[KubernatorPlugin, type, str], **kwargs): plugin_obj = plugin for p in context._plugins: - if p.name == plugin_obj.name: - logger.info("Plugin with name %r already registered, skipping", p.name) + if p._name == plugin_obj._name: + logger.info("Plugin with name %r already registered, skipping", p._name) return - logger.info("Registering plugin %r via %r", plugin_obj.name, plugin_obj) + logger.info("Registering plugin %r via %r", plugin_obj._name, plugin_obj) # Register self._run_handlers(KubernatorPlugin.register, False, context, plugin_obj, **kwargs) diff --git a/src/main/python/kubernator/plugins/__init__.py b/src/main/python/kubernator/plugins/__init__.py new file mode 100644 index 0000000..6652854 --- /dev/null +++ b/src/main/python/kubernator/plugins/__init__.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2020 Express Systems USA, Inc +# Copyright 2023 Karellen, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/src/main/python/kubernator/plugins/awscli.py b/src/main/python/kubernator/plugins/awscli.py index 5f06e83..64e39da 100644 --- a/src/main/python/kubernator/plugins/awscli.py +++ b/src/main/python/kubernator/plugins/awscli.py @@ -42,7 +42,7 @@ class AwsCliPlugin(KubernatorPlugin): logger = logger - name = "awscli" + _name = "awscli" def __init__(self): self.context = None diff --git a/src/main/python/kubernator/plugins/eks.py b/src/main/python/kubernator/plugins/eks.py index 9d22219..b29bc59 100644 --- a/src/main/python/kubernator/plugins/eks.py +++ b/src/main/python/kubernator/plugins/eks.py @@ -33,7 +33,7 @@ class EksPlugin(KubernatorPlugin): logger = logger - name = "eks" + _name = "eks" def __init__(self): self.context = None diff --git a/src/main/python/kubernator/plugins/helm.py b/src/main/python/kubernator/plugins/helm.py index f0ace79..82f9f96 100644 --- a/src/main/python/kubernator/plugins/helm.py +++ b/src/main/python/kubernator/plugins/helm.py @@ -96,7 +96,7 @@ class HelmPlugin(KubernatorPlugin): logger = logger - name = "helm" + _name = "helm" def __init__(self): self.context = None diff --git a/src/main/python/kubernator/plugins/istio.py b/src/main/python/kubernator/plugins/istio.py index d8b0859..5c4fc51 100644 --- a/src/main/python/kubernator/plugins/istio.py +++ b/src/main/python/kubernator/plugins/istio.py @@ -52,7 +52,7 @@ class IstioPlugin(KubernatorPlugin, K8SResourcePluginMixin): logger = logger - name = "istio" + _name = "istio" def __init__(self): self.context = None diff --git a/src/main/python/kubernator/plugins/k8s.py b/src/main/python/kubernator/plugins/k8s.py index 04a8561..d3add26 100644 --- a/src/main/python/kubernator/plugins/k8s.py +++ b/src/main/python/kubernator/plugins/k8s.py @@ -59,7 +59,7 @@ def final_resource_validator(resources: Sequence[K8SResource], class KubernetesPlugin(KubernatorPlugin, K8SResourcePluginMixin): logger = logger - name = "k8s" + _name = "k8s" def __init__(self): super().__init__() diff --git a/src/main/python/kubernator/plugins/kops.py b/src/main/python/kubernator/plugins/kops.py index e0ee3ff..832f19a 100644 --- a/src/main/python/kubernator/plugins/kops.py +++ b/src/main/python/kubernator/plugins/kops.py @@ -50,7 +50,7 @@ class KopsPlugin(KubernatorPlugin, K8SResourcePluginMixin): logger = logger - name = "kops" + _name = "kops" def __init__(self): self.context = None diff --git a/src/main/python/kubernator/plugins/kubeconfig.py b/src/main/python/kubernator/plugins/kubeconfig.py index b1c04be..e52cfde 100644 --- a/src/main/python/kubernator/plugins/kubeconfig.py +++ b/src/main/python/kubernator/plugins/kubeconfig.py @@ -32,7 +32,7 @@ class KubeConfigPlugin(KubernatorPlugin): logger = logger - name = "kubeconfig" + _name = "kubeconfig" def __init__(self): self.context = None diff --git a/src/main/python/kubernator/plugins/kubectl.py b/src/main/python/kubernator/plugins/kubectl.py index c061593..3049f7c 100644 --- a/src/main/python/kubernator/plugins/kubectl.py +++ b/src/main/python/kubernator/plugins/kubectl.py @@ -39,7 +39,7 @@ class KubectlPlugin(KubernatorPlugin): logger = logger - name = "kubectl" + _name = "kubectl" def __init__(self): self.context = None diff --git a/src/main/python/kubernator/plugins/minikube.py b/src/main/python/kubernator/plugins/minikube.py index 5d98ae9..ff7dca8 100644 --- a/src/main/python/kubernator/plugins/minikube.py +++ b/src/main/python/kubernator/plugins/minikube.py @@ -34,7 +34,7 @@ class MinikubePlugin(KubernatorPlugin): logger = logger - name = "minikube" + _name = "minikube" def __init__(self): self.context = None diff --git a/src/main/python/kubernator/plugins/template.py b/src/main/python/kubernator/plugins/template.py index c989411..e0461e0 100644 --- a/src/main/python/kubernator/plugins/template.py +++ b/src/main/python/kubernator/plugins/template.py @@ -92,7 +92,7 @@ class TemplatePlugin(KubernatorPlugin): logger = logger - name = "templates" + _name = "templates" def __init__(self): self.context = None diff --git a/src/main/python/kubernator/plugins/terraform.py b/src/main/python/kubernator/plugins/terraform.py index 5eacc19..75b460d 100644 --- a/src/main/python/kubernator/plugins/terraform.py +++ b/src/main/python/kubernator/plugins/terraform.py @@ -41,7 +41,7 @@ class TerraformPlugin(KubernatorPlugin): logger = logger - name = "terraform" + _name = "terraform" def __init__(self): self.context = None diff --git a/src/main/python/kubernator/plugins/terragrunt.py b/src/main/python/kubernator/plugins/terragrunt.py index 3d24619..34b8e34 100644 --- a/src/main/python/kubernator/plugins/terragrunt.py +++ b/src/main/python/kubernator/plugins/terragrunt.py @@ -38,7 +38,7 @@ class TerragruntPlugin(KubernatorPlugin): logger = logger - name = "terragrunt" + _name = "terragrunt" def __init__(self): self.context = None