Merge tag '0.5.0' into debian/newton

python-senlinclient 0.5.0 release

meta:version: 0.5.0
meta:series: newton
meta:release-type: release
meta:announce: openstack-dev@lists.openstack.org
meta:pypi: no
meta:first: yes
meta:release:Author: tengqm <tengqim@cn.ibm.com>
meta:release:Commit: Qiming Teng <tengqim@cn.ibm.com>
meta:release:Change-Id: I3032bdde98fa6515b0d6745d7db27042ca16c01c
meta:release:Code-Review+2: Doug Hellmann <doug@doughellmann.com>
meta:release:Workflow+1: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
Thomas Goirand
2016-07-13 10:47:14 +02:00
49 changed files with 910 additions and 142 deletions

6
.gitignore vendored
View File

@@ -54,3 +54,9 @@ doc/build/
# PyBuilder
target/
# Files created by releasenotes build
releasenotes/build
# swap file
*.swp

View File

@@ -1,4 +0,0 @@
python-senlinclient
===================
Client library for OpenStack Clustering Service API

View File

@@ -7,4 +7,4 @@ provides a Python API (the ``senlinclient`` module) and a command-line tool
Development takes place via the usual OpenStack processes as outlined in the
`developer guide <http://docs.openstack.org/infra/manual/developers.html>`_.
The master repository is in `Git <http://github.com/tengqm/python-senlinclient>`_.
The master repository is in `Git <https://git.openstack.org/cgit/openstack/python-senlinclient>`_.

View File

@@ -17,6 +17,5 @@ Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@@ -0,0 +1,5 @@
---
upgrade:
- OSC commands for cluster scaling are changed from 'cluster scale in'
and 'cluster scale out' to 'cluster shrink' and 'cluster expand'
respectively.

View File

@@ -0,0 +1,3 @@
---
features:
- Added command for node-check and node-recover.

277
releasenotes/source/conf.py Normal file
View File

