diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 9417f86..0000000 --- a/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -*.py[cod] - -# C extensions -*.so - -# Packages -*.egg -*.egg-info -dist -build -.eggs -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -cover -.tox -nosetests.xml -.testrepository -.venv - -# Translations -*.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - -# Complexity -output/*.html -output/*/index.html - -# Sphinx -doc/build - -# oslo-config-generator -etc/*.sample - -# pbr generates these -AUTHORS -ChangeLog - -# Editors -*~ -.*.swp -.*sw? - -# Vagrant -.vagrant -vagrant/Vagrantfile.custom -vagrant/vagrantkey* - -# generated openrc -openrc - -# tests -tests/.cache/* - diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 68c771a..0000000 --- a/LICENSE +++ /dev/null @@ -1,176 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..86e34d6 --- /dev/null +++ b/README.rst @@ -0,0 +1,10 @@ +This project is no longer maintained. + +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". + +For any further questions, please email +openstack-discuss@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/docker/etcd/Dockerfile.j2 b/docker/etcd/Dockerfile.j2 deleted file mode 100644 index d85da63..0000000 --- a/docker/etcd/Dockerfile.j2 +++ /dev/null @@ -1,9 +0,0 @@ -FROM {{ image_spec("base-tools") }} -MAINTAINER {{ maintainer }} - -RUN curl -L -o etcd-{{ etcd_version }}-linux-amd64.tar.gz https://github.com/coreos/etcd/releases/download/{{ etcd_version }}/etcd-{{ etcd_version }}-linux-amd64.tar.gz \ - && tar -zxvf etcd-{{ etcd_version }}-linux-amd64.tar.gz \ - && mv etcd-{{ etcd_version }}-linux-amd64/etcd /usr/local/bin \ - && mkdir -p /var/etcd/ \ - && rm -r etcd-{{ etcd_version }}-linux-amd64 \ - && rm etcd-{{ etcd_version }}-linux-amd64.tar.gz diff --git a/service/etcd.yaml b/service/etcd.yaml deleted file mode 100644 index e1707bd..0000000 --- a/service/etcd.yaml +++ /dev/null @@ -1,38 +0,0 @@ -dsl_version: 0.4.0 -service: - name: etcd - kind: StatefulSet - ports: - - {{ etcd.client_port }} - - {{ etcd.server_port }} - annotations: - service: - prometheus.io/port: "{{ etcd.client_port.cont }}" - prometheus.io/scrape: "true" - containers: - - name: etcd - image: etcd - daemon: - command: /opt/ccp/bin/entrypoint.py - files: - - entrypoint - # {% if etcd.tls.enabled %} - - server_certificate - - server_key - # {% endif %} - -files: - entrypoint: - path: /opt/ccp/bin/entrypoint.py - content: entrypoint.py - perm: "0755" -# {% if etcd.tls.enabled %} - server_certificate: - path: /opt/ccp/etc/tls/etcd_server_certificate.pem - content: server.pem.j2 - perm: "0644" - server_key: - path: /opt/ccp/etc/tls/etcd_server_key.pem - content: server-key.pem.j2 - perm: "0644" -# {% endif %} diff --git a/service/files/defaults.yaml b/service/files/defaults.yaml deleted file mode 100644 index ae53c4d..0000000 --- a/service/files/defaults.yaml +++ /dev/null @@ -1,17 +0,0 @@ -configs: - etcd: - connection_attempts: 20 - connection_delay: 5 - client_port: - cont: 2379 - server_port: - cont: 2380 - tls: - enabled: true - token: cluster - additional_arguments: - election-timeout: 5000 - heartbeat-interval: 250 - -versions: - etcd_version: v3.0.12 diff --git a/service/files/entrypoint.py b/service/files/entrypoint.py deleted file mode 100644 index e8462e8..0000000 --- a/service/files/entrypoint.py +++ /dev/null @@ -1,224 +0,0 @@ -#!/usr/bin/env python - -import functools -import json -import logging -import requests -import socket -import subprocess -import time -import urlparse - -from requests.exceptions import RequestException, ConnectionError -LOG_DATEFMT = "%Y-%m-%d %H:%M:%S" -LOG_FORMAT = "%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s" -logging.basicConfig(format=LOG_FORMAT, - datefmt=LOG_DATEFMT, - level=logging.DEBUG) -LOG = logging.getLogger(__name__) - -GLOBALS_PATH = '/etc/ccp/globals/globals.json' -GLOBALS_SECRETS_PATH = '/etc/ccp/global-secrets/global-secrets.json' - -def retry(f): - @functools.wraps(f) - def wrap(*args, **kwargs): - attempts = config.connection_attempts - delay = config.connection_delay - while attempts > 1: - try: - return f(*args, **kwargs) - except (RequestException, ConnectionError) as err: - LOG.warning('Retrying in %d seconds because of %s', delay, err) - time.sleep(delay) - attempts -= 1 - return f(*args, **kwargs) - return wrap - - -def merge_configs(variables, new_config): - for k, v in new_config.items(): - if k not in variables: - variables[k] = v - continue - if isinstance(v, dict) and isinstance(variables[k], dict): - merge_configs(variables[k], v) - else: - variables[k] = v - - -class Configuration(): - def __init__(self): - values = {} - with open(GLOBALS_PATH) as f: - global_conf = json.load(f) - with open(GLOBALS_SECRETS_PATH) as f: - secrets = json.load(f) - merge_configs(global_conf, secrets) - for key in ['etcd', 'namespace', 'security', 'cluster_domain']: - values[key] = global_conf[key] - hostname = socket.gethostname() - ipaddr = socket.gethostbyname(hostname) - self.etcd_binary = '/usr/local/bin/etcd' - self.connection_delay = 2 - self.connection_attempts = 5 - self.client_port = int(values['etcd']['client_port']['cont']) - self.server_port = int(values['etcd']['server_port']['cont']) - self.tls = values['etcd']['tls']['enabled'] - self.token = values['etcd']['token'] - self.namespace = values['namespace'] - self.cluster_domain = values['cluster_domain'] - self.api_version = 'v2' - if self.tls: - self.host_template = 'https://%s:%d' - self.cert_file = '/opt/ccp/etc/tls/etcd_server_certificate.pem' - self.key_file = '/opt/ccp/etc/tls/etcd_server_key.pem' - self.ca_file = '/opt/ccp/etc/tls/ca.pem' - self.verify_connectivity = self.ca_file - else: - self.host_template = 'http://%s:%d' - self.verify_connectivity = False - fqdn_template = "%s.%s.svc.%s" - svc = fqdn_template % ('etcd', self.namespace, self.cluster_domain) - # Represents fqdn service endoint for etcd - self.service = self.host_template % (svc, self.client_port) - members_endpoint = '%s/members/' % self.api_version - # URL to query when accessing etcd members api - self.members_api = urlparse.urljoin(self.service, members_endpoint) - # When joining etcd cluster, members list is special: - # =,=,... - self.name = "%s.%s" % (hostname, svc) - self.peer_url = self.host_template % (ipaddr, self.server_port) - self.member_name = "%s=%s" % (self.name, self.peer_url) - self.arguments = values.get('etcd').get('additional_arguments', None) - - -def start_etcd(config, bootstrap=False, initial_members=None): - name = config.name - client_port = config.client_port - server_port = config.server_port - client_host = config.host_template % (name, client_port) - server_host = config.host_template % (name, server_port) - if config.tls: - # We add insecure listener for checks - insecure_listener = ",http://%s:%s" % ('127.0.0.1', client_port) - else: - insecure_listener = "" - args = ['--name=%s' % name, - '--listen-peer-urls=%s' % server_host, - '--listen-client-urls=%s' % client_host + insecure_listener, - '--advertise-client-urls=%s' % client_host, - '--initial-advertise-peer-urls=%s' % server_host, - '--initial-cluster-token=%s' % config.token] - if config.tls: - args += ['--peer-auto-tls'] - args += ['--cert-file=%s' % config.cert_file] - args += ['--key-file=%s' % config.key_file] - if bootstrap: - args += ["--initial-cluster=%s=%s" % (name, server_host)] - if initial_members: - args += ["--initial-cluster-state=existing", - "--initial-cluster=%s" % initial_members] - if config.arguments: - LOG.debug("Additional arguments are %s" % config.arguments) - custom = ["--%s=%s" % (k,v) for k,v in config.arguments.iteritems()] - args += custom - cmd = [config.etcd_binary] + args - LOG.info("Launching etcd with %s" % cmd) - subprocess.check_call(cmd, shell=False) - - -@retry -def _add_etcd_member(members_api, peer_url): - headers = {'content-type': 'application/json'} - data = {'peerURLs': [peer_url]} - verify = config.verify_connectivity - r = requests.post(members_api, json=data, headers=headers, verify=verify) - # https://coreos.com/etcd/docs/latest/v2/members_api.html - if r.status_code == 201: - return peer_url - elif r.status_code == 500: - # Request failed, but might be processed later, not sure how to handle - LOG.debug('Etcd cluster returned 500, might be busy...') - r.raise_for_status() - else: - r.raise_for_status() - - -@retry -def _delete_etcd_member(members_api, name): - # HTTP API needs id of the member to delete it - # So first we get member id, then we delete it - 2 calls total. - peers = _get_etcd_members(members_api) - _id = _get_etcd_member_id(peers, name) - LOG.debug("Deleting %s with id %s from etcd cluster..." % (name, _id)) - url = urlparse.urljoin(members_api, _id) - verify = config.verify_connectivity - r = requests.delete(url, verify=verify) - if r.status_code == 204: - return [p for p in peers if p['name'] != name] - else: - LOG.debug("Delete failed with error %i", r.status_code) - r.raise_for_status() - - -@retry -def _get_etcd_members(members_api): - verify = config.verify_connectivity - r = requests.get(members_api, verify=verify) - if r.status_code == 200: - peers = r.json()['members'] - return peers - else: - r.raise_for_status() - - -def _etcd_members_as_string(peers): - # =,=,... - l = [] - for m in peers: - if m['name']: - l.append("%s=%s" % (m['name'], m['peerURLs'][0])) - return ",".join(l) - - -def _get_etcd_member_id(peers, name): - # Get member id from peers list - members = [p['id'] for p in peers if p['name'] == name] - if members: - return members[0] - else: - return None - - -if __name__ == "__main__": - config = Configuration() - etcd_members_api = config.members_api - try: - # The only reliable way to determine if etcd cluster exists is to query - # service. - peers = _get_etcd_members(etcd_members_api) - members = _etcd_members_as_string(peers) - except ConnectionError: - LOG.debug("No one seems to be alive...") - members = "" - if not members: - # TODO(amnk): add recovery from complete disaster (e.g. restore data - # from data-dir if it is available - LOG.debug("I'm a leader, starting...") - start_etcd(config, bootstrap=True) - else: - if config.name in members: - # If we find our hostname in existing members, we are recovering - # from some failure. Since we cannot guarantee having all needed - # data on new node, we need to delete ourselve before joining. - LOG.debug("Found myself in members...") - new_peers = _delete_etcd_member(etcd_members_api, config.name) - new_members = _etcd_members_as_string(new_peers) - else: - new_members = members - LOG.debug("Adding myself to cluster %s..." % etcd_members_api) - _add_etcd_member(etcd_members_api, config.peer_url) - all_members = new_members + ',' + config.member_name - LOG.debug("Joining %s" % members) - start_etcd(config, initial_members=all_members) diff --git a/service/files/server-key.pem.j2 b/service/files/server-key.pem.j2 deleted file mode 100644 index 70cf751..0000000 --- a/service/files/server-key.pem.j2 +++ /dev/null @@ -1 +0,0 @@ -{{ security.tls.server_key }} diff --git a/service/files/server.pem.j2 b/service/files/server.pem.j2 deleted file mode 100644 index 8abc152..0000000 --- a/service/files/server.pem.j2 +++ /dev/null @@ -1 +0,0 @@ -{{ security.tls.server_cert }} diff --git a/tools/yamllint.sh b/tools/yamllint.sh deleted file mode 100755 index 6e84445..0000000 --- a/tools/yamllint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -set -ex - -workdir=$(dirname $0) -yamllint -c $workdir/yamllint.yaml $(find . -not -path '*/\.*' -type f -name '*.yaml') diff --git a/tools/yamllint.yaml b/tools/yamllint.yaml deleted file mode 100644 index 6c2e4a7..0000000 --- a/tools/yamllint.yaml +++ /dev/null @@ -1,21 +0,0 @@ -extends: default - -rules: - braces: - max-spaces-inside: 1 - comments: - level: error - comments-indentation: - level: warning - document-end: - present: no - document-start: - level: error - present: no - empty-lines: - max: 1 - max-start: 0 - max-end: 0 - line-length: - level: warning - max: 120 diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 0881beb..0000000 --- a/tox.ini +++ /dev/null @@ -1,12 +0,0 @@ -[tox] -minversion = 1.6 -envlist = linters -skipsdist = True - -[testenv:linters] -deps = yamllint -commands = - {toxinidir}/tools/yamllint.sh - -[testenv:venv] -commands = {posargs}