Merge pull request #1 from pkilambi/master

Add archive policy and rule commands to cli
This commit is contained in:
Mehdi ABAAKOUK
2015-09-03 08:05:38 +02:00
8 changed files with 431 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
# 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 tempest_lib import exceptions
from gnocchiclient.tests.functional import base
class ArchivePolicyClientTest(base.ClientTestBase):
def details_multiple(self, output_lines, with_label=False):
"""Return list of dicts with item details from cli output tables.
If with_label is True, key '__label' is added to each items dict.
For more about 'label' see OutputParser.tables().
NOTE(sileht): come from tempest-lib just because cliff use
Field instead of Property as first columun header.
"""
items = []
tables_ = self.parser.tables(output_lines)
for table_ in tables_:
if ('Field' not in table_['headers']
or 'Value' not in table_['headers']):
raise exceptions.InvalidStructure()
item = {}
for value in table_['values']:
item[value[0]] = value[1]
if with_label:
item['__label'] = table_['label']
items.append(item)
return items
def test_archive_policy_scenario(self):
# CREATE
result = self.gnocchi(
u'archivepolicy', params=u"create -a name:low"
u" -a back_window:0"
u" -d granularity:1s"
u" -d points:86400 ")
policy = self.details_multiple(result)[0]
self.assertEqual('low', policy["name"])
# GET
result = self.gnocchi(
'archivepolicy', params="show low")
policy = self.details_multiple(result)[0]
self.assertEqual("low", policy["name"])
# DELETE
result = self.gnocchi('archivepolicy',
params="delete low")
self.assertEqual("", result)
# GET FAIL
result = self.gnocchi('archivepolicy',
params="show low",
fail_ok=True, merge_stderr=True)
self.assertFirstLineStartsWith(result.split('\n'),
"Not Found (HTTP 404)")
# DELETE FAIL
result = self.gnocchi('archivepolicy',
params="delete low",
fail_ok=True, merge_stderr=True)
self.assertFirstLineStartsWith(result.split('\n'),
"Not Found (HTTP 404)")

View File

@@ -0,0 +1,75 @@
# 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 tempest_lib import exceptions
from gnocchiclient.tests.functional import base
class ArchivePolicyRuleClientTest(base.ClientTestBase):
def details_multiple(self, output_lines, with_label=False):
"""Return list of dicts with item details from cli output tables.
If with_label is True, key '__label' is added to each items dict.
For more about 'label' see OutputParser.tables().
NOTE(sileht): come from tempest-lib just because cliff use
Field instead of Property as first columun header.
"""
items = []
tables_ = self.parser.tables(output_lines)
for table_ in tables_:
if ('Field' not in table_['headers']
or 'Value' not in table_['headers']):
raise exceptions.InvalidStructure()
item = {}
for value in table_['values']:
item[value[0]] = value[1]
if with_label:
item['__label'] = table_['label']
items.append(item)
return items
def test_archive_policy_rule_scenario(self):
# CREATE
result = self.gnocchi(
u'archivepolicyrule', params=u"create -a name:test"
u" -a archive_policy_name:high"
u" -a metric_pattern:disk.io.*")
policy_rule = self.details_multiple(result)[0]
self.assertEqual('test', policy_rule["name"])
# GET
result = self.gnocchi(
'archivepolicyrule', params="show test")
policy_rule = self.details_multiple(result)[0]
self.assertEqual("test", policy_rule["name"])
# DELETE
result = self.gnocchi('archivepolicyrule',
params="delete test")
self.assertEqual("", result)
# GET FAIL
result = self.gnocchi('archivepolicyrule',
params="show test",
fail_ok=True, merge_stderr=True)
self.assertFirstLineStartsWith(result.split('\n'),
"Not Found (HTTP 404)")
# DELETE FAIL
result = self.gnocchi('archivepolicyrule',
params="delete test",
fail_ok=True, merge_stderr=True)
self.assertFirstLineStartsWith(result.split('\n'),
"Not Found (HTTP 404)")

View File