@@ -0,0 +1,277 @@
# -*- coding: utf-8 -*-
# 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.
# Senlin Release Notes documentation build configuration file, created by
# sphinx-quickstart on Tue Nov 3 17:40:50 2015.
#
# 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.
# 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 = [
'oslosphinx',
'reno.sphinxext',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Senlin Client Release Notes'
copyright = u'2015, Senlin Developers'
# 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.
import pbr.version
senlin_version = pbr.version.VersionInfo('python-muranoclient')
# The full version, including alpha/beta/rc tags.
release = senlin_version.version_string_with_vcs()
# The short X.Y version.
version = senlin_version.canonical_version_string()
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all
# documents.
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = 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 = 'default'
# 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 themes here, relative to this directory.
# html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
# html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
# html_favicon = None
# 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']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
# html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
# html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
# html_additional_pages = {}
# If false, no module index is generated.
# html_domain_indices = True
# If false, no index is generated.
# html_use_index = True
# If true, the index is split into individual pages for each letter.
# html_split_index = False
# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
# html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'SenlinClientReleaseNotesdoc'
# -- 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': '',
}
# 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 = [
('index', 'SenlinClientReleaseNotes.tex',
u'Senlin Client Release Notes Documentation',
u'Senlin Developers', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False
# If true, show page references after internal links.
# latex_show_pagerefs = False
# If true, show URL addresses after external links.
# latex_show_urls = False
# Documents to append as an appendix to all manuals.
# latex_appendices = []
# If false, no module index is generated.
# latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'senlinclientreleasenotes',
u'Senlin Client Release Notes Documentation',
[u'Senlin Developers'], 1)
]
# If true, show URL addresses after external links.
# man_show_urls = False
# -- 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 = [
('index', 'SenlinClientReleaseNotes',
u'Senlin Client Release Notes Documentation',
u'Senlin Developers', 'SenlinClientReleaseNotes',
'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
# texinfo_appendices = []
# If false, no module index is generated.
# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
# texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
# texinfo_no_detailmenu = False

View File

@@ -0,0 +1,8 @@
=============================
Senlin Client Release Notes
=============================
.. toctree::
:maxdepth: 1
unreleased

View File

@@ -0,0 +1,5 @@
==============================
Current Series Release Notes
==============================
.. release-notes::

View File

@@ -2,16 +2,16 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
Babel>=1.3 # BSD
Babel>=2.3.4 # BSD
pbr>=1.6 # Apache-2.0
cliff!=1.16.0,!=1.17.0,>=1.15.0 # Apache-2.0
PrettyTable<0.8,>=0.7 # BSD
openstacksdk>=0.8.1 # Apache-2.0
openstacksdk>=0.8.6 # Apache-2.0
oslo.i18n>=2.1.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
oslo.utils>=3.5.0 # Apache-2.0
python-heatclient>=0.6.0 # Apache-2.0
oslo.utils>=3.11.0 # Apache-2.0
python-heatclient>=1.1.0 # Apache-2.0
python-openstackclient>=2.1.0 # Apache-2.0
PyYAML>=3.1.0 # MIT
requests!=2.9.0,>=2.8.1 # Apache-2.0
requests>=2.10.0 # Apache-2.0
six>=1.9.0 # MIT

View File

@@ -230,7 +230,7 @@ _EXCEPTION_MAP = {
def parse_exception(exc):
"""Parse exception code and yield useful information.
:param details: details of the exception.
:param exc: details of the exception.
"""
if isinstance(exc, sdkexc.HttpException):
if exc.details is None:

View File

@@ -27,9 +27,9 @@ prop = base.prop
class ProfileAction(argparse.Action):
"""A custom action to parse user proferences as key=value pairs
"""A custom action to parse user preferences as key=value pairs
Stores results in users proferences object.
Stores results in users preferences object.
"""
prof = profile.Profile()
@@ -124,6 +124,15 @@ class Resource(base.Resource):
def create_connection(prof=None, user_agent=None, **kwargs):
if not prof:
prof = profile.Profile()
interface = kwargs.pop('interface', None)
region_name = kwargs.pop('region_name', None)
if interface:
prof.set_interface('clustering', interface)
if region_name:
prof.set_region('clustering', region_name)
try:
conn = connection.Connection(profile=prof, user_agent=user_agent,
**kwargs)

View File

@@ -1,33 +0,0 @@
# 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 openstackclient.tests import utils
from senlinclient.tests.unit.osc import fakes
class FakeClusteringv1Client(object):
def __init__(self, **kwargs):
self.http_client = mock.Mock()
self.http_client.auth_token = kwargs['token']
self.profiles = fakes.FakeResource(None, {})
class TestClusteringv1(utils.TestCommand):
def setUp(self):
super(TestClusteringv1, self).setUp()
self.app.client_manager.clustering = FakeClusteringv1Client(
token=fakes.AUTH_TOKEN,
auth_url=fakes.AUTH_URL
)

View File

@@ -14,6 +14,9 @@ import mock
import os
import testtools
from openstack import connection as sdk_connection
from openstack import profile as sdk_profile
from senlinclient.common import sdk
@@ -54,3 +57,47 @@ class TestSdk(testtools.TestCase):
mock_prof.ALL = 'mock_prof.ALL'
sdk.ProfileAction.set_option('interface', 'test=val1')
mock_prof.set_interface.assert_called_once_with('test', 'val1')
@mock.patch.object(sdk_connection, 'Connection')
def test_create_connection_with_profile(self, mock_connection):
mock_prof = mock.Mock()
mock_conn = mock.Mock()
mock_connection.return_value = mock_conn
kwargs = {
'user_id': '123',
'password': 'abc',
'auth_url': 'test_url'
}
res = sdk.create_connection(mock_prof, **kwargs)
mock_connection.assert_called_once_with(profile=mock_prof,
user_agent=None,
user_id='123',
password='abc',
auth_url='test_url')
self.assertEqual(mock_conn, res)
@mock.patch.object(sdk_connection, 'Connection')
@mock.patch.object(sdk_profile, 'Profile')
def test_create_connection_without_profile(self, mock_profile,
mock_connection):
mock_prof = mock.Mock()
mock_conn = mock.Mock()
mock_profile.return_value = mock_prof
mock_connection.return_value = mock_conn
kwargs = {
'interface': 'public',
'region_name': 'RegionOne',
'user_id': '123',
'password': 'abc',
'auth_url': 'test_url'
}
res = sdk.create_connection(**kwargs)
mock_prof.set_interface.assert_called_once_with('clustering', 'public')
mock_prof.set_region.assert_called_once_with('clustering', 'RegionOne')
mock_connection.assert_called_once_with(profile=mock_prof,
user_agent=None,
user_id='123',
password='abc',
auth_url='test_url')
self.assertEqual(mock_conn, res)

View File

@@ -11,10 +11,13 @@
# under the License.
import json
import mock
import requests
import six
import sys
from openstackclient.tests import utils
AUTH_TOKEN = "foobar"
AUTH_URL = "http://0.0.0.0"
@@ -158,3 +161,19 @@ class FakeResponse(requests.Response):
self._content = json.dumps(data)
if not isinstance(self._content, six.binary_type):
self._content = self._content.encode()
class FakeClusteringv1Client(object):
def __init__(self, **kwargs):
self.http_client = mock.Mock()
self.http_client.auth_token = kwargs['token']
self.profiles = FakeResource(None, {})
class TestClusteringv1(utils.TestCommand):
def setUp(self):
super(TestClusteringv1, self).setUp()
self.app.client_manager.clustering = FakeClusteringv1Client(
token=AUTH_TOKEN, auth_url=AUTH_URL
)

View File

@@ -17,8 +17,8 @@ from openstack.cluster.v1 import action as sdk_action
from openstack import exceptions as sdk_exc
from openstackclient.common import exceptions as exc
from senlinclient.osc.v1 import action as osc_action
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import action as osc_action
class TestAction(fakes.TestClusteringv1):

View File

@@ -14,8 +14,8 @@ import mock
from openstack.cluster.v1 import build_info as sdk_build_info
from senlinclient.osc.v1 import build_info as osc_build_info
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import build_info as osc_build_info
class TestBuildInfo(fakes.TestClusteringv1):

View File

@@ -18,8 +18,8 @@ from openstack.cluster.v1 import cluster as sdk_cluster
from openstack import exceptions as sdk_exc
from openstackclient.common import exceptions as exc
from senlinclient.osc.v1 import cluster as osc_cluster
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import cluster as osc_cluster
class TestCluster(fakes.TestClusteringv1):

View File

@@ -14,8 +14,8 @@ import mock
from openstack.cluster.v1 import cluster_policy as sdk_cluster_policy
from senlinclient.osc.v1 import cluster_policy as osc_cluster_policy
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import cluster_policy as osc_cluster_policy
class TestClusterPolicy(fakes.TestClusteringv1):

View File

@@ -17,8 +17,8 @@ from openstack.cluster.v1 import event as sdk_event
from openstack import exceptions as sdk_exc
from openstackclient.common import exceptions as exc
from senlinclient.osc.v1 import event as osc_event
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import event as osc_event
class TestEvent(fakes.TestClusteringv1):

View File

@@ -18,8 +18,8 @@ from openstack.cluster.v1 import node as sdk_node
from openstack import exceptions as sdk_exc
from openstackclient.common import exceptions as exc
from senlinclient.osc.v1 import node as osc_node
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import node as osc_node
class TestNode(fakes.TestClusteringv1):
@@ -402,3 +402,57 @@ class TestNodeDelete(TestNode):
mock_stdin.readline.assert_called_with()
self.mock_client.delete_node.assert_not_called()
class TestNodeCheck(TestNode):
response = {"action": "8bb476c3-0f4c-44ee-9f64-c7b0260814de"}
def setUp(self):
super(TestNodeCheck, self).setUp()
self.cmd = osc_node.CheckNode(self.app, None)
self.mock_client.check_node = mock.Mock(
return_value=self.response)
def test_node_check(self):
arglist = ['node1', 'node2', 'node3']
parsed_args = self.check_parser(self.cmd, arglist, [])
self.cmd.take_action(parsed_args)
self.mock_client.check_node.assert_has_calls(
[mock.call('node1'), mock.call('node2'),
mock.call('node3')]
)
def test_node_check_not_found(self):
arglist = ['node1']
self.mock_client.check_node.side_effect = sdk_exc.ResourceNotFound
parsed_args = self.check_parser(self.cmd, arglist, [])
error = self.assertRaises(exc.CommandError, self.cmd.take_action,
parsed_args)
self.assertIn('Node not found: node1', str(error))
class TestNodeRecover(TestNode):
response = {"action": "8bb476c3-0f4c-44ee-9f64-c7b0260814de"}
def setUp(self):
super(TestNodeRecover, self).setUp()
self.cmd = osc_node.RecoverNode(self.app, None)
self.mock_client.recover_node = mock.Mock(
return_value=self.response)
def test_node_recover(self):
arglist = ['node1', 'node2', 'node3']
parsed_args = self.check_parser(self.cmd, arglist, [])
self.cmd.take_action(parsed_args)
self.mock_client.recover_node.assert_has_calls(
[mock.call('node1'), mock.call('node2'),
mock.call('node3')]
)
def test_node_recover_not_found(self):
arglist = ['node1']
self.mock_client.recover_node.side_effect = sdk_exc.ResourceNotFound
parsed_args = self.check_parser(self.cmd, arglist, [])
error = self.assertRaises(exc.CommandError, self.cmd.take_action,
parsed_args)
self.assertIn('Node not found: node1', str(error))

View File

@@ -18,8 +18,8 @@ from openstack.cluster.v1 import policy as sdk_policy
from openstack import exceptions as sdk_exc
from openstackclient.common import exceptions as exc
from senlinclient.osc.v1 import policy as osc_policy
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import policy as osc_policy
class TestPolicy(fakes.TestClusteringv1):

View File

@@ -16,8 +16,8 @@ from openstack.cluster.v1 import policy_type as sdk_policy_type
from openstack import exceptions as sdk_exc
from openstackclient.common import exceptions as exc
from senlinclient.osc.v1 import policy_type as osc_policy_type
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import policy_type as osc_policy_type
class TestPolicyType(fakes.TestClusteringv1):

View File

@@ -19,8 +19,8 @@ from openstack import exceptions as sdk_exc
from openstackclient.common import exceptions as exc
from openstackclient.common import utils
from senlinclient.osc.v1 import profile as osc_profile
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import profile as osc_profile
class TestProfile(fakes.TestClusteringv1):

View File

@@ -16,8 +16,8 @@ from openstack.cluster.v1 import profile_type as sdk_profile_type
from openstack import exceptions as sdk_exc
from openstackclient.common import exceptions as exc
from senlinclient.osc.v1 import profile_type as osc_profile_type
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import profile_type as osc_profile_type
class TestProfileType(fakes.TestClusteringv1):

View File

@@ -18,8 +18,8 @@ from openstack.cluster.v1 import receiver as sdk_receiver
from openstack import exceptions as sdk_exc
from openstackclient.common import exceptions as exc
from senlinclient.osc.v1 import receiver as osc_receiver
from senlinclient.tests.unit.osc.v1 import fakes
from senlinclient.tests.unit.v1 import fakes
from senlinclient.v1 import receiver as osc_receiver
class TestReceiver(fakes.TestClusteringv1):

View File

@@ -16,6 +16,7 @@ import six
import testtools
from openstack import exceptions as oexc
from oslotest import mockpatch
from senlinclient.common import exc
from senlinclient.common.i18n import _
from senlinclient.common import utils
@@ -39,6 +40,13 @@ class ShellTest(testtools.TestCase):
'template': {"Template": "data"}
}
}
self.patch('senlinclient.v1.shell.show_deprecated')
# NOTE(pshchelo): this overrides the testtools.TestCase.patch method
# that does simple monkey-patching in favor of mock's patching
def patch(self, target, **kwargs):
mockfixture = self.useFixture(mockpatch.Patch(target, **kwargs))
return mockfixture.mock
def _make_args(self, args):
"""Convert a dict to an object."""

View File

@@ -27,139 +27,376 @@ class Client(object):
######################################################################
def profile_types(self, **query):
"""List profile types
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html
#listProfileTypes
"""
return self.service.profile_types(**query)
def get_profile_type(self, profile_type):
"""Show profile type details
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#showProfileType
"""
return self.service.get_profile_type(profile_type)
def profiles(self, **query):
"""List profiles
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#listProfiles
"""
return self.service.profiles(**query)
def create_profile(self, **attrs):
"""Create a profile
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#createProfile
"""
return self.service.create_profile(**attrs)
def get_profile(self, profile):
"""Show profile details
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#showProfile
"""
return self.service.get_profile(profile)
def update_profile(self, profile, **attrs):
"""Update a profile
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#updateProfile
"""
return self.service.update_profile(profile, **attrs)
def delete_profile(self, profile, ignore_missing=True):
"""Delete a profile
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#deleteProfile
"""
return self.service.delete_profile(profile, ignore_missing)
def policy_types(self, **query):
"""List policy types
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html
#listPolicyType
"""
return self.service.policy_types(**query)
def get_policy_type(self, policy_type):
"""Show policy type details
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html
#showPolicyType
"""
return self.service.get_policy_type(policy_type)
def policies(self, **query):
"""List policies
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#listPolicies
"""
return self.service.policies(**query)
def create_policy(self, **attrs):
"""Create a policy
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#createPolicy
"""
return self.service.create_policy(**attrs)
def get_policy(self, policy):
"""Show policy details
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#showPolicy
"""
return self.service.get_policy(policy)
def update_policy(self, policy, **attrs):
"""Update policy
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#updatePolicy
"""
return self.service.update_policy(policy, **attrs)
def delete_policy(self, policy, ignore_missing=True):
"""Delete policy
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#deletePolicy
"""
return self.service.delete_policy(policy, ignore_missing)
def clusters(self, **queries):
"""List clusters
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#listClusters
"""
return self.service.clusters(**queries)
def create_cluster(self, **attrs):
"""Create a cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#createCluster
"""
return self.service.create_cluster(**attrs)
def get_cluster(self, cluster):
"""Show cluster details
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#showCluster
"""
return self.service.get_cluster(cluster)
def update_cluster(self, cluster, **attrs):
"""Update cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#updateCluster
"""
return self.service.update_cluster(cluster, **attrs)
def delete_cluster(self, cluster, ignore_missing=True):
"""Delete cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#deleteCluster
"""
return self.service.delete_cluster(cluster, ignore_missing)
def cluster_add_nodes(self, cluster, nodes):
"""Add a node to cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#clusterAction
"""
return self.service.cluster_add_nodes(cluster, nodes)
def cluster_del_nodes(self, cluster, nodes):
"""Delete a node belongs to cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#clusterAction
"""
return self.service.cluster_del_nodes(cluster, nodes)
def cluster_resize(self, cluster, **params):
"""Resize cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#clusterAction
"""
return self.service.cluster_resize(cluster, **params)
def cluster_scale_out(self, cluster, count):
"""Scale out cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#clusterAction
"""
return self.service.cluster_scale_out(cluster, count)
def cluster_scale_in(self, cluster, count):
"""Scale in cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#clusterAction
"""
return self.service.cluster_scale_in(cluster, count)
def cluster_policies(self, cluster, **queries):
"""List all policies attached to cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html
#listClusterPolicies
"""
return self.service.cluster_policies(cluster, **queries)
def get_cluster_policy(self, policy, cluster):
"""Show details of a policy attached to cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html
#showClusterPolicy
"""
return self.service.get_cluster_policy(policy, cluster)
def cluster_attach_policy(self, cluster, policy, **attrs):
"""Attach a policy to cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#clusterAction
"""
return self.service.cluster_attach_policy(cluster, policy, **attrs)
def cluster_detach_policy(self, cluster, policy):
"""Detach a policy from cluster
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#clusterAction
"""
return self.service.cluster_detach_policy(cluster, policy)
def cluster_update_policy(self, cluster, policy, **attrs):
"""Update the policy attachment
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#clusterAction
"""
return self.service.cluster_update_policy(cluster, policy, **attrs)
def check_cluster(self, cluster, **params):
"""Check cluster's health status
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#clusterAction
"""
return self.service.check_cluster(cluster, **params)
def recover_cluster(self, cluster, **params):
"""Recover cluster from failure state
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#clusterAction
"""
return self.service.recover_cluster(cluster, **params)
def nodes(self, **queries):
"""List nodes
Doc link: http://developer.openstack.org/api-ref-clustering-v1.html
#listNodes
"""
return self.service.nodes(**queries)
def create_node(self, **attrs):
"""Create a node
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#createNode
"""
return self.service.create_node(**attrs)
def get_node(self, node, args=None):
"""Show node details
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#showNode
"""
return self.service.get_node(node, args=args)
def update_node(self, node, **attrs):
"""Update node
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#updateNode
"""
return self.service.update_node(node, **attrs)
def delete_node(self, node, ignore_missing=True):
"""Delete node
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#deleteNode
"""
return self.service.delete_node(node, ignore_missing)
def check_node(self, node, **params):
"""Check node's health status
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#nodeAction
"""
return self.service.check_node(node, **params)
def recover_node(self, node, **params):
"""Recover node from failure state
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#nodeAction
"""
return self.service.recover_node(node, **params)
def receivers(self, **queries):
"""List receivers
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#listReceivers
"""
return self.service.receivers(**queries)
def create_receiver(self, **attrs):
"""Creare a receiver
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html
#createReceiver
"""
return self.service.create_receiver(**attrs)
def get_receiver(self, receiver):
"""Show receiver details
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#showReceiver
"""
return self.service.get_receiver(receiver)
def delete_receiver(self, receiver, ignore_missing=True):
"""Delete receiver
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html
#deleteReceiver
"""
return self.service.delete_receiver(receiver, ignore_missing)
def events(self, **queries):
"""List events
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#listEvents
"""
return self.service.events(**queries)
def get_event(self, event):
"""Show event details
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#showEvent
"""
return self.service.get_event(event)
def actions(self, **queries):
"""List actions
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#listActions
"""
return self.service.actions(**queries)
def get_action(self, action):
"""Show action details
Doc link:
http://developer.openstack.org/api-ref-clustering-v1.html#showAction
"""
return self.service.get_action(action)

View File

@@ -332,3 +332,57 @@ class DeleteNode(command.Command):
{'count': failure_count,
'total': len(parsed_args.node)})
print('Request accepted')
class CheckNode(command.Command):
"""Check the node(s)."""
log = logging.getLogger(__name__ + ".CheckNode")
def get_parser(self, prog_name):
parser = super(CheckNode, self).get_parser(prog_name)
parser.add_argument(
'node',
metavar='<node>',
nargs='+',
help=_('ID or name of node(s) to check.')
)
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
senlin_client = self.app.client_manager.clustering
for nid in parsed_args.node:
try:
resp = senlin_client.check_node(nid)
except sdk_exc.ResourceNotFound:
raise exc.CommandError(_('Node not found: %s') % nid)
print('Node check request on node %(nid)s is accepted by '
'action %(action)s.'
% {'nid': nid, 'action': resp['action']})
class RecoverNode(command.Command):
"""Recover the node(s)."""
log = logging.getLogger(__name__ + ".RecoverNode")
def get_parser(self, prog_name):
parser = super(RecoverNode, self).get_parser(prog_name)
parser.add_argument(
'node',
metavar='<node>',
nargs='+',
help=_('ID or name of node(s) to recover.')
)
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
senlin_client = self.app.client_manager.clustering
for nid in parsed_args.node:
try:
resp = senlin_client.recover_node(nid)
except sdk_exc.ResourceNotFound:
raise exc.CommandError(_('Node not found: %s') % nid)
print('Node recover request on node %(nid)s is accepted by '
'action %(action)s.'
% {'nid': nid, 'action': resp['action']})

View File

@@ -15,17 +15,27 @@ import logging
from openstack import exceptions as sdk_exc
from senlinclient.common import exc
from senlinclient.common.i18n import _
from senlinclient.common.i18n import _LW
from senlinclient.common import utils
logger = logging.getLogger(__name__)
def show_deprecated(deprecated, recommended):
logger.warning(_LW('"%(old)s" is deprecated, '
'please use "%(new)s" instead.'),
{'old': deprecated,
'new': recommended}
)
def do_build_info(service, args=None):
"""Retrieve build information.
:param sc: Instance of senlinclient.
:param args: Additional command line arguments, if any.
"""
show_deprecated('senlin build-info', 'openstack cluster build info')
result = service.get_build_info()
formatters = {
@@ -44,6 +54,8 @@ def do_profile_type_list(service, args=None):
:param sc: Instance of senlinclient.
:param args: Additional command line arguments, if any.
"""
show_deprecated('senlin profile-type-list',
'openstack cluster profile type list')
types = service.profile_types()
utils.print_list(types, ['name'], sortby_index=0)
@@ -56,6 +68,8 @@ def do_profile_type_list(service, args=None):
% ', '.join(utils.supported_formats.keys()))
def do_profile_type_show(service, args):
"""Get the details about a profile type."""
show_deprecated('senlin profile-type-show',
'openstack cluster profile type show')
try:
res = service.get_profile_type(args.type_name)
except sdk_exc.ResourceNotFound:
@@ -83,8 +97,8 @@ def do_profile_type_show(service, args):
help=_('Only return profiles that appear after the given ID.'))
@utils.arg('-o', '--sort', metavar='<KEY:DIR>',
help=_('Sorting option which is a string containing a list of keys '
'separated by commas. Each key can be optionally appened by '
'a sort direction (:asc or :desc)'))
'separated by commas. Each key can be optionally appended '
'by a sort direction (:asc or :desc)'))
@utils.arg('-g', '--global-project', default=False, action="store_true",
help=_('Indicate that the list should include profiles from'
' all projects. This option is subject to access policy '
@@ -93,6 +107,7 @@ def do_profile_type_show(service, args):
help=_('Print full IDs in list.'))
def do_profile_list(service, args=None):
"""List profiles that meet the criteria."""
show_deprecated('senlin profile-list', 'openstack cluster profile list')
fields = ['id', 'name', 'type', 'created_at']
queries = {
'limit': args.limit,
@@ -143,7 +158,8 @@ def _show_profile(service, profile_id):
help=_('Name of the profile to create.'))
def do_profile_create(service, args):
"""Create a profile."""
show_deprecated('senlin profile-create',
'openstack cluster profile create')
spec = utils.get_spec_content(args.spec_file)
type_name = spec.get('type', None)
type_version = spec.get('version', None)
@@ -173,6 +189,7 @@ def do_profile_create(service, args):
help=_('Name or ID of profile to show.'))
def do_profile_show(service, args):
"""Show the profile details."""
show_deprecated('senlin profile-show', 'openstack cluster profile show')
_show_profile(service, args.id)
@@ -187,6 +204,8 @@ def do_profile_show(service, args):
help=_('Name or ID of the profile to update.'))
def do_profile_update(service, args):
"""Update a profile."""
show_deprecated('senlin profile-update',
'openstack cluster profile update')
params = {
'name': args.name,
}
@@ -206,6 +225,8 @@ def do_profile_update(service, args):
help=_('Name or ID of profile(s) to delete.'))
def do_profile_delete(service, args):
"""Delete profile(s)."""
show_deprecated('senlin profile-delete',
'openstack cluster profile delete')
failure_count = 0
for pid in args.id:
@@ -225,6 +246,8 @@ def do_profile_delete(service, args):
def do_policy_type_list(service, args):
"""List the available policy types."""
show_deprecated('senlin policy-type-list',
'openstack cluster policy type list')
types = service.policy_types()
utils.print_list(types, ['name'], sortby_index=0)
@@ -237,6 +260,8 @@ def do_policy_type_list(service, args):
% ', '.join(utils.supported_formats.keys()))
def do_policy_type_show(service, args):
"""Get the details about a policy type."""
show_deprecated('senlin policy-type-show',
'openstack cluster policy type show')
try:
res = service.get_policy_type(args.type_name)
except sdk_exc.ResourceNotFound:
@@ -262,8 +287,8 @@ def do_policy_type_show(service, args):
help=_('Only return policies that appear after the given ID.'))
@utils.arg('-o', '--sort', metavar='<KEY:DIR>',
help=_('Sorting option which is a string containing a list of keys '
'separated by commas. Each key can be optionally appened by '
'a sort direction (:asc or :desc)'))
'separated by commas. Each key can be optionally appended '
'by a sort direction (:asc or :desc)'))
@utils.arg('-g', '--global-project', default=False, action="store_true",
help=_('Indicate that the list should include policies from'
' all projects. This option is subject to access policy '
@@ -272,6 +297,7 @@ def do_policy_type_show(service, args):
help=_('Print full IDs in list.'))
def do_policy_list(service, args=None):
"""List policies that meet the criteria."""
show_deprecated('senlin policy-list', 'openstack cluster policy list')
fields = ['id', 'name', 'type', 'created_at']
queries = {
'limit': args.limit,
@@ -312,6 +338,7 @@ def _show_policy(service, policy_id):
help=_('Name of the policy to create.'))
def do_policy_create(service, args):
"""Create a policy."""
show_deprecated('senlin policy-create', 'openstack cluster policy create')
spec = utils.get_spec_content(args.spec_file)
attrs = {
'name': args.name,
@@ -326,6 +353,7 @@ def do_policy_create(service, args):
help=_('Name of the policy to be updated.'))
def do_policy_show(service, args):
"""Show the policy details."""
show_deprecated('senlin policy-show', 'openstack cluster policy show')
_show_policy(service, policy_id=args.id)
@@ -335,6 +363,7 @@ def do_policy_show(service, args):
help=_('Name of the policy to be updated.'))
def do_policy_update(service, args):
"""Update a policy."""
show_deprecated('senlin policy-update', 'openstack cluster policy update')
params = {
'name': args.name,
}
@@ -349,6 +378,7 @@ def do_policy_update(service, args):
help=_('Name or ID of policy(s) to delete.'))
def do_policy_delete(service, args):
"""Delete policy(s)."""
show_deprecated('senlin policy-delete', 'openstack cluster policy delete')
failure_count = 0
for pid in args.id:
@@ -373,8 +403,8 @@ def do_policy_delete(service, args):
action='append')
@utils.arg('-o', '--sort', metavar='<KEY:DIR>',
help=_('Sorting option which is a string containing a list of keys '
'separated by commas. Each key can be optionally appened by '
'a sort direction (:asc or :desc)'))
'separated by commas. Each key can be optionally appended '
'by a sort direction (:asc or :desc)'))
@utils.arg('-l', '--limit', metavar='<LIMIT>',
help=_('Limit the number of clusters returned.'))
@utils.arg('-m', '--marker', metavar='<ID>',
@@ -388,6 +418,7 @@ def do_policy_delete(service, args):
help=_('Print full IDs in list.'))
def do_cluster_list(service, args=None):
"""List the user's clusters."""
show_deprecated('senlin cluster-list', 'openstack cluster list')
fields = ['id', 'name', 'status', 'created_at', 'updated_at']
queries = {
'limit': args.limit,
@@ -443,6 +474,7 @@ def _show_cluster(service, cluster_id):
help=_('Name of the cluster to create.'))
def do_cluster_create(service, args):
"""Create the cluster."""
show_deprecated('senlin cluster-create', 'openstack cluster create')
if args.min_size and not args.desired_capacity:
args.desired_capacity = args.min_size
attrs = {
@@ -463,6 +495,7 @@ def do_cluster_create(service, args):
help=_('Name or ID of cluster(s) to delete.'))
def do_cluster_delete(service, args):
"""Delete the cluster(s)."""
show_deprecated('senlin cluster-delete', 'openstack cluster delete')
failure_count = 0
for cid in args.id:
@@ -492,6 +525,7 @@ def do_cluster_delete(service, args):
help=_('Name or ID of cluster to be updated.'))
def do_cluster_update(service, args):
"""Update the cluster."""
show_deprecated('senlin cluster-update', 'openstack cluster update')
cluster = service.get_cluster(args.id)
attrs = {
'name': args.name,
@@ -508,6 +542,7 @@ def do_cluster_update(service, args):
help=_('Name or ID of cluster to show.'))
def do_cluster_show(service, args):
"""Show details of the cluster."""
show_deprecated('senlin cluster-show', 'openstack cluster show')
_show_cluster(service, args.id)
@@ -526,7 +561,8 @@ def do_cluster_show(service, args):
help=_('Name or ID of cluster to nodes from.'))
def do_cluster_node_list(service, args):
"""List nodes from cluster."""
show_deprecated('senlin cluster-node-list',
'openstack cluster node members list')
queries = {
'cluster_id': args.id,
'limit': args.limit,
@@ -555,6 +591,8 @@ def do_cluster_node_list(service, args):
help=_('Name or ID of cluster to operate on.'))
def do_cluster_node_add(service, args):
"""Add specified nodes to cluster."""
show_deprecated('senlin cluster-node-add',
'openstack cluster node members add')
node_ids = args.nodes.split(',')
resp = service.cluster_add_nodes(args.id, node_ids)
print('Request accepted by action: %s' % resp['action'])
@@ -567,6 +605,8 @@ def do_cluster_node_add(service, args):
help=_('Name or ID of cluster to operate on.'))
def do_cluster_node_del(service, args):
"""Delete specified nodes from cluster."""
show_deprecated('senlin cluster-node-del',
'openstack cluster node members del')
node_ids = args.nodes.split(',')
resp = service.cluster_del_nodes(args.id, node_ids)
print('Request accepted by action: %s' % resp['action'])
@@ -599,7 +639,7 @@ def do_cluster_resize(service, args):
"""Resize a cluster."""
# validate parameters
# NOTE: this will be much simpler if cliutils supports exclusive groups
show_deprecated('senlin cluster-resize', 'openstack cluster resize')
action_args = {}
capacity = args.capacity
@@ -672,6 +712,7 @@ def do_cluster_resize(service, args):
help=_('Name or ID of cluster to operate on.'))
def do_cluster_scale_out(service, args):
"""Scale out a cluster by the specified number of nodes."""
show_deprecated('senlin cluster-scale-out', 'openstack cluster scale out')
resp = service.cluster_scale_out(args.id, args.count)
print('Request accepted by action %s' % resp['action'])
@@ -682,6 +723,7 @@ def do_cluster_scale_out(service, args):
help=_('Name or ID of cluster to operate on.'))
def do_cluster_scale_in(service, args):
"""Scale in a cluster by the specified number of nodes."""
show_deprecated('senlin cluster-scale-in', 'openstack cluster scale in')
resp = service.cluster_scale_in(args.id, args.count)
print('Request accepted by action %s' % resp['action'])
@@ -693,14 +735,16 @@ def do_cluster_scale_in(service, args):
action='append')
@utils.arg('-o', '--sort', metavar='<SORT_STRING>',
help=_('Sorting option which is a string containing a list of keys '
'separated by commas. Each key can be optionally appened by '
'a sort direction (:asc or :desc)'))
'separated by commas. Each key can be optionally appended '
'by a sort direction (:asc or :desc)'))
@utils.arg('-F', '--full-id', default=False, action="store_true",
help=_('Print full IDs in list.'))
@utils.arg('id', metavar='<CLUSTER>',
help=_('Name or ID of cluster to query on.'))
def do_cluster_policy_list(service, args):
"""List policies from cluster."""
show_deprecated('senlin cluster-policy-list',
'openstack cluster policy binding list')
fields = ['policy_id', 'policy_name', 'policy_type', 'enabled']
cluster = service.get_cluster(args.id)
@@ -729,6 +773,8 @@ def do_cluster_policy_list(service, args):
help=_('ID or name of the cluster to query on.'))
def do_cluster_policy_show(service, args):
"""Show a specific policy that is bound to the specified cluster."""
show_deprecated('senlin cluster-policy-show',
'openstack cluster policy binding show')
binding = service.get_cluster_policy(args.policy, args.id)
utils.print_dict(binding.to_dict())
@@ -742,6 +788,8 @@ def do_cluster_policy_show(service, args):
help=_('Name or ID of cluster to operate on.'))
def do_cluster_policy_attach(service, args):
"""Attach policy to cluster."""
show_deprecated('senlin cluster-policy-attach',
'openstack cluster policy attach')
kwargs = {
'enabled': args.enabled,
}
@@ -756,6 +804,8 @@ def do_cluster_policy_attach(service, args):
help=_('Name or ID of cluster to operate on.'))
def do_cluster_policy_detach(service, args):
"""Detach policy from cluster."""
show_deprecated('senlin cluster-policy-detach',
'openstack cluster policy detach')
resp = service.cluster_detach_policy(args.id, args.policy)
print('Request accepted by action %s' % resp['action'])
@@ -768,6 +818,8 @@ def do_cluster_policy_detach(service, args):
help=_('Name or ID of cluster to operate on.'))
def do_cluster_policy_update(service, args):
"""Update a policy's properties on a cluster."""
show_deprecated('senlin cluster-policy-update',
'openstack cluster policy binding update')
kwargs = {
'enabled': args.enabled,
}
@@ -780,6 +832,7 @@ def do_cluster_policy_update(service, args):
help=_('ID or name of cluster(s) to operate on.'))
def do_cluster_check(service, args):
"""Check the cluster(s)."""
show_deprecated('senlin cluster-check', 'openstack cluster check')
for cid in args.id:
resp = service.check_cluster(cid)
print('Cluster check request on cluster %(cid)s is accepted by '
@@ -790,6 +843,7 @@ def do_cluster_check(service, args):
help=_('ID or name of cluster(s) to operate on.'))
def do_cluster_recover(service, args):
"""Recover the cluster(s)."""
show_deprecated('senlin cluster-recover', 'openstack cluster recover')
for cid in args.id:
resp = service.recover_cluster(cid)
print('Cluster recover request on cluster %(cid)s is accepted by '
@@ -808,8 +862,8 @@ def do_cluster_recover(service, args):
action='append')
@utils.arg('-o', '--sort', metavar='<KEY:DIR>',
help=_('Sorting option which is a string containing a list of keys '
'separated by commas. Each key can be optionally appened by '
'a sort direction (:asc or :desc)'))
'separated by commas. Each key can be optionally appended '
'by a sort direction (:asc or :desc)'))
@utils.arg('-l', '--limit', metavar='<LIMIT>',
help=_('Limit the number of nodes returned.'))
@utils.arg('-m', '--marker', metavar='<ID>',
@@ -822,6 +876,7 @@ def do_cluster_recover(service, args):
help=_('Print full IDs in list.'))
def do_node_list(service, args):
"""Show list of nodes."""
show_deprecated('senlin node-list', 'openstack cluster node list')
fields = ['id', 'name', 'index', 'status', 'cluster_id', 'physical_id',
'profile_name', 'created_at', 'updated_at']
@@ -855,7 +910,6 @@ def do_node_list(service, args):
def _show_node(service, node_id, show_details=False):
"""Show detailed info about the specified node."""
args = {'show_details': True} if show_details else None
try:
node = service.get_node(node_id, args=args)
@@ -889,6 +943,7 @@ def _show_node(service, node_id, show_details=False):
help=_('Name of the node to create.'))
def do_node_create(service, args):
"""Create the node."""
show_deprecated('senlin node-create', 'openstack cluster node create')
attrs = {
'name': args.name,
'cluster_id': args.cluster,
@@ -907,6 +962,7 @@ def do_node_create(service, args):
help=_('Name or ID of the node to show the details for.'))
def do_node_show(service, args):
"""Show detailed info about the specified node."""
show_deprecated('senlin node-show', 'openstack cluster node show')
_show_node(service, args.id, args.details)
@@ -914,6 +970,7 @@ def do_node_show(service, args):
help=_('Name or ID of node(s) to delete.'))
def do_node_delete(service, args):
"""Delete the node(s)."""
show_deprecated('senlin node-delete', 'openstack cluster node delete')
failure_count = 0
for nid in args.id:
@@ -943,6 +1000,7 @@ def do_node_delete(service, args):
help=_('Name or ID of node to update.'))
def do_node_update(service, args):
"""Update the node."""
show_deprecated('senlin node-update', 'openstack cluster node update')
# Find the node first, we need its UUID
try:
node = service.get_node(args.id)
@@ -964,6 +1022,7 @@ def do_node_update(service, args):
help=_('ID of node(s) to check.'))
def do_node_check(service, args):
"""Check the node(s)."""
show_deprecated('senlin node-check', 'openstack cluster node check')
failure_count = 0
for nid in args.id:
@@ -982,6 +1041,7 @@ def do_node_check(service, args):
help=_('ID of node(s) to recover.'))
def do_node_recover(service, args):
"""Recover the node(s)."""
show_deprecated('senlin node-recover', 'openstack cluster node recover')
failure_count = 0
for nid in args.id:
@@ -1010,8 +1070,8 @@ def do_node_recover(service, args):
help=_('Only return receivers that appear after the given ID.'))
@utils.arg('-o', '--sort', metavar='<KEY:DIR>',
help=_('Sorting option which is a string containing a list of keys '
'separated by commas. Each key can be optionally appened by '
'a sort direction (:asc or :desc)'))
'separated by commas. Each key can be optionally appended '
'by a sort direction (:asc or :desc)'))
@utils.arg('-g', '--global-project', default=False, action="store_true",
help=_('Indicate that the list should include receivers from'
' all projects. This option is subject to access policy '
@@ -1020,6 +1080,7 @@ def do_node_recover(service, args):
help=_('Print full IDs in list.'))
def do_receiver_list(service, args):
"""List receivers that meet the criteria."""
show_deprecated('senlin receiver-list', 'openstack cluster receiver list')
fields = ['id', 'name', 'type', 'cluster_id', 'action', 'created_at']
queries = {
'limit': args.limit,
@@ -1063,6 +1124,7 @@ def _show_receiver(service, receiver_id):
help=_('Name or ID of the receiver to show.'))
def do_receiver_show(service, args):
"""Show the receiver details."""
show_deprecated('senlin receiver-show', 'openstack cluster receiver show')
_show_receiver(service, receiver_id=args.id)
@@ -1080,6 +1142,8 @@ def do_receiver_show(service, args):
help=_('Name of the receiver to create.'))
def do_receiver_create(service, args):
"""Create a receiver."""
show_deprecated('senlin receiver-create',
'openstack cluster receiver create')
params = {
'name': args.name,
@@ -1097,6 +1161,8 @@ def do_receiver_create(service, args):
help=_('Name or ID of receiver(s) to delete.'))
def do_receiver_delete(service, args):
"""Delete receiver(s)."""
show_deprecated('senlin receiver-delete',
'openstack cluster receiver delete')
failure_count = 0
for wid in args.id:
@@ -1125,8 +1191,8 @@ def do_receiver_delete(service, args):
help=_('Only return events that appear after the given event ID.'))
@utils.arg('-o', '--sort', metavar='<KEY:DIR>',
help=_('Sorting option which is a string containing a list of keys '
'separated by commas. Each key can be optionally appened by '
'a sort direction (:asc or :desc)'))
'separated by commas. Each key can be optionally appended '
'by a sort direction (:asc or :desc)'))
@utils.arg('-g', '--global-project', default=False, action="store_true",
help=_('Whether events from all projects should be listed. '
' Default to False. Setting this to True may demand '
@@ -1135,7 +1201,7 @@ def do_receiver_delete(service, args):
help=_('Print full IDs in list.'))
def do_event_list(service, args):
"""List events."""
show_deprecated('senlin event-list', 'openstack cluster event list')
fields = ['id', 'timestamp', 'obj_type', 'obj_id', 'obj_name', 'action',
'status', 'status_reason', 'level']
queries = {
@@ -1161,6 +1227,7 @@ def do_event_list(service, args):
help=_('ID of event to display details for.'))
def do_event_show(service, args):
"""Describe the event."""
show_deprecated('senlin event-show', 'openstack cluster event show')
try:
event = service.get_event(args.id)
except sdk_exc.ResourceNotFound:
@@ -1179,8 +1246,8 @@ def do_event_show(service, args):
action='append')
@utils.arg('-o', '--sort', metavar='<KEY:DIR>',
help=_('Sorting option which is a string containing a list of keys '
'separated by commas. Each key can be optionally appened by '
'a sort direction (:asc or :desc)'))
'separated by commas. Each key can be optionally appended '
'by a sort direction (:asc or :desc)'))
@utils.arg('-l', '--limit', metavar='<LIMIT>',
help=_('Limit the number of actions returned.'))
@utils.arg('-m', '--marker', metavar='<ID>',
@@ -1189,7 +1256,7 @@ def do_event_show(service, args):
help=_('Print full IDs in list.'))
def do_action_list(service, args):
"""List actions."""
show_deprecated('senlin action-list', 'openstack cluster action list')
fields = ['id', 'name', 'action', 'status', 'target', 'depends_on',
'depended_by', 'created_at']
@@ -1229,6 +1296,7 @@ def do_action_list(service, args):
help=_('Name or ID of the action to show the details for.'))
def do_action_show(service, args):
"""Show detailed info about the specified action."""
show_deprecated('senlin action-show', 'openstack cluster action show')
try:
action = service.get_action(args.id)
except sdk_exc.ResourceNotFound:

