From fe9dcb9fdef3da958c2ce30d7f27df4b72e974bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Piotrowski?= Date: Fri, 5 Feb 2016 13:44:21 +0100 Subject: [PATCH] Allow fuel-setup-network to configure repositories This means it is fuel-setup-network no more and has been renamed to more general fuel-setup. For the same reason MasterNode became a top-level class that is expanded by particular commands with required methods. Script requires now '-n' argument that specifies environment name. - 'network' works as old fuel-setup-network did. - 'repos' expects MOS_REPOS and UBUNTU_LATEST environment variables to be set in the same way fuel-qa does it - because user might want to run both of them, running verify_network has been split into its own command The 'version' property of MasterNode requires requests library. All other dependencies has been bumped to latest releases. Change-Id: I9d0f5ba0a17b5821f8fb86b6a089c7d8adf802e1 --- contrib/fuel-setup-network/requirements.txt | 5 - .../fuel-setup.py} | 114 ++++++++++++++---- contrib/fuel-setup/requirements.txt | 8 ++ 3 files changed, 99 insertions(+), 28 deletions(-) delete mode 100644 contrib/fuel-setup-network/requirements.txt rename contrib/{fuel-setup-network/fuel-setup-network.py => fuel-setup/fuel-setup.py} (62%) create mode 100644 contrib/fuel-setup/requirements.txt diff --git a/contrib/fuel-setup-network/requirements.txt b/contrib/fuel-setup-network/requirements.txt deleted file mode 100644 index f66e35a..0000000 --- a/contrib/fuel-setup-network/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -ecdsa>=0.13 -paramiko>=1.16.0 -psycopg2>=2.6.1 -pycrypto>=2.6.1 -py2-ipaddress>=3.4.1; python_version < '3' diff --git a/contrib/fuel-setup-network/fuel-setup-network.py b/contrib/fuel-setup/fuel-setup.py similarity index 62% rename from contrib/fuel-setup-network/fuel-setup-network.py rename to contrib/fuel-setup/fuel-setup.py index 8f29ac1..873f95f 100755 --- a/contrib/fuel-setup-network/fuel-setup-network.py +++ b/contrib/fuel-setup/fuel-setup.py @@ -13,14 +13,19 @@ # 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 __future__ import print_function + import argparse from ipaddress import ip_network import os import shutil +import sys import tempfile import paramiko import psycopg2 +import requests import yaml @@ -89,28 +94,40 @@ class MasterNode(object): 'Exit code: {exit_code}.') raise RuntimeError(error.format(cmd=command, exit_code=exit_code)) - def download(self, env_id=1): - command = self.command.format(subcommand='network', env_id=env_id, + def download(self, subcommand, env_id=1): + command = self.command.format(subcommand=subcommand, env_id=env_id, action='--download') self.__exec(command) - yamlfile = 'network_{}.yaml'.format(env_id) + yamlfile = '{}_{}.yaml'.format(subcommand, env_id) src = os.path.join('/root', yamlfile) dest = os.path.join(self.tmpdir, yamlfile) self.sftp.get(src, dest) - def upload(self, env_id=1): - yamlfile = 'network_{}.yaml'.format(env_id) + def upload(self, subcommand, env_id=1): + yamlfile = '{}_{}.yaml'.format(subcommand, env_id) src = os.path.join(self.tmpdir, yamlfile) dest = os.path.join('/root', yamlfile) self.sftp.put(src, dest) - command = self.command.format(subcommand='network', env_id=env_id, + command = self.command.format(subcommand=subcommand, env_id=env_id, action='--upload') self.__exec(command) + def verify(self, env_id=1): + command = self.command.format(subcommand='network', env_id=env_id, + action='--verify') + self.__exec(command) + + def close(self): + self.sftp.close() + self.transport.close() + shutil.rmtree(self.tmpdir) + + +class MasterNodeNetwork(MasterNode): def update_yaml(self, networks, yamlfile): fuel_networks = frozenset(['public', 'management', 'storage', 'private']) @@ -147,38 +164,89 @@ class MasterNode(object): network['ip_ranges'] = [iprange] with open(yamlfile, 'w') as f: - yaml.safe_dump(cluster, f, default_flow_style=False) + yaml.safe_dump(cluster, f) def update(self, env_id, networks): - yamlfile = os.path.join(self.tmpdir, 'network_{}.yaml'.format(env_id)) + subcommand = 'network' + yamlfile = os.path.join(self.tmpdir, '{}_{}.yaml'.format(subcommand, + env_id)) - self.download(env_id) + self.download(subcommand, env_id) self.update_yaml(networks, yamlfile) - self.upload(env_id) - self.verify(env_id) + self.upload(subcommand, env_id) - def verify(self, env_id=1): - command = self.command.format(subcommand='network', env_id=env_id, - action='--verify') - self.__exec(command) - def close(self): - self.sftp.close() - self.transport.close() - shutil.rmtree(self.tmpdir) +class MasterNodeRepo(MasterNode): + def __init__(self, ipaddress, port=22, username='root', password='r00tme', + repo_ubuntu=False, repo_mos=False): + super(MasterNodeRepo, self).__init__(ipaddress, port, + username, password) + self.repo_ubuntu = os.environ.get('UBUNTU_LATEST', False) + self.repo_mos = os.environ.get('MOS_REPOS', False) + + if self.repo_mos: + version = requests.get( + 'http://{}:8000/api/v1/version'.format(ipaddress) + ).json()['release'] + self.repo_mos = '{}/ubuntu/{}'.format(self.repo_mos, version) + + def update_yaml(self, yamlfile, repo_ubuntu, repo_mos): + with open(yamlfile, 'r') as f: + settings = yaml.safe_load(f) + + for repo in settings['editable']['repo_setup']['repos']['value']: + if repo_ubuntu and repo['name'].startswith('ubuntu'): + repo['uri'] = repo_ubuntu + + if repo_mos and repo['name'].startswith('mos'): + repo['uri'] = repo_mos + + with open(yamlfile, 'w') as f: + yaml.safe_dump(settings, f) + + def update(self, env_id, repo_ubuntu=None, repo_mos=None): + subcommand = 'settings' + yamlfile = os.path.join(self.tmpdir, '{}_{}.yaml'.format(subcommand, + env_id)) + + if repo_ubuntu is None: + repo_ubuntu = self.repo_ubuntu + + if repo_mos is None: + repo_mos = self.repo_mos + + self.download(subcommand, env_id) + self.update_yaml(yamlfile, repo_ubuntu, repo_mos) + self.upload(subcommand, env_id) if __name__ == '__main__': + action_choices = ['network', 'repos', 'verify'] + parser = argparse.ArgumentParser() - parser.add_argument('environment_name', + parser.add_argument('action', + help='available commands', + choices=action_choices) + parser.add_argument('-n', '--env', help='name of the environment to configure') parser.add_argument('-i', '--id', default='1', help='ID of the cluster which network should be setup') args = parser.parse_args() - networks = get_env_networks(args.environment_name) + networks = get_env_networks(args.env) master_node_address = cidr_to_iprange(networks['admin'], start=2)[0] - master_node = MasterNode(master_node_address) - master_node.update(args.id, networks) + if args.action == 'network': + master_node = MasterNodeNetwork(master_node_address) + master_node.update(args.id, networks) + elif args.action == 'repos': + master_node = MasterNodeRepo(master_node_address) + master_node.update(args.id) + elif args.action == 'verify': + master_node = MasterNode(master_node_address) + master_node.verify(args.id) + else: + print('Unknown action given', file=sys.stderr) + sys.exit(1) + master_node.close() diff --git a/contrib/fuel-setup/requirements.txt b/contrib/fuel-setup/requirements.txt new file mode 100644 index 0000000..ea9e53e --- /dev/null +++ b/contrib/fuel-setup/requirements.txt @@ -0,0 +1,8 @@ +ecdsa==0.13 +paramiko==1.16.0 +psycopg2==2.6.1 +py2-ipaddress>=3.4.1; python_version < '3' +pycrypto==2.6.1 +PyYAML==3.11 +requests==2.9.1 +wheel==0.26.0