@@ -0,0 +1,53 @@
#
# 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 oslo_serialization import jsonutils
from gnocchiclient.v1 import base
class ArchivePolicyManager(base.Manager):
def list(self):
"""List archive policies
"""
url = self.client._build_url("archive_policy")
return self.client.api.get(url).json()
def get(self, policy_name):
"""Get a archive_policy
:param policy_name: Name of the archive_policy
:type policy_name: str
"""
url = self.client._build_url("archive_policy/%s" % policy_name)
return self.client.api.get(url).json()
def create(self, data):
"""Create a archive_policy
"""
url = self.client._build_url("archive_policy/")
return self.client.api.post(
url, headers={'Content-Type': "application/json"},
data=jsonutils.dumps(data)).json()
def delete(self, policy_name):
"""Delete a archive_policy
:param policy_name: ID of the archive_policy
:type policy_name: str
"""
url = self.client._build_url("archive_policy/%s" % policy_name)
self.client.api.delete(url)

View File

@@ -0,0 +1,85 @@
#
# 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 cliff import command
from cliff import lister
from cliff import show
class CliArchivePolicyList(lister.Lister):
COLS = ('name',
'back_window', 'definition', 'aggregation_methods')
def get_parser(self, prog_name, history=True):
parser = super(CliArchivePolicyList, self).get_parser(prog_name)
return parser
def take_action(self, parsed_args):
policy = self.app.client.archivepolicy.list(parsed_args)
return self.COLS, [self._2tuple(r) for r in policy]
@classmethod
def _2tuple(cls, field):
return tuple([field[k] for k in cls.COLS])
class CliArchivePolicyShow(show.ShowOne):
def get_parser(self, prog_name):
parser = super(CliArchivePolicyShow, self).get_parser(prog_name)
parser.add_argument("name",
help="Name of the archive policy")
return parser
def take_action(self, parsed_args):
res = self.app.client.archivepolicy.get(
policy_name=parsed_args.name)
return self.dict2columns(res)
class CliArchivePolicyCreate(show.ShowOne):
def get_parser(self, prog_name):
parser = super(CliArchivePolicyCreate, self).get_parser(prog_name)
parser.add_argument("-a", "--attribute", action='append',
help=("name and value of a attribute "
"separated with a ':'"))
parser.add_argument("-d", "--definition", action='append',
help=("name and value of a attribute "
"separated with a ':'"))
return parser
def take_action(self, parsed_args):
data = {}
if parsed_args.attribute:
for attr in parsed_args.attribute:
attr, __, value = attr.partition(":")
data[attr] = value
if parsed_args.definition:
definition = {}
data["definition"] = []
for attr in parsed_args.definition:
attr, __, value = attr.partition(":")
definition[attr] = value
data["definition"].append(definition)
policy = self.app.client.archivepolicy.create(data=data)
return self.dict2columns(policy)
class CliArchivePolicyDelete(command.Command):
def get_parser(self, prog_name):
parser = super(CliArchivePolicyDelete, self).get_parser(prog_name)
parser.add_argument("name",
help="Name of the archive policy")
return parser
def take_action(self, parsed_args):
self.app.client.archivepolicy.delete(parsed_args.name)

View File

@@ -0,0 +1,55 @@
#
# 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 oslo_serialization import jsonutils
from gnocchiclient.v1 import base
class ArchivePolicyRuleManager(base.Manager):
def list(self):
"""List archive policies
"""
url = self.client._build_url("archive_policy_rule")
return self.client.api.get(url).json()
def get(self, policy_rule_name):
"""Get a archive_policy
:param policy_name: Name of the archive_policy
:type policy_name: str
"""
url = self.client._build_url("archive_policy_rule/%s"
% policy_rule_name)
return self.client.api.get(url).json()
def create(self, data):
"""Create a archive_policy
"""
url = self.client._build_url("archive_policy_rule/")
return self.client.api.post(
url, headers={'Content-Type': "application/json"},
data=jsonutils.dumps(data)).json()
def delete(self, policy_rule_name):
"""Delete a archive_policy
:param policy_name: ID of the archive_policy
:type policy_name: str
"""
url = self.client._build_url("archive_policy_rule/%s"
% policy_rule_name)
self.client.api.delete(url)

