Release repos list/update
Fuel releases contain metadata including default set of rpm/deb repositories that are to be used during cluster deployment. This change introduces couple new subcommands that allow to view and change the list of release repositories. DocImpact Change-Id: Ied9d69b98345318d7a92ca4c7093ac0424599cc3 Implements: blueprint fuelclient-modify-release-repos
This commit is contained in:
committed by
Roman Prykhodchenko
parent
34b745f54a
commit
5b2b85d93d
@@ -71,6 +71,7 @@ def get_client(resource, version='v1', connection=None):
|
||||
'node': v1.node,
|
||||
'openstack-config': v1.openstack_config,
|
||||
'plugins': v1.plugins,
|
||||
'release': v1.release,
|
||||
'task': v1.task,
|
||||
'vip': v1.vip
|
||||
}
|
||||
|
||||
81
fuelclient/commands/release.py
Normal file
81
fuelclient/commands/release.py
Normal file
@@ -0,0 +1,81 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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.
|
||||
|
||||
from fuelclient.commands import base
|
||||
from fuelclient.common import data_utils
|
||||
from fuelclient import utils
|
||||
|
||||
|
||||
class ReleaseMixIn(object):
|
||||
entity_name = 'release'
|
||||
|
||||
|
||||
class ReleaseList(ReleaseMixIn, base.BaseListCommand):
|
||||
"""Show list of all available releases."""
|
||||
|
||||
columns = ("id",
|
||||
"name",
|
||||
"state",
|
||||
"operating_system",
|
||||
"version")
|
||||
|
||||
|
||||
class ReleaseReposList(ReleaseMixIn, base.BaseListCommand):
|
||||
"""Show repos for a given release."""
|
||||
|
||||
def columns(self, repos):
|
||||
if repos:
|
||||
return tuple(repos[0])
|
||||
return ()
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ReleaseReposList, self).get_parser(prog_name)
|
||||
parser.add_argument('id', type=int,
|
||||
help='Id of the {0}.'.format(self.entity_name))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
data = self.client.get_attributes_metadata_by_id(parsed_args.id)
|
||||
repos = data["editable"]["repo_setup"]["repos"]["value"]
|
||||
columns = self.columns(repos)
|
||||
repos = data_utils.get_display_data_multi(columns, repos)
|
||||
return columns, repos
|
||||
|
||||
|
||||
class ReleaseReposUpdate(ReleaseMixIn, base.BaseCommand):
|
||||
"""Update repos for a given release."""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ReleaseReposUpdate, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'-f', '--file', action='store', required=True,
|
||||
help='Input yaml file with list of repositories')
|
||||
parser.add_argument(
|
||||
'id', type=int, help='Id of the {0}.'.format(self.entity_name))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
data = self.client.get_attributes_metadata_by_id(parsed_args.id)
|
||||
new_repos = utils.parse_yaml_file(parsed_args.file)
|
||||
data["editable"]["repo_setup"]["repos"]["value"] = new_repos
|
||||
self.client.update_attributes_metadata_by_id(parsed_args.id, data)
|
||||
self.app.stdout.write(
|
||||
"Repositories for the release with "
|
||||
"id {rel_id} were set from {file}.\n".format(
|
||||
rel_id=parsed_args.id,
|
||||
file=parsed_args.file
|
||||
)
|
||||
)
|
||||
@@ -20,6 +20,7 @@ class Release(BaseObject):
|
||||
class_api_path = "releases/"
|
||||
instance_api_path = "releases/{0}/"
|
||||
networks_path = 'releases/{0}/networks'
|
||||
attributes_metadata_path = 'releases/{0}/attributes_metadata'
|
||||
deployment_tasks_path = 'releases/{0}/deployment_tasks'
|
||||
|
||||
def get_networks(self):
|
||||
@@ -30,6 +31,14 @@ class Release(BaseObject):
|
||||
url = self.networks_path.format(self.id)
|
||||
return self.connection.put_request(url, data)
|
||||
|
||||
def update_attributes_metadata(self, data):
|
||||
url = self.attributes_metadata_path.format(self.id)
|
||||
self.connection.put_request(url, data)
|
||||
|
||||
def get_attributes_metadata(self):
|
||||
url = self.attributes_metadata_path.format(self.id)
|
||||
return self.connection.get_request(url)
|
||||
|
||||
def get_deployment_tasks(self):
|
||||
url = self.deployment_tasks_path.format(self.id)
|
||||
return self.connection.get_request(url)
|
||||
|
||||
65
fuelclient/tests/unit/v2/cli/test_release.py
Normal file
65
fuelclient/tests/unit/v2/cli/test_release.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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 mock
|
||||
|
||||
from fuelclient.tests.unit.v2.cli import test_engine
|
||||
from fuelclient.tests.utils import fake_release
|
||||
|
||||
|
||||
class TestReleaseCommand(test_engine.BaseCLITest):
|
||||
"""Tests for fuel2 release * commands."""
|
||||
|
||||
def setUp(self):
|
||||
super(TestReleaseCommand, self).setUp()
|
||||
self.m_client.get_by_id.return_value = fake_release.get_fake_release()
|
||||
self.m_client.get_attributes_metadata_by_id.return_value = \
|
||||
fake_release.get_fake_attributes_metadata()
|
||||
|
||||
def test_release_list(self):
|
||||
args = 'release list'
|
||||
self.exec_command(args)
|
||||
self.m_client.get_all.assert_called_once_with()
|
||||
self.m_get_client.assert_called_once_with('release', mock.ANY)
|
||||
|
||||
def test_release_repos_list(self):
|
||||
args = 'release repos list 1'
|
||||
self.exec_command(args)
|
||||
self.m_client.get_attributes_metadata_by_id.assert_called_once_with(1)
|
||||
self.m_get_client.assert_called_once_with('release', mock.ANY)
|
||||
|
||||
@mock.patch('fuelclient.commands.release.utils.parse_yaml_file')
|
||||
def test_release_repos_update(self, mock_parse_yaml):
|
||||
args = 'release repos update 1 -f repos.yaml'
|
||||
new_repos = [
|
||||
{
|
||||
"name": "fake",
|
||||
"type": "deb",
|
||||
"uri": "some_uri",
|
||||
"priority": 1050,
|
||||
"section": "main",
|
||||
"suite": "trusty"
|
||||
}
|
||||
]
|
||||
mock_parse_yaml.return_value = new_repos
|
||||
data = fake_release.get_fake_attributes_metadata()
|
||||
data["editable"]["repo_setup"]["repos"]["value"] = new_repos
|
||||
self.exec_command(args)
|
||||
mock_parse_yaml.assert_called_once_with('repos.yaml')
|
||||
self.m_client.get_attributes_metadata_by_id.assert_called_once_with(1)
|
||||
self.m_client.update_attributes_metadata_by_id \
|
||||
.assert_called_once_with(1, data)
|
||||
self.m_get_client.assert_called_once_with('release', mock.ANY)
|
||||
@@ -38,6 +38,7 @@ from fuelclient.tests.utils.fake_openstack_config \
|
||||
import get_fake_openstack_config
|
||||
from fuelclient.tests.utils.fake_plugin import get_fake_plugin
|
||||
from fuelclient.tests.utils.fake_plugin import get_fake_plugins
|
||||
from fuelclient.tests.utils.fake_release import get_fake_release
|
||||
|
||||
|
||||
__all__ = (get_fake_deployment_history,
|
||||
@@ -46,6 +47,7 @@ __all__ = (get_fake_deployment_history,
|
||||
get_fake_yaml_deployment_info,
|
||||
get_fake_yaml_network_conf,
|
||||
get_fake_env,
|
||||
get_fake_release,
|
||||
get_fake_fuel_version,
|
||||
get_fake_interface_config,
|
||||
get_fake_network_group,
|
||||
|
||||
62
fuelclient/tests/utils/fake_release.py
Normal file
62
fuelclient/tests/utils/fake_release.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
def get_fake_attributes_metadata(repos=None):
|
||||
return {
|
||||
'editable': {
|
||||
'repo_setup': {
|
||||
'repos': {
|
||||
'value': repos or [
|
||||
{
|
||||
'name': 'upstream',
|
||||
'type': 'deb',
|
||||
'uri': 'fake_upstream_uri',
|
||||
'suite': 'trusty',
|
||||
'section': 'main restricted',
|
||||
'priority': 1000
|
||||
},
|
||||
{
|
||||
'name': 'mos',
|
||||
'type': 'deb',
|
||||
'uri': 'fake_mos_uri',
|
||||
'suite': 'mos',
|
||||
'section': 'main restricted',
|
||||
'priority': 1050
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def get_fake_release(release_id=None, name=None, state=None,
|
||||
operating_system=None, version=None, repos=None):
|
||||
"""Create a random fake release
|
||||
|
||||
Returns the serialized and parametrized representation of a dumped Fuel
|
||||
release. Represents the average amount of data.
|
||||
|
||||
"""
|
||||
return {
|
||||
'id': release_id or 1,
|
||||
'name': name or 'Mitaka on Ubuntu 14.04',
|
||||
'state': state or 'available',
|
||||
'operating_system': operating_system or 'environment',
|
||||
'version': version or 'mitaka-9.0',
|
||||
'attributes_metadata': get_fake_attributes_metadata(repos=repos),
|
||||
}
|
||||
@@ -22,6 +22,7 @@ from fuelclient.v1 import network_configuration
|
||||
from fuelclient.v1 import network_group
|
||||
from fuelclient.v1 import node
|
||||
from fuelclient.v1 import openstack_config
|
||||
from fuelclient.v1 import release
|
||||
from fuelclient.v1 import plugins
|
||||
from fuelclient.v1 import task
|
||||
from fuelclient.v1 import vip
|
||||
@@ -38,5 +39,6 @@ __all__ = ('cluster_settings',
|
||||
'node',
|
||||
'openstack_config',
|
||||
'plugins',
|
||||
'release',
|
||||
'task',
|
||||
'vip')
|
||||
|
||||
33
fuelclient/v1/release.py
Normal file
33
fuelclient/v1/release.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# 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.
|
||||
|
||||
from fuelclient import objects
|
||||
from fuelclient.v1 import base_v1
|
||||
|
||||
|
||||
class ReleaseClient(base_v1.BaseV1Client):
|
||||
|
||||
_entity_wrapper = objects.Release
|
||||
|
||||
def update_attributes_metadata_by_id(self, release_id, data):
|
||||
release_obj = self._entity_wrapper(obj_id=release_id)
|
||||
release_obj.update_attributes_metadata(data)
|
||||
|
||||
def get_attributes_metadata_by_id(self, release_id):
|
||||
release_obj = self._entity_wrapper(obj_id=release_id)
|
||||
return release_obj.get_attributes_metadata()
|
||||
|
||||
|
||||
def get_client(connection):
|
||||
return ReleaseClient(connection)
|
||||
@@ -65,6 +65,9 @@ fuelclient =
|
||||
node_ansible-inventory=fuelclient.commands.node:NodeAnsibleInventory
|
||||
plugins_list=fuelclient.commands.plugins:PluginsList
|
||||
plugins_sync=fuelclient.commands.plugins:PluginsSync
|
||||
release_list=fuelclient.commands.release:ReleaseList
|
||||
release_repos_list=fuelclient.commands.release:ReleaseReposList
|
||||
release_repos_update=fuelclient.commands.release:ReleaseReposUpdate
|
||||
task_list=fuelclient.commands.task:TaskList
|
||||
task_show=fuelclient.commands.task:TaskShow
|
||||
task_history_show=fuelclient.commands.task:TaskHistoryShow
|
||||
|
||||
Reference in New Issue
Block a user