View File

@@ -27,55 +27,57 @@ console_scripts =
senlin = senlinclient.shell:main
openstack.cli.extension =
clustering = senlinclient.osc.plugin
clustering = senlinclient.plugin
openstack.clustering.v1 =
cluster_action_list = senlinclient.osc.v1.action:ListAction
cluster_action_show = senlinclient.osc.v1.action:ShowAction
cluster_build_info = senlinclient.osc.v1.build_info:BuildInfo
cluster_check = senlinclient.osc.v1.cluster:CheckCluster
cluster_create = senlinclient.osc.v1.cluster:CreateCluster
cluster_delete = senlinclient.osc.v1.cluster:DeleteCluster
cluster_event_list = senlinclient.osc.v1.event:ListEvent
cluster_event_show = senlinclient.osc.v1.event:ShowEvent
cluster_list = senlinclient.osc.v1.cluster:ListCluster
cluster_members_list = senlinclient.osc.v1.cluster:ClusterNodeList
cluster_members_add = senlinclient.osc.v1.cluster:ClusterNodeAdd
cluster_members_del = senlinclient.osc.v1.cluster:ClusterNodeDel
cluster_node_create = senlinclient.osc.v1.node:CreateNode
cluster_node_delete = senlinclient.osc.v1.node:DeleteNode
cluster_node_list = senlinclient.osc.v1.node:ListNode
cluster_node_show = senlinclient.osc.v1.node:ShowNode
cluster_node_update = senlinclient.osc.v1.node:UpdateNode
cluster_policy_attach = senlinclient.osc.v1.cluster:ClusterPolicyAttach
cluster_policy_binding_list = senlinclient.osc.v1.cluster_policy:ClusterPolicyList
cluster_policy_binding_show = senlinclient.osc.v1.cluster_policy:ClusterPolicyShow
cluster_policy_binding_update = senlinclient.osc.v1.cluster_policy:ClusterPolicyUpdate
cluster_policy_create = senlinclient.osc.v1.policy:CreatePolicy
cluster_policy_delete = senlinclient.osc.v1.policy:DeletePolicy
cluster_policy_detach = senlinclient.osc.v1.cluster:ClusterPolicyDetach
cluster_policy_list = senlinclient.osc.v1.policy:ListPolicy
cluster_policy_show = senlinclient.osc.v1.policy:ShowPolicy
cluster_policy_type_list = senlinclient.osc.v1.policy_type:PolicyTypeList
cluster_policy_type_show = senlinclient.osc.v1.policy_type:PolicyTypeShow
cluster_policy_update = senlinclient.osc.v1.policy:UpdatePolicy
cluster_profile_create = senlinclient.osc.v1.profile:CreateProfile
cluster_profile_delete = senlinclient.osc.v1.profile:DeleteProfile
cluster_profile_list = senlinclient.osc.v1.profile:ListProfile
cluster_profile_show = senlinclient.osc.v1.profile:ShowProfile
cluster_profile_type_list = senlinclient.osc.v1.profile_type:ProfileTypeList
cluster_profile_type_show = senlinclient.osc.v1.profile_type:ProfileTypeShow
cluster_profile_update = senlinclient.osc.v1.profile:UpdateProfile
cluster_receiver_create = senlinclient.osc.v1.receiver:CreateReceiver
cluster_receiver_delete = senlinclient.osc.v1.receiver:DeleteReceiver
cluster_receiver_list = senlinclient.osc.v1.receiver:ListReceiver
cluster_receiver_show = senlinclient.osc.v1.receiver:ShowReceiver
cluster_recover = senlinclient.osc.v1.cluster:RecoverCluster
cluster_resize = senlinclient.osc.v1.cluster:ResizeCluster
cluster_scale_in = senlinclient.osc.v1.cluster:ScaleInCluster
cluster_scale_out = senlinclient.osc.v1.cluster:ScaleOutCluster
cluster_show = senlinclient.osc.v1.cluster:ShowCluster
cluster_update = senlinclient.osc.v1.cluster:UpdateCluster
cluster_action_list = senlinclient.v1.action:ListAction
cluster_action_show = senlinclient.v1.action:ShowAction
cluster_build_info = senlinclient.v1.build_info:BuildInfo
cluster_check = senlinclient.v1.cluster:CheckCluster
cluster_create = senlinclient.v1.cluster:CreateCluster
cluster_delete = senlinclient.v1.cluster:DeleteCluster
cluster_event_list = senlinclient.v1.event:ListEvent
cluster_event_show = senlinclient.v1.event:ShowEvent
cluster_list = senlinclient.v1.cluster:ListCluster
cluster_members_list = senlinclient.v1.cluster:ClusterNodeList
cluster_members_add = senlinclient.v1.cluster:ClusterNodeAdd
cluster_members_del = senlinclient.v1.cluster:ClusterNodeDel
cluster_node_check = senlinclient.v1.node:CheckNode
cluster_node_create = senlinclient.v1.node:CreateNode
cluster_node_delete = senlinclient.v1.node:DeleteNode
cluster_node_list = senlinclient.v1.node:ListNode
cluster_node_recover = senlinclient.v1.node:RecoverNode
cluster_node_show = senlinclient.v1.node:ShowNode
cluster_node_update = senlinclient.v1.node:UpdateNode
cluster_policy_attach = senlinclient.v1.cluster:ClusterPolicyAttach
cluster_policy_binding_list = senlinclient.v1.cluster_policy:ClusterPolicyList
cluster_policy_binding_show = senlinclient.v1.cluster_policy:ClusterPolicyShow
cluster_policy_binding_update = senlinclient.v1.cluster_policy:ClusterPolicyUpdate
cluster_policy_create = senlinclient.v1.policy:CreatePolicy
cluster_policy_delete = senlinclient.v1.policy:DeletePolicy
cluster_policy_detach = senlinclient.v1.cluster:ClusterPolicyDetach
cluster_policy_list = senlinclient.v1.policy:ListPolicy
cluster_policy_show = senlinclient.v1.policy:ShowPolicy
cluster_policy_type_list = senlinclient.v1.policy_type:PolicyTypeList
cluster_policy_type_show = senlinclient.v1.policy_type:PolicyTypeShow
cluster_policy_update = senlinclient.v1.policy:UpdatePolicy
cluster_profile_create = senlinclient.v1.profile:CreateProfile
cluster_profile_delete = senlinclient.v1.profile:DeleteProfile
cluster_profile_list = senlinclient.v1.profile:ListProfile
cluster_profile_show = senlinclient.v1.profile:ShowProfile
cluster_profile_type_list = senlinclient.v1.profile_type:ProfileTypeList
cluster_profile_type_show = senlinclient.v1.profile_type:ProfileTypeShow
cluster_profile_update = senlinclient.v1.profile:UpdateProfile
cluster_receiver_create = senlinclient.v1.receiver:CreateReceiver
cluster_receiver_delete = senlinclient.v1.receiver:DeleteReceiver
cluster_receiver_list = senlinclient.v1.receiver:ListReceiver
cluster_receiver_show = senlinclient.v1.receiver:ShowReceiver
cluster_recover = senlinclient.v1.cluster:RecoverCluster
cluster_resize = senlinclient.v1.cluster:ResizeCluster
cluster_shrink = senlinclient.v1.cluster:ScaleInCluster
cluster_expand = senlinclient.v1.cluster:ScaleOutCluster
cluster_show = senlinclient.v1.cluster:ShowCluster
cluster_update = senlinclient.v1.cluster:UpdateCluster
[global]
setup-hooks =