View File

@@ -0,0 +1,74 @@
#
# 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 cliff import command
from cliff import lister
from cliff import show
class CliArchivePolicyRuleList(lister.Lister):
COLS = ('archive_policy_name', 'metric_pattern', 'name')
def get_parser(self, prog_name, history=True):
parser = super(CliArchivePolicyRuleList, self).get_parser(prog_name)
return parser
def take_action(self, parsed_args):
policy = self.app.client.archivepolicyrule.list(parsed_args)
return self.COLS, [self._2tuple(r) for r in policy]
@classmethod
def _2tuple(cls, field):
return tuple([field[k] for k in cls.COLS])
class CliArchivePolicyRuleShow(show.ShowOne):
def get_parser(self, prog_name):
parser = super(CliArchivePolicyRuleShow, self).get_parser(prog_name)
parser.add_argument("name",
help="Name of the archive policy rule")
return parser
def take_action(self, parsed_args):
res = self.app.client.archivepolicyrule.get(
policy_rule_name=parsed_args.name)
return self.dict2columns(res)
class CliArchivePolicyRuleCreate(show.ShowOne):
def get_parser(self, prog_name):
parser = super(CliArchivePolicyRuleCreate, self).get_parser(prog_name)
parser.add_argument("-a", "--attribute", action='append',
help=("name and value of a attribute "
"separated with a ':'"))
return parser
def take_action(self, parsed_args):
data = {}
if parsed_args.attribute:
for attr in parsed_args.attribute:
attr, __, value = attr.partition(":")
data[attr] = value
policy = self.app.client.archivepolicyrule.create(data=data)
return self.dict2columns(policy)
class CliArchivePolicyRuleDelete(command.Command):
def get_parser(self, prog_name):
parser = super(CliArchivePolicyRuleDelete, self).get_parser(prog_name)
parser.add_argument("name",
help="Name of the archive policy rule")
return parser
def take_action(self, parsed_args):
self.app.client.archivepolicyrule.delete(parsed_args.name)

View File

@@ -15,6 +15,8 @@
from keystoneclient import session as keystoneclient_session
from gnocchiclient.v1 import archivepolicy
from gnocchiclient.v1 import archivepolicyrule
from gnocchiclient.v1 import resource
@@ -42,6 +44,9 @@ class Client(object):
"""Initialize a new client for the Gnocchi v1 API."""
self.api = keystoneclient_session.Session(auth, **kwargs)
self.resource = resource.ResourceManager(self)
self.archivepolicy = archivepolicy.ArchivePolicyManager(self)
self.archivepolicyrule = archivepolicyrule.ArchivePolicyRuleManager(
self)
self.interface = interface
self.region_name = region_name
self._endpoint = endpoint

View File

@@ -35,6 +35,14 @@ gnocchi.cli.v1 =
resource_create = gnocchiclient.v1.resourcecli:CliResourceCreate
resource_update = gnocchiclient.v1.resourcecli:CliResourceUpdate
resource_delete = gnocchiclient.v1.resourcecli:CliResourceDelete
archivepolicy_list = gnocchiclient.v1.archivepolicycli:CliArchivePolicyList
archivepolicy_show = gnocchiclient.v1.archivepolicycli:CliArchivePolicyShow
archivepolicy_create = gnocchiclient.v1.archivepolicycli:CliArchivePolicyCreate
archivepolicy_delete = gnocchiclient.v1.archivepolicycli:CliArchivePolicyDelete
archivepolicyrule_list = gnocchiclient.v1.archivepolicyrulecli:CliArchivePolicyRuleList
archivepolicyrule_show = gnocchiclient.v1.archivepolicyrulecli:CliArchivePolicyRuleShow
archivepolicyrule_create = gnocchiclient.v1.archivepolicyrulecli:CliArchivePolicyRuleCreate
archivepolicyrule_delete = gnocchiclient.v1.archivepolicyrulecli:CliArchivePolicyRuleDelete
keystoneclient.auth.plugin =
gnocchi-noauth = gnocchiclient.noauth:GnocchiNoAuthPlugin