207 lines
6.4 KiB
Python
Executable File
207 lines
6.4 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Copyright 2016 Mirantis, 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.
|
|
|
|
import argparse
|
|
import os
|
|
|
|
import six
|
|
import yaml
|
|
|
|
from fuelclient import objects
|
|
|
|
|
|
FUELMENU_DEFAULT_SETTINGS_PATH = \
|
|
"/usr/lib/python2.7/site-packages/fuelmenu/settings.yaml"
|
|
|
|
|
|
def is_subdict(dict1, dict2):
|
|
"""Checks that dict1 is subdict of dict2.
|
|
|
|
>>> is_subdict({"a": 1}, {'a': 1, 'b': 1})
|
|
True
|
|
|
|
:param dict1: the candidate
|
|
:param dict2: the super dict
|
|
:return: True if all keys from dict1 are present
|
|
and has same value in dict2 otherwise False
|
|
"""
|
|
for k, v in six.iteritems(dict1):
|
|
if k not in dict2 or dict2[k] != v:
|
|
return False
|
|
return True
|
|
|
|
|
|
def lists_merge(main, patch, key):
|
|
"""Merges the list of dicts with same keys.
|
|
|
|
>>> lists_merge([{"a": 1, "c": 2}], [{"a": 1, "c": 3}], key="a")
|
|
[{'a': 1, 'c': 3}]
|
|
|
|
:param main: the main list
|
|
:type main: list
|
|
:param patch: the list of additional elements
|
|
:type patch: list
|
|
:param key: the key for compare
|
|
"""
|
|
main_idx = dict(
|
|
(x[key], i) for i, x in enumerate(main)
|
|
)
|
|
|
|
patch_idx = dict(
|
|
(x[key], i) for i, x in enumerate(patch)
|
|
)
|
|
|
|
for k in sorted(patch_idx):
|
|
if k in main_idx:
|
|
main[main_idx[k]].update(patch[patch_idx[k]])
|
|
else:
|
|
main.append(patch[patch_idx[k]])
|
|
return main
|
|
|
|
|
|
def update_release_repos(repositories,
|
|
release_match,
|
|
replace_repos=False):
|
|
"""Applies repositories for existing default settings.
|
|
:param repositories: the meta information of repositories
|
|
:param release_match: The pattern to check Fuel Release
|
|
"""
|
|
releases = six.moves.filter(
|
|
lambda x: is_subdict(release_match, x.data),
|
|
objects.Release.get_all()
|
|
)
|
|
for release in releases:
|
|
modified = _update_repository_settings(
|
|
release.data["attributes_metadata"],
|
|
repositories,
|
|
replace_repos=replace_repos)
|
|
if modified:
|
|
release.data["attributes_metadata"] = modified
|
|
print "Try to update the Release '%s'" % release.data['name']
|
|
release.connection.put_request(
|
|
release.instance_api_path.format(release.id),
|
|
release.data
|
|
)
|
|
|
|
|
|
def _update_repository_settings(settings,
|
|
repositories,
|
|
replace_repos=False):
|
|
"""Updates repository settings.
|
|
:param settings: the target settings
|
|
:param repositories: the meta of repositories
|
|
"""
|
|
editable = settings["editable"]
|
|
if 'repo_setup' not in editable:
|
|
return
|
|
|
|
repos_attr = editable["repo_setup"]["repos"]
|
|
if replace_repos:
|
|
repos_attr['value'] = repositories
|
|
else:
|
|
lists_merge(repos_attr['value'], repositories, "name")
|
|
|
|
settings["editable"]["repo_setup"]["repos"] = repos_attr
|
|
|
|
return settings
|
|
|
|
|
|
def fix_fuel_repos(address, port, user, password,
|
|
release_version, release_os, repositories):
|
|
os.environ["SERVER_ADDRESS"] = address
|
|
os.environ["LISTEN_PORT"] = port
|
|
os.environ["KEYSTONE_USER"] = user
|
|
os.environ["KEYSTONE_PASS"] = password
|
|
|
|
release_match = {
|
|
"version": release_version,
|
|
"operating_system": release_os
|
|
}
|
|
|
|
update_release_repos(repositories, release_match)
|
|
|
|
|
|
def fix_fuelmenu_repos(repositories, replace_repos=False):
|
|
print "Try to update default fuelmenu settings"
|
|
with open(FUELMENU_DEFAULT_SETTINGS_PATH) as f:
|
|
settings = yaml.safe_load(f)
|
|
if replace_repos:
|
|
settings["BOOTSTRAP"]["repos"] = repositories
|
|
else:
|
|
lists_merge(settings["BOOTSTRAP"]["repos"], repositories, "name")
|
|
with open(FUELMENU_DEFAULT_SETTINGS_PATH, "w") as f:
|
|
f.write(yaml.safe_dump(settings, default_flow_style=False))
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
subparsers = parser.add_subparsers(
|
|
dest="action", help='actions'
|
|
)
|
|
fuel_parser = subparsers.add_parser(
|
|
'fuel', help='fix fuel repos'
|
|
)
|
|
fuel_parser.add_argument(
|
|
'--release-version', dest='release_version', action='store',
|
|
type=str, help='release version', default='newton-10.0'
|
|
)
|
|
fuel_parser.add_argument(
|
|
'--release-os', dest='release_os', action='store',
|
|
type=str, help='release operating system', default='Ubuntu'
|
|
)
|
|
fuel_parser.add_argument(
|
|
'--repositories-file', dest='repositories_file', action='store',
|
|
type=str, help='file where repositories are defined', required=True
|
|
)
|
|
fuel_parser.add_argument(
|
|
'-a', '--address', dest='address', action='store', type=str,
|
|
help='fuel address', default='127.0.0.1'
|
|
)
|
|
fuel_parser.add_argument(
|
|
'-p', '--port', dest='port', action='store', type=str,
|
|
help='fuel port', default='8000'
|
|
)
|
|
fuel_parser.add_argument(
|
|
'--user', dest='user', action='store', type=str,
|
|
help='fuel user', default='admin'
|
|
)
|
|
fuel_parser.add_argument(
|
|
'--password', dest='password', action='store', type=str,
|
|
help='fuel password', default='admin'
|
|
)
|
|
fuelmenu_parser = subparsers.add_parser(
|
|
'fuelmenu', help='fix fuelmenu repos'
|
|
)
|
|
fuelmenu_parser.add_argument(
|
|
'--repositories-file', dest='repositories_file', action='store',
|
|
type=str, help='file where repositories are defined', required=True
|
|
)
|
|
params, other_params = parser.parse_known_args()
|
|
|
|
with open(params.repositories_file) as f:
|
|
repositories = yaml.safe_load(f)
|
|
|
|
if params.action == 'fuel':
|
|
fix_fuel_repos(params.address, params.port,
|
|
params.user, params.password,
|
|
params.release_version, params.release_os,
|
|
repositories)
|
|
else:
|
|
fix_fuelmenu_repos(repositories)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|