diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..e51474d0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +# EditorConfig http://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 4 +tab_width = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = true +max_line_length = 80 +curly_bracket_next_line = false +spaces_around_operators = true +spaces_around_brackets = true +indent_brace_style = K&R + diff --git a/.travis.yml b/.travis.yml index 6c5b6cd3..c6bfacfe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,24 +6,30 @@ python: - "2.7" before_install: - - export LIGGIT2_VERSION=0.24.0 - - export LIBGIT2=$VIRTUAL_ENV - - wget https://github.com/libgit2/libgit2/archive/v${LIGGIT2_VERSION}.tar.gz - - tar xzf v${LIGGIT2_VERSION}.tar.gz - - cd libgit2-${LIGGIT2_VERSION}/ - - cmake . -DCMAKE_INSTALL_PREFIX=$LIBGIT2 - - make - - make install - - export LDFLAGS="-Wl,-rpath='$LIBGIT2/lib',--enable-new-dtags $LDFLAGS" - - cd .. - - pip install -r test-requirements.txt - - pip install -r requirements.txt - - pip install pygit2==0.24.0 + - export LIGGIT2_VERSION=0.24.0 + - export LIBGIT2=$VIRTUAL_ENV + - wget https://github.com/libgit2/libgit2/archive/v${LIGGIT2_VERSION}.tar.gz + - tar xzf v${LIGGIT2_VERSION}.tar.gz + - cd libgit2-${LIGGIT2_VERSION}/ + - cmake . -DCMAKE_INSTALL_PREFIX=$LIBGIT2 + - make + - make install + - export LDFLAGS="-Wl,-rpath='$LIBGIT2/lib',--enable-new-dtags $LDFLAGS" + - cd .. + - pip install -r test-requirements.txt + - pip install -r requirements.txt + - pip install tox + - pip install pygit2==0.24.0 install: - - pip install . + - pip install . script: - - flake8 - - armada -h + - flake8 + - armada -h # - armada -c examples/armada.yaml -d + +after_success: + - cd docs && make html + - touch .nojekyll + - git clean -fdx diff --git a/Dockerfile b/Dockerfile index ae74350b..257216b5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,16 @@ FROM ubuntu:16.04 MAINTAINER Armada Team -ENV USER=armada \ - VERSION=master \ - REPO=https://github.com/att-comdev/armada.git +ARG VERSION +ARG REPO -RUN apt-get update && \ - apt-get install -y \ +ENV USER=armada \ + VERSION=${VERSION:-master} \ + REPO=${REPO:-https://github.com/att-comdev/armada.git} + + +RUN apt-get update -yqq && \ + apt-get install -yqq \ build-essential \ git \ git-review \ @@ -16,18 +20,19 @@ RUN apt-get update && \ gcc \ libssl-dev \ libffi-dev \ - libgit2-dev \ - && git clone -b $VERSION $REPO ${HOME}/armada + libgit2-dev + +RUN git clone -b $VERSION $REPO ${HOME}/armada WORKDIR /root/armada RUN pip install -r requirements.txt \ - && sh scripts/libgit2.sh \ + && sh tools/libgit2.sh \ && pip install --upgrade urllib3 \ - && pip install pygit2 \ - && python setup.py install - -ENTRYPOINT ["armada"] + && pip install pygit2==0.25.0 \ + && pip install -e . EXPOSE 8000 -CMD gunicorn server:api -b :8000 +ENTRYPOINT ["./entrypoint.sh"] + +CMD ["server"] diff --git a/README.md b/README.md deleted file mode 100644 index 346861bc..00000000 --- a/README.md +++ /dev/null @@ -1,135 +0,0 @@ -# Armada - -[![Docker Repository on Quay](https://quay.io/repository/attcomdev/armada/status "Docker Repository on Quay")](https://quay.io/repository/attcomdev/armada) -[![Build Status](https://travis-ci.org/att-comdev/armada.svg?branch=master)](https://travis-ci.org/att-comdev/armada) - -A python orchestrator for a installing, upgrading, and managing a collection of helm charts, dependencies, and values overrides. - -Note that this project is pre-alpha and under active development. It may undergo drastic changes to support the long-term vision but contributions are welcome. - - -## Overview - -The armada python library and command line tool provides a way to synchronize a helm (tiller) target with an operators intended state, consisting of several charts, dependencies, and overrides using a single file or directory with a collection of files. This allows operators to define many charts, potentially with different namespaces for those releases, and their overrides in a central place. With a single command, deploy and/or upgrade them where applicable. - -Armada also supports fetching helm chart source and then building charts from source from various local and remote locations, such as git/github endpoints. In the future, it may supprot other mechanisms as well. - -It will also give the operator some indication of what is about to change by assisting with diffs for both values, values overrides, and actual template changes. - -Its functionality may extend beyond helm, assisting in interacting with kubernetes directly to perform basic pre and post steps, such as removing completed or failed jobs, running backup jobs, blocking on chart readiness, or deleting resources that do not support upgrades. However, primarily, it will be an interface to support orchestrating Helm. - - -## Running Armada - -To use this container, use these simple instructions: - -``` -docker build -t armada . -``` - - -``` -docker run -v ~/.kube/config:/root/.kube/config -v $(pwd)/examples/:/examples -v /tmp:/dev/log quay.io/attcomdev/armada:latest -``` - -## Development - -For development please refer to [Getting Started](./docs/development/getting-started.rst) guide - -## Installation - -The installation is fairly straight forward: - -Recomended Enviroment: Ubuntu 16.04 - -### Installing Dependecies: - -you can run: - -* `tox testenv:ubuntu` or `sudo sh scripts/libgit2.sh` -* `sudo pip install -r requirements.txt` - -NOTE: If you want to use virtualenv please refer to [pygit2](http://www.pygit2.org/install.html#libgit2-within-a-virtual-environment) - -### Installing armada: - -`sudo pip install -e .` - -`armada -h` - -## Using Armada - -Before using armada we need to check a few things: - -1. you have a properly configure `~/.kube/config` - * `kubectl config view` - * If it does not exist, you can create it using [kubectl](https://kubernetes.io/docs/user-guide/kubectl/kubectl_config/) - -1. Check that you have a running Tiller - * `kubectl get pods -n kube-system` - -To run armada, simply supply it with your YAML based intention for any number of charts: - -``` -armada -c examples/armada.yaml -``` - -Your output will look something like this: - -``` -$ armada -c examples/armada.yaml -2017-02-10 09:42:36,753 armada INFO Cloning git://github.com/att-comdev/openstack-helm/keystone for release keystone -2017-02-10 09:42:39,238 armada INFO Building dependency chart common for release keystone -2017-02-10 09:42:39,238 armada INFO Cloning git://github.com/att-comdev/openstack-helm/common for release None -2017-02-10 09:42:41,459 armada INFO Installing release keystone -``` - -If you were to run it a second time, modifying the shared values override example in examples/armada.conf: - -``` -endpoints: &endpoints - glance: - this: is an example -``` - -to: - -``` -endpoints: &endpoints - glance: - this: is an example - that: is another example -``` - -And re-run armada, we will notice it will upgrade the keystone release, instead of install it on this pass, as well as report back the values changes as a unified diff. A unified diff for any template changes would also be shown had those occurred. - -``` -alan@hpdesktop:~/Workbench/att/attcomdev/armada$ armada -c examples/armada.yaml -2017-02-10 09:44:43,396 armada INFO Cloning git://github.com/att-comdev/openstack-helm/keystone for release keystone -2017-02-10 09:44:47,640 armada INFO Building dependency chart common for release keystone -2017-02-10 09:44:47,640 armada INFO Cloning git://github.com/att-comdev/openstack-helm/common for release None -2017-02-10 09:44:49,701 armada INFO Upgrading release keystone -2017-02-10 09:44:49,704 armada INFO Values Unified Diff (keystone) ---- - -+++ - -@@ -1,3 +1,3 @@ - - endpoints: -- glance: {this: is an example} -+ glance: {that: is another example, this: is an example} - -``` - -# Helm gRPC - -The helm gRPC libraries are located in the hapi directory. They were generated with the grpc_tools.protoc utility against Helm 2.1.3. Should you wish to re-generate them you can easily do so: - -``` - git clone https://github.com/kubernetes/helm ./helm - python -m grpc_tools.protoc -I helm/_proto --python_out=. --grpc_python_out=. helm/_proto/hapi/chart/* - python -m grpc_tools.protoc -I helm/_proto --python_out=. --grpc_python_out=. helm/_proto/hapi/services/* - python -m grpc_tools.protoc -I helm/_proto --python_out=. --grpc_python_out=. helm/_proto/hapi/release/* - python -m grpc_tools.protoc -I helm/_proto --python_out=. --grpc_python_out=. helm/_proto/hapi/version/* -``` diff --git a/README.rst b/README.rst new file mode 100644 index 00000000..cdc98c04 --- /dev/null +++ b/README.rst @@ -0,0 +1,119 @@ +Armada +====== + +|Docker Repository on Quay| |Build Status| |Doc Status| + +A python orchestrator for a installing, upgrading, and managing a +collection of helm charts, dependencies, and values overrides. + +Note that this project is pre-alpha and under active development. It may +undergo drastic changes to support the long-term vision but +contributions are welcome. + +Overview +-------- + +The armada python library and command line tool provides a way to +synchronize a helm (tiller) target with an operators intended state, +consisting of several charts, dependencies, and overrides using a single +file or directory with a collection of files. This allows operators to +define many charts, potentially with different namespaces for those +releases, and their overrides in a central place. With a single command, +deploy and/or upgrade them where applicable. + +Armada also supports fetching helm chart source and then building charts +from source from various local and remote locations, such as git/github +endpoints. In the future, it may supprot other mechanisms as well. + +It will also give the operator some indication of what is about to +change by assisting with diffs for both values, values overrides, and +actual template changes. + +Its functionality may extend beyond helm, assisting in interacting with +kubernetes directly to perform basic pre and post steps, such as +removing completed or failed jobs, running backup jobs, blocking on +chart readiness, or deleting resources that do not support upgrades. +However, primarily, it will be an interface to support orchestrating +Helm. + +Running Armada +-------------- + +To use this container, use these simple instructions: + +:: + + docker run -d --name armada -p 8000:8000 -v ~/.kube/config:/root/.kube/config -v $(pwd)/examples/:/examples -v /tmp:/dev/log quay.io/attcomdev/armada:latest + +Manual Install +~~~~~~~~~~~~~~ + +If you want to build the docker image, follow these steps: + +:: + + docker build . -t /armada + docker run -d --name armada -p 8000:8000 -v ~/.kube/config:/root/.kube/config -v $(pwd)/examples/:/examples /armada + +Installation +------------ + +The installation is fairly straight forward: + +Recomended Enviroment: Ubuntu 16.04 + +Installing Dependecies: +~~~~~~~~~~~~~~~~~~~~~~~ + +you can run: + +- ``tox testenv:ubuntu`` or ``sudo sh scripts/libgit2.sh`` +- ``sudo pip install -r requirements.txt`` + +NOTE: If you want to use virtualenv please refer to `pygit2`_ + +Installing armada: +~~~~~~~~~~~~~~~~~~ + +``sudo pip install -e .`` + +``armada [-h | --help]`` + +Using Armada +------------ + +Before using armada we need to check a few things: + +1. you have a properly configure ``~/.kube/config`` + + - ``kubectl config view`` + - If it does not exist, you can create it using `kubectl`_ + +2. Check that you have a running Tiller + + - ``kubectl get pods -n kube-system`` + +To run armada, simply supply it with your YAML based intention for any +number of charts: + +:: + + $ aramda apply examples/armada.yaml [--debug ] + +Your output will look something like this: + +:: + + $ armada apply examples/armada.yaml 2017-02-10 09:42:36,753 + armada INFO Cloning git: + +.. _pygit2: http://www.pygit2.org/install.html#libgit2-within-a-virtual-environment +.. _kubectl: https://kubernetes.io/docs/user-guide/kubectl/kubectl_config/ + +.. |Docker Repository on Quay| image:: https://quay.io/repository/attcomdev/armada/status + :target: https://quay.io/repository/attcomdev/armada +.. |Build Status| image:: https://travis-ci.org/att-comdev/armada.svg?branch=master + :target: https://travis-ci.org/att-comdev/armada +.. |Doc Status| image:: https://readthedocs.org/projects/armada-helm/badge/?version=latest + :target: http://armada-helm.readthedocs.io/ + diff --git a/armada/__init__.py b/armada/__init__.py index e69de29b..edcec8e2 100644 --- a/armada/__init__.py +++ b/armada/__init__.py @@ -0,0 +1,23 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + +__all__ = ['__version__'] + +import pbr.version + +version_info = pbr.version.VersionInfo('armada') +try: + __version__ = version_info.version_string() +except AttributeError: + __version__ = None diff --git a/armada/api/__init__.py b/armada/api/__init__.py new file mode 100644 index 00000000..3a4dedd8 --- /dev/null +++ b/armada/api/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 The Armada Authors. +# +# 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/armada/cli/__init__.py b/armada/cli/__init__.py new file mode 100644 index 00000000..3a4dedd8 --- /dev/null +++ b/armada/cli/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 The Armada Authors. +# +# 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/armada/cli/apply.py b/armada/cli/apply.py new file mode 100644 index 00000000..72aba151 --- /dev/null +++ b/armada/cli/apply.py @@ -0,0 +1,53 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + +import logging + +from cliff import command as cmd + +from armada.handlers.armada import Armada + +LOG = logging.getLogger(__name__) + +def applyCharts(args): + + armada = Armada(open(args.file).read(), + args.disable_update_pre, + args.disable_update_post, + args.enable_chart_cleanup, + args.skip_pre_flight, + args.dry_run) + armada.sync() + +class ApplyChartsCommand(cmd.Command): + def get_parser(self, prog_name): + parser = super(ApplyChartsCommand, self).get_parser(prog_name) + parser.add_argument('file', type=str, metavar='FILE', + help='Armada yaml file') + parser.add_argument('--dry-run', action='store_true', + default=False, help='Run charts with dry run') + parser.add_argument('--skip-pre-flight', action='store_true', + default=False, help='Skip Pre Flight') + parser.add_argument('--debug', action='store', + default=False, help='Run charts with dry run') + parser.add_argument('--disable-update-pre', action='store', + default=False, help='Disable pre upgrade actions') + parser.add_argument('--disable-update-post', action='store', + default=False, help='Disable post upgrade actions') + parser.add_argument('--enable-chart-cleanup', action='store', + default=False, help='Enable Chart Clean Up') + return parser + + def take_action(self, parsed_args): + applyCharts(parsed_args) diff --git a/armada/cli/tiller.py b/armada/cli/tiller.py new file mode 100644 index 00000000..f513e5e7 --- /dev/null +++ b/armada/cli/tiller.py @@ -0,0 +1,45 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + +import logging + +from cliff import command as cmd + +from armada.handlers.tiller import Tiller + +LOG = logging.getLogger(__name__) + +def tillerServer(args): + + tiller = Tiller() + + if args.status: + LOG.info('Tiller is Active: %s', tiller.tiller_status()) + + if args.releases: + for release in tiller.list_releases(): + LOG.info("Release: %s ( namespace= %s )", release.name, + release.namespace) + +class TillerServerCommand(cmd.Command): + def get_parser(self, prog_name): + parser = super(TillerServerCommand, self).get_parser(prog_name) + parser.add_argument('--status', action='store_true', + default=False, help='Check Tiller service') + parser.add_argument('--releases', action='store_true', + default=False, help='List Tiller Releases') + return parser + + def take_action(self, parsed_args): + tillerServer(parsed_args) diff --git a/armada/handlers/__init__.py b/armada/handlers/__init__.py new file mode 100644 index 00000000..3a4dedd8 --- /dev/null +++ b/armada/handlers/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 The Armada Authors. +# +# 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/armada/armada.py b/armada/handlers/armada.py similarity index 75% rename from armada/armada.py rename to armada/handlers/armada.py index 5182d9e2..87c7a639 100644 --- a/armada/armada.py +++ b/armada/handlers/armada.py @@ -1,11 +1,30 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + import difflib import yaml +import logging from supermutes.dot import dotify from chartbuilder import ChartBuilder from tiller import Tiller -from logutil import LOG +from ..utils.release import release_prefix +from ..utils import git +from ..utils import lint + +LOG = logging.getLogger(__name__) class Armada(object): ''' @@ -17,6 +36,7 @@ class Armada(object): disable_update_pre=False, disable_update_post=False, enable_chart_cleanup=False, + skip_pre_flight=False, dry_run=False): ''' Initialize the Armada Engine and establish @@ -25,6 +45,7 @@ class Armada(object): self.disable_update_pre = disable_update_pre self.disable_update_post = disable_update_post self.enable_chart_cleanup = enable_chart_cleanup + self.skip_pre_flight = skip_pre_flight self.dry_run = dry_run self.config = yaml.load(config) self.tiller = Tiller() @@ -37,15 +58,24 @@ class Armada(object): if chart_name == name: return chart, values + def pre_flight_checks(self): + for ch in self.config['armada']['charts']: + location = ch.get('chart').get('source').get('location') + ct_type = ch.get('chart').get('source').get('type') + + if ct_type == 'git' and not git.check_available_repo(location): + raise ValueError(str("Invalid Url Path: " + location)) + + if not self.tiller.tiller_status(): + raise Exception("Tiller Services is not Available") + + if not lint.valid_manifest(self.config): + raise Exception("Invalid Armada Manifest") + def sync(self): ''' Syncronize Helm with the Armada Config(s) ''' - def release_prefix(prefix, chart): - ''' - how to attach prefix to chart - ''' - return "{}-{}".format(prefix, chart) # extract known charts on tiller right now known_releases = self.tiller.list_charts() @@ -55,10 +85,16 @@ class Armada(object): LOG.debug("Release %s, Version %s found on tiller", release[0], release[1]) + if not self.skip_pre_flight: + LOG.info("Performing Checking Pre Flight Tasks") + self.pre_flight_checks() + else: + LOG.info("Skipping Pre flight Checks") + for entry in self.config['armada']['charts']: chart = dotify(entry['chart']) - values = entry['chart']['values'] + values = entry.get('chart').get('values', {}) pre_actions = {} post_actions = {} @@ -86,10 +122,12 @@ class Armada(object): installed_chart, installed_values = self.find_release_chart( known_releases, release_prefix(prefix, chart.release_name)) - if not self.disable_update_pre: + if not self.disable_update_pre and getattr(chart, 'upgrade', + False): pre_actions = getattr(chart.upgrade, 'pre', {}) - if not self.disable_update_post: + if not self.disable_update_post and getattr(chart, 'upgrade', + False): post_actions = getattr(chart.upgrade, 'post', {}) # show delta for both the chart templates and the chart values diff --git a/armada/chartbuilder.py b/armada/handlers/chartbuilder.py similarity index 86% rename from armada/chartbuilder.py rename to armada/handlers/chartbuilder.py index b6bca33b..c112a8d4 100644 --- a/armada/chartbuilder.py +++ b/armada/handlers/chartbuilder.py @@ -1,5 +1,20 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + import os import yaml +import logging from hapi.chart.template_pb2 import Template from hapi.chart.chart_pb2 import Chart @@ -7,9 +22,9 @@ from hapi.chart.metadata_pb2 import Metadata from hapi.chart.config_pb2 import Config from supermutes.dot import dotify -from logutil import LOG -from git import git_clone, source_cleanup +from ..utils.git import git_clone, source_cleanup +LOG = logging.getLogger(__name__) class ChartBuilder(object): ''' @@ -67,6 +82,9 @@ class ChartBuilder(object): return os.path.join(self._source_tmp_dir, self.chart.source.subpath) + if self.chart.source.type == 'local': + return os.path.join(self.chart.source.location, + self.chart.source.subpath) else: LOG.exception("Unknown source type %s for chart %s", @@ -77,7 +95,8 @@ class ChartBuilder(object): ''' Cleanup source ''' - source_cleanup(self._source_tmp_dir) + if self.chart.source.type == 'git': + source_cleanup(self._source_tmp_dir) def get_metadata(self): ''' diff --git a/armada/k8s.py b/armada/handlers/k8s.py similarity index 68% rename from armada/k8s.py rename to armada/handlers/k8s.py index 3372c729..80c3d042 100644 --- a/armada/k8s.py +++ b/armada/handlers/k8s.py @@ -1,7 +1,22 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + from kubernetes import client, config from kubernetes.client.rest import ApiException +import logging -from logutil import LOG +LOG = logging.getLogger(__name__) class K8s(object): ''' diff --git a/armada/tiller.py b/armada/handlers/tiller.py similarity index 91% rename from armada/tiller.py rename to armada/handlers/tiller.py index c9870619..221f5343 100644 --- a/armada/tiller.py +++ b/armada/handlers/tiller.py @@ -1,16 +1,34 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + import grpc +import logging + from hapi.services.tiller_pb2 import ReleaseServiceStub, ListReleasesRequest, \ InstallReleaseRequest, UpdateReleaseRequest, UninstallReleaseRequest from hapi.chart.config_pb2 import Config from k8s import K8s -from logutil import LOG +from ..utils.release import release_prefix TILLER_PORT = 44134 TILLER_VERSION = b'2.1.3' TILLER_TIMEOUT = 300 RELEASE_LIMIT = 64 +LOG = logging.getLogger(__name__) + class Tiller(object): ''' The Tiller class supports communication and requests to the Tiller Helm @@ -69,7 +87,7 @@ class Tiller(object): ''' return if tiller exist or not ''' - if self._get_tiller_ip: + if self._get_tiller_ip(): return True return False @@ -218,11 +236,6 @@ class Tiller(object): :result - will remove any chart that is not present in yaml ''' - def release_prefix(prefix, chart): - ''' - how to attach prefix to chart - ''' - return "{}-{}".format(prefix, chart["chart"]["release_name"]) valid_charts = [release_prefix(prefix, chart) for chart in charts] actual_charts = [x.name for x in self.list_releases()] diff --git a/armada/log.py b/armada/log.py new file mode 100644 index 00000000..6f1a7cb2 --- /dev/null +++ b/armada/log.py @@ -0,0 +1,84 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + +import os +import logging +import string +import sys + +if sys.version_info < (2, 7): + import functools + + @functools.wraps(logging.Formatter.format) + def new_format(self, record, string=string, + old_format=logging.Formatter.format): + if string.find is None: + string.find = str.find + return old_format(self, record) + logging.Formatter.format = new_format + + +class ColorFormatter(logging.Formatter): + LEVEL_COLORS = { + logging.DEBUG: '\033[00;32m', # GREEN + logging.INFO: '\033[00;36m', # CYAN + logging.WARN: '\033[01;33m', # BOLD YELLOW + logging.ERROR: '\033[01;31m', # BOLD RED + logging.CRITICAL: '\033[01;31m', # BOLD RED + } + + def format(self, record, Formatter=logging.Formatter): + # Hack to get last log line instead of exception on 2.6 + res = Formatter.format(self, record) # old-style class on 2.6 + return self.LEVEL_COLORS[record.levelno] + res + '\033[m' + + +def set_console_formatter(**formatter_kwargs): + formatter_kwargs.setdefault( + 'fmt', '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') + formatter_kwargs.setdefault('datefmt', '%m-%d %H:%M') + + root_logger = logging.getLogger('') + cliff_log = logging.getLogger('cliff') + stevedore_log = logging.getLogger('stevedore') + iso8601_log = logging.getLogger("iso8601") + + log_dir = os.path.expanduser('~/.armada') + if not os.path.exists(log_dir): + os.makedirs(log_dir) + + file_logger = logging.FileHandler(filename=str(log_dir + '/armada.log')) + root_logger.addHandler(file_logger) + + cliff_log.setLevel(logging.INFO) + stevedore_log.setLevel(logging.INFO) + iso8601_log.setLevel(logging.INFO) + + for handler in root_logger.handlers: + if handler.__class__ is logging.StreamHandler: # Skip subclasses + console_handler = handler + # Skip if not a tty (default ssh, redirect, ...) + isatty = getattr(handler.stream, 'isatty', None) + if isatty is None or not isatty(): + continue + break + else: + return # Didn't find any suitable StreamHandlers there + formatter = ColorFormatter(**formatter_kwargs) + console_handler.setFormatter(formatter) + + +def silence_iso8601(): + iso8601_logger = logging.getLogger('iso8601') + iso8601_logger.setLevel(logging.INFO) diff --git a/armada/logutil.py b/armada/logutil.py deleted file mode 100644 index 4eec84b6..00000000 --- a/armada/logutil.py +++ /dev/null @@ -1,20 +0,0 @@ - -import logging -from logging.handlers import SysLogHandler - -LOG = logging.getLogger('armada') -LOG_FORMAT = '%(asctime)s %(name)-12s %(levelname)-8s %(message)s' -LOG_DATE = '%m-%d %H:%M' - -def setup_logging(debug): - ''' - :params args - logging information arguments in cli - - various utilties to support logging - ''' - level = logging.DEBUG if debug else logging.INFO - logging.basicConfig(level=level, format=LOG_FORMAT, date_fmt=LOG_DATE) - handler = SysLogHandler(address='/dev/log') - syslog_formatter = logging.Formatter('%(name)s: %(levelname)s %(message)s') - handler.setFormatter(syslog_formatter) - LOG.addHandler(handler) diff --git a/armada/shell.py b/armada/shell.py new file mode 100644 index 00000000..22f55b20 --- /dev/null +++ b/armada/shell.py @@ -0,0 +1,45 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + +import sys + +from cliff import app +from cliff import commandmanager as cm + +import armada +from armada import log + +class ArmadaApp(app.App): + def __init__(self, **kwargs): + super(ArmadaApp, self).__init__( + description='Armada - Upgrade and deploy your charts', + version=armada.__version__, + command_manager=cm.CommandManager('armada'), + **kwargs) + + def build_option_parser(self, description, version, argparse_kwargs=None): + parser = super(ArmadaApp, self).build_option_parser( + description, version, argparse_kwargs) + return parser + + def configure_logging(self): + super(ArmadaApp, self).configure_logging() + log.set_console_formatter() + log.silence_iso8601() + + +def main(argv=None): + if argv is None: + argv = sys.argv[1:] + return ArmadaApp().run(argv) diff --git a/armada/utils/__init__.py b/armada/utils/__init__.py new file mode 100644 index 00000000..3a4dedd8 --- /dev/null +++ b/armada/utils/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 The Armada Authors. +# +# 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/armada/git.py b/armada/utils/git.py similarity index 58% rename from armada/git.py rename to armada/utils/git.py index e87c68ed..655776e4 100644 --- a/armada/git.py +++ b/armada/utils/git.py @@ -1,6 +1,9 @@ import pygit2 import tempfile import shutil +import requests + +HTTP_OK = 200 def git_clone(repo_url, branch='master'): ''' @@ -16,3 +19,14 @@ def source_cleanup(target_dir): Clean up source ''' shutil.rmtree(target_dir) + + +def check_available_repo(repo_url): + try: + resp = requests.get(repo_url.replace('git:', 'http:')) + if resp.status_code == HTTP_OK: + return True + + return False + except Exception: + return False diff --git a/armada/utils/lint.py b/armada/utils/lint.py new file mode 100644 index 00000000..33d2de48 --- /dev/null +++ b/armada/utils/lint.py @@ -0,0 +1,23 @@ + +ARMADA_DEFINITION = 'armada' +RELEASE_PREFIX = 'release_prefix' +CHARTS_DEFINITION = 'charts' + + +def valid_manifest(config): + if not (isinstance(config.get(ARMADA_DEFINITION, None), dict)): + raise Exception("Did not declare armada object") + + armada_config = config.get('armada') + + if not isinstance(armada_config.get(RELEASE_PREFIX), basestring): + raise Exception('Release needs to be a string') + + if not isinstance(armada_config.get(CHARTS_DEFINITION), list): + raise Exception('Check yaml invalid chart definition must be array') + + for chart in armada_config.get('charts', []): + if not isinstance(chart.get('chart').get('name'), basestring): + raise Exception('Chart name needs to be a string') + + return True diff --git a/armada/utils/release.py b/armada/utils/release.py new file mode 100644 index 00000000..3b52c440 --- /dev/null +++ b/armada/utils/release.py @@ -0,0 +1,19 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + +def release_prefix(prefix, chart): + ''' + how to attach prefix to chart + ''' + return "{}-{}".format(prefix, chart) diff --git a/armada/version.py b/armada/version.py new file mode 100644 index 00000000..edcec8e2 --- /dev/null +++ b/armada/version.py @@ -0,0 +1,23 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + +__all__ = ['__version__'] + +import pbr.version + +version_info = pbr.version.VersionInfo('armada') +try: + __version__ = version_info.version_string() +except AttributeError: + __version__ = None diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..51dccea5 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# +# Armada documentation build configuration file, created by +# sphinx-quickstart on Wed May 3 10:39:15 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +# templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Armada' +copyright = u'2017, Armada Team' +author = u'Armada Team' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'0.2.0' +# The full version, including alpha/beta/rc tags. +release = u'0.2.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ['_static'] + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Armadadoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'Armada.tex', u'Armada Documentation', + u'Armada Team', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'armada', u'Armada Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'Armada', u'Armada Documentation', + author, 'Armada', 'One line description of project.', + 'Miscellaneous'), +] diff --git a/docs/development/getting-started.rst b/docs/source/development/getting-started.rst similarity index 78% rename from docs/development/getting-started.rst rename to docs/source/development/getting-started.rst index ff4f2d03..534b7352 100644 --- a/docs/development/getting-started.rst +++ b/docs/source/development/getting-started.rst @@ -5,11 +5,22 @@ Development Docker ###### -To use this container, use these simple instructions: +To use the docker containter to develop: + +1. Fork the [repo](http://github.com/att-comdev/armada) +2. After making changes push to repo and build from forked repo .. code-block:: bash - docker run quay.io/attcomdev/armada:latest + export repo="https://github.com//armada.git" + export branch="" + docker build . -p 8000:8000 -v ${HOME}/.kube/config:/root/.kube/config -t quay.io/attcomdev/armada:latest --build-arg REPO=$repo --build-arg VERSION=$branch + +.. note:: + + The first build will take a little while. Afterwards the it will much faster + +3. EZPZ :) Virtualenv ########## diff --git a/docs/source/development/index.rst b/docs/source/development/index.rst new file mode 100644 index 00000000..d4778dcc --- /dev/null +++ b/docs/source/development/index.rst @@ -0,0 +1,13 @@ +.. Armada documentation master file, created by + sphinx-quickstart on Wed May 3 10:39:15 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Developers Guide +================ + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + getting-started.rst diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..3bc615ea --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,24 @@ +.. Armada documentation master file, created by + sphinx-quickstart on Wed May 3 10:39:15 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Armada's documentation! +================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + readme + development/index + operations/index + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/operations/guide-build-armada-yaml.rst b/docs/source/operations/guide-build-armada-yaml.rst new file mode 100644 index 00000000..0edff2c4 --- /dev/null +++ b/docs/source/operations/guide-build-armada-yaml.rst @@ -0,0 +1,171 @@ +Armada - Making Your First Armada Yaml +====================================== + +Keywords +-------- + ++---------------------+--------+----------------------+ +| keyword | type | action | ++=====================+========+======================+ +| ``armada`` | object | will | +| | | define an | +| | | armada | +| | | release | ++---------------------+--------+----------------------+ +| ``release_prefix`` | string | will tag | +| | | all | +| | | charts | +| | | released | +| | | by the | +| | | yaml in | +| | | order to | +| | | manage it | +| | | the | +| | | lifecycle | +| | | of charts | ++---------------------+--------+----------------------+ +| ``charts`` | array | will | +| | | store the | +| | | definitio | +| | | ns | +| | | of all | +| | | your | +| | | charts | ++---------------------+--------+----------------------+ +| ``chart`` | object | will | +| | | define | +| | | what your | +| | | chart | +| | | | ++---------------------+--------+----------------------+ + +Defining a chart +~~~~~~~~~~~~~~~~ + +To define your charts is not any different than helm. we do provide some +post/pre actions that will help us manage our charts better. + +Behavior +^^^^^^^^ + +1. will check if chart exists + + 1. if it does not exist + + - we will install the chart + + 2. if exist then + + - armada will check if there are any differences in the charts + - if the charts are different then it will execute an upgrade + - else it will not perform any actions + +Chart Keywords +^^^^^^^^^^^^^^ + +Chart +^^^^^ + ++-----------------+----------+------------------------------------------------------------------------+ +| keyword | type | action | ++=================+==========+========================================================================+ +| name | string | will be the name fo the chart | ++-----------------+----------+------------------------------------------------------------------------+ +| release\_name | string | will be the name of the release | ++-----------------+----------+------------------------------------------------------------------------+ +| namespace | string | will place your chart in define namespace | ++-----------------+----------+------------------------------------------------------------------------+ +| install | object | will install the chart into your kubernetes cluster | ++-----------------+----------+------------------------------------------------------------------------+ +| update | object | will updated any chart managed by the armada yaml | ++-----------------+----------+------------------------------------------------------------------------+ +| values | object | will override any default values in the charts | ++-----------------+----------+------------------------------------------------------------------------+ +| source | object | will provide a path to a ``git repo`` or ``local dir`` deploy chart. | ++-----------------+----------+------------------------------------------------------------------------+ +| dependencies | object | will reference any chart deps before install | ++-----------------+----------+------------------------------------------------------------------------+ + +Source +^^^^^^ + ++-------------+----------+---------------------------------------------------------------+ +| keyword | type | action | ++=============+==========+===============================================================+ +| type | string | will be the source to build the charts ``git`` or ``local`` | ++-------------+----------+---------------------------------------------------------------+ +| location | string | will be the ``url`` or ``path`` to the charts | ++-------------+----------+---------------------------------------------------------------+ +| subpath | string | will specify the path to target chart | ++-------------+----------+---------------------------------------------------------------+ +| reference | string | will be the branch of the repo | ++-------------+----------+---------------------------------------------------------------+ + +.. note:: + + You can use references in order to build your charts, this will reduce the size of the chart definition will show example in multichart below + +Simple Example +~~~~~~~~~~~~~~ + +:: + + armada: + release_prefix: "my_armada" + charts: + - chart: &cockroach + name: cockroach + release_name: cockroach + namespace: db + install: + no_hooks: false + values: + Replicas: 1 + source: + type: git + location: git://github.com/kubernetes/charts/ + subpath: stable/cockroachdb + reference: master + dependencies: [] + +Multichart Example +~~~~~~~~~~~~~~~~~~ + +:: + + armada: + release_prefix: "my_armada" + charts: + - chart: &common + name: common + release_name: null + namespace: null + values: {} + source: + type: git + location: git://github.com/kubernetes/charts/ + subpath: common + reference: master + dependencies: [] + + - chart: &cockroach + name: cockroach + release_name: cockroach + namespace: db + install: + no_hooks: false + values: + Replicas: 1 + source: + type: git + location: git://github.com/kubernetes/charts/ + subpath: stable/cockroachdb + reference: master + dependencies: + - *common + +References +~~~~~~~~~~ + +For working examples please check the examples in our repo +`here `__ diff --git a/docs/source/operations/guide-troubleshooting.rst b/docs/source/operations/guide-troubleshooting.rst new file mode 100644 index 00000000..1a5b3a31 --- /dev/null +++ b/docs/source/operations/guide-troubleshooting.rst @@ -0,0 +1,53 @@ +Armada - Troubleshooting +======================== + +Debugging Pods +-------------- + +Before starting to work in armada we need to check that the tiller pod is active and running. + +.. code:: bash + + kubectl get pods -n kube-system | grep tiller + +.. code:: bash + + armada tiller --status + +Checking Logs +------------- + +In order to check the logs the logs file will be in `~/.armada` directory. + +When running Armada in the container you can execute docker logs to retrieve logs + +.. code:: bash + + docker logs [container-name | container-id] + + +Working with SSL +---------------- + +You might run into SSL error with armada if you are not using the correct +versions of SSL. + +Debugging Checklist: + +1. python -c "import ssl; print ssl.OPENSSL_VERSION" + + If the version that appers is less than 1.0 then problems will occur, please + update to current or use our docker container solve this issue + +2. check your urllib3 version, you could run into urllib3 issues. older versions + of this lib can cause SSL errors run ``pip install --upgrade urllib3`` and it + should solve this issue + + + +Issue +----- + +If the issue that you are having does not appear here please check the aramda +issues [here](https://github.com/att-comdev/armada/issues). If the issue does +not exist, please create an issue. diff --git a/docs/source/operations/index.rst b/docs/source/operations/index.rst new file mode 100644 index 00000000..33c2b6a5 --- /dev/null +++ b/docs/source/operations/index.rst @@ -0,0 +1,14 @@ +.. Armada documentation master file, created by + sphinx-quickstart on Wed May 3 10:39:15 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Operations Guide +================ + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + guide-troubleshooting.rst + guide-build-armada-yaml.rst diff --git a/docs/source/readme.rst b/docs/source/readme.rst new file mode 100644 index 00000000..a6210d3d --- /dev/null +++ b/docs/source/readme.rst @@ -0,0 +1 @@ +.. include:: ../../README.rst diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 00000000..b296683e --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +CMD="armada" +PORT="8000" + +set -e + +if [ "$1" = 'server' ]; then + gunicorn server:api -b :$PORT +fi + +if [ "$1" = 'tiller' ] || [ "$1" = 'apply' ]; then + exec $CMD "$@" +fi + +exec "$@" diff --git a/requirements.txt b/requirements.txt index d84c316e..0d43195f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,12 @@ kubernetes==1.0.0 protobuf==3.2.0 PyYAML==3.12 supermutes==0.2.5 +urllib3==1.21.1 +# API falcon==1.1.0 gunicorn==19.7.1 + +# CLI + +cliff==2.7.0 diff --git a/scripts/armada b/scripts/armada deleted file mode 100755 index e295f853..00000000 --- a/scripts/armada +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python - -import sys -import argparse -from armada.armada import Armada -from armada.logutil import LOG, setup_logging - -DESCRIPTION = "Armada" - -def parse_args(): - - ap = argparse.ArgumentParser(description=DESCRIPTION) - ap.add_argument('-c', '--config', action='store', required=True, - help='Path to YAML File or Directory') - ap.add_argument('--debug', action='store_true', default=False, - required=False, help='Enable debug logging') - ap.add_argument('--enable-chart-cleanup', action='store_true', - default=False, required=False, help='Clean up enviroment') - ap.add_argument('-d', '--dry-run', action='store_true', default=False, - required=False, help='Enable dry-run flag on all Tiller' - 'Calls') - ap.add_argument('--disable-update-pre', action='store_true', default=False, - required=False, help='Disable pre update actions') - ap.add_argument('--disable-update-post', action='store_true', - default=False, required=False, - help='Disable post update actions') - - return ap.parse_args() - - -def run(args): - - armada = Armada(open(args.config).read(), - args.disable_update_pre, - args.disable_update_post, - args.enable_chart_cleanup, - args.dry_run) - armada.sync() - - -if __name__ == '__main__': - - args = parse_args() - setup_logging(args.debug) - - try: - run(args) - sys.exit(0) - except Exception as err: - LOG.exception(err) - sys.exit(1) diff --git a/scripts/libgit2_docker.sh b/scripts/libgit2_docker.sh deleted file mode 100644 index e49a66b5..00000000 --- a/scripts/libgit2_docker.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# Ubuntu 16.04 Install only - -apt install git cmake make -y -apt-get install -y python-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev libssh2-1 libgit2-dev python-pip libgit2-24 -apt-get install -y pkg-config libssh2-1-dev libhttp-parser-dev libssl-dev libz-dev - -LIBGIT_VERSION='0.25.0' - -wget https://github.com/libgit2/libgit2/archive/v${LIBGIT_VERSION}.tar.gz -tar xzf v${LIBGIT_VERSION}.tar.gz -cd libgit2-${LIBGIT_VERSION}/ -cmake . -make -make install -pip install pygit2==${LIBGIT_VERSION} -ldconfig diff --git a/server.py b/server.py index db8a0163..f34a79c2 100644 --- a/server.py +++ b/server.py @@ -1,11 +1,28 @@ +# Copyright 2017 The Armada Authors. +# +# 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. +# + +import logging import falcon import json from falcon import HTTP_200 -from armada.tiller import Tiller as tillerHandler -from armada.armada import Armada as armadaHandler -from armada.logutil import setup_logging +from armada.handlers.tiller import Tiller as tillerHandler +from armada.handlers.armada import Armada as armadaHandler + +LOG = logging.getLogger(__name__) class Tiller(object): ''' @@ -32,7 +49,6 @@ class Armada(object): def on_post(self, req, resp): armada = armadaHandler(req.stream.read()) - print armada.tiller.k8s.get_namespace_pod() armada.sync() resp.data = json.dumps({'message': 'Success'}) @@ -51,6 +67,3 @@ url_routes = ( for route, service in url_routes: api.add_route(route, service) - - -setup_logging(False) diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..f660928b --- /dev/null +++ b/setup.cfg @@ -0,0 +1,47 @@ +[metadata] +name = armada +summary = tool for managing multiple chart ocherstartion lifecycle +description-file = README.rst + +author = armada team +home-page = http://armada-helm.readthedocs.io/en/latest/ +classifier = + Intended Audience :: Information Technology + Intended Audience :: System Administrators + License :: OSI Approved :: Apache Software License + Operating System :: POSIX :: Linux + Programming Language :: Python + Programming Language :: Python :: 2 + Programming Language :: Python :: 2.7 + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.5 + +[files] +packages = + armada + armada.cli + armada.api + armada.handlers + hapi + hapi.chart + hapi.release + hapi.services + hapi.version + +[build_sphinx] +source-dir = docs/source +build-dir = docs/build +all_files = 1 + +[entry_points] +console_scripts = + armada = armada.shell:main +armada = + apply = armada.cli.apply:ApplyChartsCommand + tiller = armada.cli.tiller:TillerServerCommand + +[pbr] +warnerrors = True + +[wheel] +universal = 1 diff --git a/setup.py b/setup.py index 9724e9bb..b9d5367a 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ -from setuptools import setup from setuptools.command.test import test as TestCommand import sys +import setuptools class Tox(TestCommand): """Runs Tox comands""" @@ -17,15 +17,11 @@ class Tox(TestCommand): sys.exit(errcode) -setup( - name='armada', - version='0.1.0', - description='Armada Helm Orchestrator', - packages=['armada', - 'hapi', - 'hapi.chart', - 'hapi.release', - 'hapi.services', - 'hapi.version'], - scripts=['scripts/armada'] -) +try: + import multiprocessing # noqa +except ImportError: + pass + +setuptools.setup( + setup_requires=['pbr>=2.0.0'], + pbr=True) diff --git a/test-requirements.txt b/test-requirements.txt index 90185032..35e90679 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,2 +1,3 @@ flake8==3.3.0 -tox==2.6.0 +tox +Sphinx diff --git a/scripts/libgit2.sh b/tools/libgit2.sh old mode 100644 new mode 100755 similarity index 100% rename from scripts/libgit2.sh rename to tools/libgit2.sh diff --git a/tox.ini b/tox.ini index 946d4f05..17b0907f 100644 --- a/tox.ini +++ b/tox.ini @@ -7,13 +7,15 @@ deps= -r{toxinidir}/test-requirements.txt setenv= PYTHONWARNINGS=all -commands = - sh {toxinidir}/scripts/libgit2.sh [testenv:ubuntu] commands = sh {toxinidir}/scripts/libgit2.sh +[testenv:docs] +commands = python setup.py build_sphinx + + [flake8] ignore=E302,H306 exclude= libgit2-0.24.0, .git, .idea, .tox, *.egg-info, *.eggs, bin, dist, hapi