View File

@@ -6,9 +6,9 @@
hacking<0.11,>=0.10.0
coverage>=3.6 # Apache-2.0
discover # BSD
fixtures>=1.3.1 # Apache-2.0/BSD
fixtures>=3.0.0 # Apache-2.0/BSD
requests-mock>=0.7.0 # Apache-2.0
mock>=1.2 # BSD
mock>=2.0 # BSD
mox3>=0.7.0 # Apache-2.0
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0
@@ -16,3 +16,4 @@ sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
testrepository>=0.0.18 # Apache-2.0/BSD
testscenarios>=0.4 # Apache-2.0/BSD
testtools>=1.4.0 # MIT
reno>=1.6.2 # Apache2

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# IMPORTANT: Cleanse existing environment varible first
# IMPORTANT: Cleanse existing environment variable first
unset OS_USERNAME
unset OS_PASSWORD
unset OS_REGION_NAME

View File

@@ -1,5 +1,5 @@
[tox]
envlist = py34,py27,pypy,pep8
envlist = py34,py27,pypy,pep8,releasenotes
minversion = 1.6
skipsdist = True
@@ -31,6 +31,9 @@ commands = python setup.py testr --coverage --testr-args='{posargs}'
commands=
python setup.py build_sphinx
[testenv:releasenotes]
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
[flake8]
show-source = True
exclude=.venv,.git,.tox,dist,*openstack/common*,*lib/python*,*egg,build