Merge pull request #1 from pkilambi/master
Add archive policy and rule commands to cli
This commit is contained in:
76
gnocchiclient/tests/functional/test_archive_policy.py
Normal file
76
gnocchiclient/tests/functional/test_archive_policy.py
Normal 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)")
|
||||
75
gnocchiclient/tests/functional/test_archive_policy_rule.py
Normal file
75
gnocchiclient/tests/functional/test_archive_policy_rule.py
Normal 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)")
|
||||
53
gnocchiclient/v1/archivepolicy.py
Normal file
53
gnocchiclient/v1/archivepolicy.py
Normal 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)
|
||||
85
gnocchiclient/v1/archivepolicycli.py
Normal file
85
gnocchiclient/v1/archivepolicycli.py
Normal 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)
|
||||
55
gnocchiclient/v1/archivepolicyrule.py
Normal file
55
gnocchiclient/v1/archivepolicyrule.py
Normal 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)
|
||||
74
gnocchiclient/v1/archivepolicyrulecli.py
Normal file
74
gnocchiclient/v1/archivepolicyrulecli.py
Normal 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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user