Retire Packaging Deb project repos
This commit is part of a series to retire the Packaging Deb project. Step 2 is to remove all content from the project repos, replacing it with a README notification where to find ongoing work, and how to recover the repo if needed at some future point (as in https://docs.openstack.org/infra/manual/drivers.html#retiring-a-project). Change-Id: I431ed20740926bc6101cb607a0b3d6d8b6ccdcd5
This commit is contained in:
parent
6b6c4843ea
commit
853d025f9b
18
.gitignore
vendored
18
.gitignore
vendored
@ -1,18 +0,0 @@
|
||||
.coverage*
|
||||
.venv
|
||||
cover
|
||||
*.pyc
|
||||
AUTHORS
|
||||
build
|
||||
dist
|
||||
run_tests.err.log
|
||||
.tox
|
||||
doc/source/api
|
||||
*.egg
|
||||
monclient/versioninfo
|
||||
*.egg-info
|
||||
*.log
|
||||
.testrepository
|
||||
.pydevproject
|
||||
.project
|
||||
.idea
|
@ -1,4 +0,0 @@
|
||||
[gerrit]
|
||||
host=review.openstack.org
|
||||
port=29418
|
||||
project=openstack/python-monascaclient.git
|
@ -1,9 +0,0 @@
|
||||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-160} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ $OS_TEST_PATH $LISTOPT $IDOPTION
|
||||
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
||||
group_regex=monascaclient\.tests(?:\.|_)([^_]+)
|
@ -1,17 +0,0 @@
|
||||
If you would like to contribute to the development of OpenStack, you must
|
||||
follow the steps in this page:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html
|
||||
|
||||
If you already have a good understanding of how the system works and your
|
||||
OpenStack accounts are set up, you can skip to the development workflow
|
||||
section of this documentation to learn how changes to OpenStack should be
|
||||
submitted for review via the Gerrit tool:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||
|
||||
Pull requests submitted through GitHub will be ignored.
|
||||
|
||||
Bugs should be filed on Launchpad, not GitHub:
|
||||
|
||||
https://bugs.launchpad.net/monasca
|
@ -1,4 +0,0 @@
|
||||
python-monascaclient Style Commandments
|
||||
===============================================
|
||||
|
||||
Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/
|
175
LICENSE
175
LICENSE
@ -1,175 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
14
README
Normal file
14
README
Normal file
@ -0,0 +1,14 @@
|
||||
This project is no longer maintained.
|
||||
|
||||
The contents of this repository are still available in the Git
|
||||
source code management system. To see the contents of this
|
||||
repository before it reached its end of life, please check out the
|
||||
previous commit with "git checkout HEAD^1".
|
||||
|
||||
For ongoing work on maintaining OpenStack packages in the Debian
|
||||
distribution, please see the Debian OpenStack packaging team at
|
||||
https://wiki.debian.org/OpenStack/.
|
||||
|
||||
For any further questions, please email
|
||||
openstack-dev@lists.openstack.org or join #openstack-dev on
|
||||
Freenode.
|
437
README.rst
437
README.rst
@ -1,437 +0,0 @@
|
||||
========================
|
||||
Team and repository tags
|
||||
========================
|
||||
|
||||
.. image:: https://governance.openstack.org/badges/python-monascaclient.svg
|
||||
:target: https://governance.openstack.org/reference/tags/index.html
|
||||
|
||||
.. Change things from this point on
|
||||
|
||||
Python bindings to the Monasca API
|
||||
=======================================
|
||||
|
||||
This is a client library for Monasca built to interface with the Monasca API. It
|
||||
provides a Python API (the ``monascaclient`` module) and a command-line tool
|
||||
(``monasca``).
|
||||
|
||||
The Monasca Client was written using the OpenStack Heat Python client as a framework.
|
||||
|
||||
.. contents:: Contents:
|
||||
:local:
|
||||
|
||||
Ubuntu Install
|
||||
--------------
|
||||
Requires:
|
||||
- pip - version >= 1.4. python get-pip.py
|
||||
|
||||
See versions on PYPI:
|
||||
https://pypi.python.org/pypi/python-monascaclient/
|
||||
|
||||
Install It:
|
||||
- sudo pip install python-monascaclient
|
||||
|
||||
Alternative Manual Install Steps:
|
||||
- cd to your python-monascaclient repo
|
||||
- sudo pip install -r requirements.txt
|
||||
- python setup.py install
|
||||
|
||||
Building and Packaging
|
||||
----------------------
|
||||
Install the tool dependencies
|
||||
sudo apt-get install python-pip python-virtualenv
|
||||
|
||||
In the python-monascaclient source directory
|
||||
virtualenv --no-site-packages .venv
|
||||
|
||||
source ./.venv/bin/activate
|
||||
|
||||
pip install wheel
|
||||
|
||||
python setup.py bdist_wheel
|
||||
|
||||
pip install $(ls -1rt dist/*.whl | tail -1) --upgrade
|
||||
|
||||
Command-line API
|
||||
----------------
|
||||
Installing this distribution gets you a shell command, ``monasca``, that you
|
||||
can use to interact with the Monitoring API server.
|
||||
|
||||
Usage:
|
||||
monasca
|
||||
|
||||
monasca help
|
||||
|
||||
monasca help <command>
|
||||
|
||||
monasca -j <command>
|
||||
|
||||
This outputs the results in json format. Normally output is in table format.
|
||||
|
||||
|
||||
The monascaclient CLI needs the Monasca API endpoint url and the OS_AUTH_TOKEN to pass to the
|
||||
Monasca API RESTful interface. This is provided through environment or CLI
|
||||
parameters.
|
||||
|
||||
Environmental Variables
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Environmental variables can be sourced, or optionally passed in as CLI arguments.
|
||||
It is easiest to source them first and then use the CLI.
|
||||
|
||||
When token and endpoint are known::
|
||||
|
||||
export OS_AUTH_TOKEN=XXX
|
||||
export MONASCA_API_URL=http://192.168.10.4:8070/v2.0/
|
||||
|
||||
When using Keystone to obtain the token and endpoint::
|
||||
|
||||
export OS_USERNAME=
|
||||
export OS_PASSWORD=
|
||||
export OS_USER_DOMAIN_NAME=
|
||||
export OS_PROJECT_NAME=
|
||||
export OS_AUTH_URL=
|
||||
export OS_REGION_NAME=
|
||||
# Optional(specific version added to OS_AUTH_URL if (v2.0 or v3) not present already)
|
||||
export OS_AUTH_VERSION=
|
||||
|
||||
When OS_USER_DOMAIN_NAME is not set, then 'Default' is assumed. Alternatively IDs can be used instead of names.
|
||||
Although *deprecated*, but OS_TENANT_NAME and OS_TENANT_ID can be used for
|
||||
OS_PROEJCT_NAME and OS_PROJECT_ID respectively.
|
||||
|
||||
When using Vagrant Environment with middleware disabled::
|
||||
|
||||
export OS_AUTH_TOKEN=82510970543135
|
||||
export OS_NO_CLIENT_AUTH=1
|
||||
export MONASCA_API_URL=http://192.168.10.4:8070/v2.0/
|
||||
|
||||
The Monasca API will treat the auth token as the tenant ID when Keystone is not enabled.
|
||||
|
||||
You'll find complete documentation on the shell by running
|
||||
``monasca help``::
|
||||
|
||||
usage: monasca [-j] [--version] [-d] [-v] [-k] [--cert-file CERT_FILE]
|
||||
[--key-file KEY_FILE] [--os-cacert OS_CACERT]
|
||||
[--timeout TIMEOUT] [--os-username OS_USERNAME]
|
||||
[--os-password OS_PASSWORD] [--os-project-id OS_PROJECT_ID]
|
||||
[--os-user-domain-id OS_USER_DOMAIN_ID] [--os-user-domain-name OS_USER_DOMAIN_NAME]
|
||||
[--os-project-name OS_PROJECT_NAME]
|
||||
[--os-project-domain-id OS_PROJECT_DOMAIN_ID] [--os-project-domain-name OS_PROJECT_DOMAIN_NAME]
|
||||
[--os-auth-url OS_AUTH_URL] [--os-auth-version OS_AUTH_VERSION] [--os-region-name OS_REGION_NAME]
|
||||
[--os-auth-token OS_AUTH_TOKEN] [--os-no-client-auth]
|
||||
[--monasca-api-url MONASCA_API_URL]
|
||||
[--monasca-api-version MONASCA_API_VERSION]
|
||||
[--os-service-type OS_SERVICE_TYPE]
|
||||
[--os-endpoint-type OS_ENDPOINT_TYPE]
|
||||
<subcommand> ...
|
||||
|
||||
Command-line interface to the monasca-client API.
|
||||
|
||||
positional arguments:
|
||||
<subcommand>
|
||||
alarm-definition-create Create an alarm definition.
|
||||
alarm-definition-delete Delete the alarm definition.
|
||||
alarm-definition-list List alarm definitions for this tenant.
|
||||
alarm-definition-patch Patch the alarm definition.
|
||||
alarm-definition-show Describe the alarm definition.
|
||||
alarm-definition-update Update the alarm definition.
|
||||
alarm-delete Delete the alarm.
|
||||
alarm-history Alarm state history.
|
||||
alarm-history-list List alarms state history.
|
||||
alarm-list List alarms for this tenant.
|
||||
alarm-patch Patch the alarm.
|
||||
alarm-show Describe the alarm.
|
||||
alarm-update Update the alarm.
|
||||
dimension-name-list List names of dimensions.
|
||||
dimension-value-list List the dimension values for a given dimension name.
|
||||
measurement-list List measurements for the specified metric.
|
||||
metric-create Create metric.
|
||||
metric-create-raw Create metric from raw json body.
|
||||
metric-list List metrics for this tenant.
|
||||
metric-name-list List names of metrics.
|
||||
metric-statistics List measurement statistics for the specified metric.
|
||||
notification-create Create notification.
|
||||
notification-delete Delete notification.
|
||||
notification-list List notifications for this tenant.
|
||||
notification-patch Patch notification.
|
||||
notification-show Describe the notification.
|
||||
notification-update Update notification.
|
||||
bash-completion Prints all of the commands and options to stdout.
|
||||
help Display help about this program or one of its
|
||||
subcommands.
|
||||
|
||||
optional arguments:
|
||||
-j, --json output raw json response
|
||||
--version Shows the client version and exits.
|
||||
-d, --debug Defaults to env[MONASCA_DEBUG].
|
||||
-v, --verbose Print more verbose output.
|
||||
-k, --insecure Explicitly allow the client to perform "insecure" SSL
|
||||
(https) requests. The server's certificate will not
|
||||
be verified against any certificate authorities. This
|
||||
option should be used with caution.
|
||||
--cert-file CERT_FILE Path of certificate file to use in SSL connection.
|
||||
This file can optionally be prepended with the
|
||||
private key.
|
||||
--key-file KEY_FILE Path of client key to use in SSL connection.This
|
||||
option is not necessary if your key is prepended to
|
||||
your cert file.
|
||||
--os-cacert OS_CACERT Specify a CA bundle file to use in verifying a
|
||||
TLS (https) server certificate. Defaults to
|
||||
env[OS_CACERT]. Without either of these, the
|
||||
client looks for the default system CA
|
||||
certificates.
|
||||
--timeout TIMEOUT Number of seconds to wait for a response.
|
||||
--os-username OS_USERNAME Defaults to env[OS_USERNAME].
|
||||
--os-password OS_PASSWORD Defaults to env[OS_PASSWORD].
|
||||
--os-project-id OS_PROJECT_ID
|
||||
Defaults to env[OS_PROJECT_ID].
|
||||
--os-project-name OS_PROJECT_NAME
|
||||
Defaults to env[OS_PROJECT_NAME].
|
||||
--os-domain-id OS_DOMAIN_ID
|
||||
Defaults to env[OS_DOMAIN_ID].
|
||||
--os-domain-name OS_DOMAIN_NAME
|
||||
Defaults to env[OS_DOMAIN_NAME].
|
||||
--os-auth-url OS_AUTH_URL Defaults to env[OS_AUTH_URL].
|
||||
--os-auth-version OS_AUTH_VERSION
|
||||
Defaults to env[OS_AUTH_VERSION].
|
||||
--os-region-name OS_REGION_NAME
|
||||
Defaults to env[OS_REGION_NAME].
|
||||
--os-auth-token OS_AUTH_TOKEN
|
||||
Defaults to env[OS_AUTH_TOKEN].
|
||||
--os-no-client-auth Do not contact keystone for a token. Defaults to
|
||||
env[OS_NO_CLIENT_AUTH].
|
||||
--monasca-api-url MONASCA_API_URL
|
||||
Defaults to env[MONASCA_API_URL].
|
||||
--monasca-api-version MONASCA_API_VERSION
|
||||
Defaults to env[MONASCA_API_VERSION] or 2_0
|
||||
--os-service-type OS_SERVICE_TYPE
|
||||
Defaults to env[OS_SERVICE_TYPE].
|
||||
--os-endpoint-type OS_ENDPOINT_TYPE
|
||||
Defaults to env[OS_ENDPOINT_TYPE].
|
||||
|
||||
See "mon help COMMAND" for help on a specific command.
|
||||
|
||||
|
||||
Bash Completion
|
||||
~~~~~~~~~~~~~~~
|
||||
Basic command tab completion can be enabled by sourcing the bash completion script.
|
||||
::
|
||||
|
||||
source /usr/local/share/monasca.bash_completion
|
||||
|
||||
|
||||
Metrics Examples
|
||||
~~~~~~~~~~~~~~~~
|
||||
Note: To see complete usage: 'monasca help' and 'monasca help <command>'
|
||||
|
||||
metric-create::
|
||||
|
||||
monasca metric-create cpu1 123.40
|
||||
monasca metric-create metric1 1234.56 --dimensions instance_id=123,service=ourservice
|
||||
monasca metric-create metric1 2222.22 --dimensions instance_id=123,service=ourservice
|
||||
monasca metric-create metric1 3333.33 --dimensions instance_id=222,service=ourservice
|
||||
monasca metric-create metric1 4444.44 --dimensions instance_id=222 --value-meta rc=404
|
||||
|
||||
metric-list::
|
||||
|
||||
monasca metric-list
|
||||
+---------+--------------------+
|
||||
| name | dimensions |
|
||||
+---------+--------------------+
|
||||
| cpu1 | |
|
||||
| metric1 | instance_id:123 |
|
||||
| | service:ourservice |
|
||||
+---------+--------------------+
|
||||
|
||||
measurement-list::
|
||||
|
||||
monasca measurement-list metric1 2014-01-01T00:00:00Z
|
||||
+---------+--------------------+----------------+----------------------+--------------+-------------+
|
||||
| name | dimensions | measurement_id | timestamp | value | value_meta |
|
||||
+---------+--------------------+----------------+----------------------+--------------+-------------+
|
||||
| metric1 | instance_id:123 | 723885 | 2014-05-08T21:46:32Z | 1234.56 | |
|
||||
| | service:ourservice | 725951 | 2014-05-08T21:48:50Z | 2222.22 | |
|
||||
| metric1 | instance_id:222 | 726837 | 2014-05-08T21:49:47Z | 3333.33 | |
|
||||
| | service:ourservice | 726983 | 2014-05-08T21:50:27Z | 4444.44 | rc: 404 |
|
||||
+---------+--------------------+----------------+----------------------+--------------+-------------+
|
||||
|
||||
monasca measurement-list metric1 2014-01-01T00:00:00Z --dimensions instance_id=123
|
||||
+---------+--------------------+----------------+----------------------+--------------+-------------+
|
||||
| name | dimensions | measurement_id | timestamp | value | value_meta |
|
||||
+---------+--------------------+----------------+----------------------+--------------+-------------+
|
||||
| metric1 | instance_id:123 | 723885 | 2014-05-08T21:46:32Z | 1234.56 | |
|
||||
| | service:ourservice | 725951 | 2014-05-08T21:48:50Z | 2222.22 | |
|
||||
+---------+--------------------+----------------+----------------------+--------------+-------------+
|
||||
|
||||
|
||||
Notifications Examples
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
Note: To see complete usage: 'monasca help' and 'monasca help <command>'
|
||||
|
||||
notification-create::
|
||||
|
||||
monasca notification-create cindyemail1 EMAIL cindy.employee@hp.com
|
||||
monasca notification-create myapplication WEBHOOK http://localhost:5000
|
||||
monasca notification-create mypagerduty PAGERDUTY nzH2LVRdMzun11HNC2oD
|
||||
|
||||
notification-list::
|
||||
|
||||
monasca notification-list
|
||||
+---------------+--------------------------------------+-------+----------------------+
|
||||
| name | id | type | address |
|
||||
+---------------+--------------------------------------+-------+----------------------+
|
||||
| cindyemail1 | 5651406c-447d-40bd-b868-b2b3e6b59e32 | EMAIL |cindy.employee@hp.com |
|
||||
| myapplication | 55905ce2-91e3-41ce-b45a-de7032f8d718 | WEBHOOK |http://localhost:5000
|
||||
| mypagerduty | 5720ccb5-6a3d-22ba-545g-ce467a5b41a2 | PAGERDUTY |nzH2LVRdMzun11HNC2oD
|
||||
+---------------+--------------------------------------+-------+----------------------+
|
||||
|
||||
|
||||
Alarms Examples
|
||||
~~~~~~~~~~~~~~~
|
||||
Note: To see complete usage: 'monasca help' and 'monasca help <command>'
|
||||
|
||||
alarm-definition-create::
|
||||
|
||||
monasca alarm-definition-create alarmPerHost "max(cpu.load_avg_1_min) > 0" --match-by hostname
|
||||
|
||||
alarm-definition-list::
|
||||
|
||||
+--------------+--------------------------------------+-----------------------------+----------+-----------------+
|
||||
| name | id | expression | match_by | actions_enabled |
|
||||
+--------------+--------------------------------------+-----------------------------+----------+-----------------+
|
||||
| alarmPerHost | 4bf6bfc2-c5ac-4d57-b7db-cf5313b05412 | max(cpu.load_avg_1_min) > 0 | hostname | True |
|
||||
+--------------+--------------------------------------+-----------------------------+----------+-----------------+
|
||||
|
||||
alarm-definition-show::
|
||||
|
||||
monasca alarm-definition-show 4bf6bfc2-c5ac-4d57-b7db-cf5313b05412
|
||||
+----------------------+----------------------------------------------------------------------------------------------------+
|
||||
| Property | Value |
|
||||
+----------------------+----------------------------------------------------------------------------------------------------+
|
||||
| actions_enabled | true |
|
||||
| alarm_actions | [] |
|
||||
| description | "" |
|
||||
| expression | "max(cpu.load_avg_1_min) > 0" |
|
||||
| id | "4bf6bfc2-c5ac-4d57-b7db-cf5313b05412" |
|
||||
| links | href:http://192.168.10.4:8070/v2.0/alarm-definitions/4bf6bfc2-c5ac-4d57-b7db-cf5313b05412,rel:self |
|
||||
| match_by | [ |
|
||||
| | "hostname" |
|
||||
| | ] |
|
||||
| name | "alarmPerHost" |
|
||||
| ok_actions | [] |
|
||||
| severity | "LOW" |
|
||||
| undetermined_actions | [] |
|
||||
+----------------------+----------------------------------------------------------------------------------------------------+
|
||||
|
||||
alarm-definition-delete::
|
||||
|
||||
monasca alarm-definition-delete 4bf6bfc2-c5ac-4d57-b7db-cf5313b05412
|
||||
|
||||
alarm-list::
|
||||
|
||||
monasca alarm-list
|
||||
+--------------------------------------+--------------------------------------+----------------+---------------+---------------------+----------+-------+--------------------------+--------------------------+
|
||||
| id | alarm_definition_id | alarm_name | metric_name | metric_dimensions | severity | state | state_updated_timestamp | created_timestamp |
|
||||
+--------------------------------------+--------------------------------------+----------------+---------------+---------------------+----------+-------+--------------------------+--------------------------+
|
||||
| 11e8c15d-0263-4b71-a8b8-4ecdaeb2902c | af1f347b-cddb-46da-b7cc-924261eeecdf | High CPU usage | cpu.idle_perc | hostname: devstack | LOW | OK | 2015-03-26T21:45:15.000Z | 2015-03-26T21:41:50.000Z |
|
||||
| e5797cfe-b66e-4d44-98cd-3c7fc62d4c33 | af1f347b-cddb-46da-b7cc-924261eeecdf | High CPU usage | cpu.idle_perc | hostname: mini-mon | LOW | OK | 2015-03-26T21:43:15.000Z | 2015-03-26T21:41:47.000Z |
|
||||
| | | | | service: monitoring | | | | |
|
||||
+--------------------------------------+--------------------------------------+----------------+---------------+---------------------+----------+-------+--------------------------+--------------------------+
|
||||
|
||||
alarm-history::
|
||||
|
||||
monasca alarm-history 9d748b72-939b-45e7-a807-c0c5ad88d3e4
|
||||
+--------------------------------------+-----------+--------------+------------------------------------------------------------------------------+-------------+--------------------+---------------------+--------------------------+
|
||||
| alarm_id | new_state | old_state | reason | reason_data | metric_name | metric_dimensions | timestamp |
|
||||
+--------------------------------------+-----------+--------------+------------------------------------------------------------------------------+-------------+--------------------+---------------------+--------------------------+
|
||||
| 9d748b72-939b-45e7-a807-c0c5ad88d3e4 | ALARM | UNDETERMINED | Thresholds were exceeded for the sub-alarms: [max(cpu.load_avg_1_min) > 0.0] | {} | cpu.load_avg_1_min | hostname: mini-mon | 2014-10-14T21:14:11.000Z |
|
||||
| | | | | | | service: monitoring | |
|
||||
+--------------------------------------+-----------+--------------+------------------------------------------------------------------------------+-------------+--------------------+---------------------+--------------------------+
|
||||
|
||||
|
||||
alarm-patch::
|
||||
|
||||
monasca alarm-patch fda5537b-1550-435f-9d6c-262b7e05065b --state OK
|
||||
|
||||
|
||||
Python API
|
||||
----------
|
||||
|
||||
There's also a complete Python API.
|
||||
|
||||
In order to use the python api directly, you must pass in a valid auth token and
|
||||
monasca api endpoint, or you can pass in the credentials required by the keystone
|
||||
client and let the Python API do the authentication. The user can obtain the token
|
||||
and endpoint using the keystone client api:
|
||||
http://docs.openstack.org/developer/python-keystoneclient/.
|
||||
The service catalog name for our API endpoint is "monasca".
|
||||
|
||||
Start using the monascaclient API by constructing the monascaclient client.Client class.
|
||||
The Client class takes these parameters: api_version, endpoint, and token.
|
||||
The Client class is used to call all monasca-api resource commands (i.e.
|
||||
client.Client.metrics.create(fields)).
|
||||
|
||||
Long running users of the Client will receive an indication
|
||||
that the keystone token has expired when they receive an HTTP response
|
||||
code of 401 Unauthorized from the monasca-API. In this case, it is
|
||||
up to the user to get a new token from keystone which can be passed
|
||||
into the client.Client.replace_token(token) method. If you constructed
|
||||
the Client with all the keystone credentials needed to authenticate,
|
||||
then the API will automatically try one time to re-authenticate with
|
||||
keystone whenever the token expires.
|
||||
|
||||
The api_version matches the version of the Monasca API. Currently it is 'v2_0'.
|
||||
|
||||
When calling the commands, refer to monascaclient.v2_0.shell.py 'do_<command>'
|
||||
to see the required and optional fields for each command.
|
||||
https://github.com/openstack/python-monascaclient/blob/master/monascaclient/v2_0/shell.py
|
||||
|
||||
Refer to the example in python-monascaclient/client_api_example.py for more detail::
|
||||
|
||||
from monascaclient import client
|
||||
from monascaclient import ksclient
|
||||
import monascaclient.exc as exc
|
||||
import time
|
||||
|
||||
api_version = '2_0'
|
||||
|
||||
# Authenticate to Keystone
|
||||
keystone_url = 'http://keystone:5000/v3'
|
||||
ks = ksclient.KSClient(auth_url=keystone_url, username='user', password='password')
|
||||
|
||||
# construct the mon client
|
||||
monasca_client = client.Client(api_version, ks.monasca_url, token=ks.token)
|
||||
|
||||
# call the metric-create command
|
||||
dimensions = {'instance_id': '12345', 'service': 'hello'}
|
||||
fields = {}
|
||||
fields['name'] = 'cindy1'
|
||||
fields['dimensions'] = dimensions
|
||||
fields['timestamp'] = time.time() * 1000
|
||||
fields['value'] = 222.333
|
||||
try:
|
||||
resp = monasca_client.metrics.create(**fields)
|
||||
except exc.HTTPException as he:
|
||||
print(he.code)
|
||||
print(he.message)
|
||||
else:
|
||||
print(resp)
|
||||
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
(C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP
|
||||
|
||||
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.
|
@ -1,90 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""An example using monascaclient via the Python API"""
|
||||
|
||||
from monascaclient import client
|
||||
import monascaclient.exc as exc
|
||||
import time
|
||||
|
||||
# In order to use the python api directly, you must first obtain an
|
||||
# auth token and identify which endpoint you wish to speak to.
|
||||
endpoint = 'http://192.168.10.4:8070/v2.0'
|
||||
|
||||
# The api version of monasca-api
|
||||
api_version = '2_0'
|
||||
|
||||
# Pass in the keystone authentication kwargs to construct a monasca client.
|
||||
# The monasca_client will try to authenticate with keystone one time
|
||||
# when it sees a 401 unauthorized resp, to take care of a stale token.
|
||||
# In this example no token is input, so it will get a 401 when executing the
|
||||
# first metrics.create request, and will authenticate and try again.
|
||||
auth_kwargs = {'username': 'mini-mon',
|
||||
'password': 'password',
|
||||
'project_name': 'mini-mon',
|
||||
'auth_url': 'http://192.168.10.5:35357/v3/'}
|
||||
monasca_client = client.Client(api_version, endpoint, **auth_kwargs)
|
||||
|
||||
# you can reference the monascaclient.v2_0.shell.py
|
||||
# do_commands for command field initialization.
|
||||
|
||||
# post a metric
|
||||
dimensions = {'instance_id': '12345', 'service': 'nova'}
|
||||
fields = {}
|
||||
fields['name'] = 'metric1'
|
||||
fields['dimensions'] = dimensions
|
||||
# time in milliseconds
|
||||
fields['timestamp'] = time.time() * 1000
|
||||
fields['value'] = 222.333
|
||||
try:
|
||||
resp = monasca_client.metrics.create(**fields)
|
||||
except exc.HTTPException as he:
|
||||
print('HTTPException code=%s message=%s' % (he.code, he.message))
|
||||
else:
|
||||
print(resp)
|
||||
print('Successfully created metric')
|
||||
|
||||
# post a metric with a unicode service name
|
||||
dimensions = {'instance_id': '12345', 'service': u'\u76db\u5927'}
|
||||
fields = {}
|
||||
fields['name'] = 'metric1'
|
||||
fields['dimensions'] = dimensions
|
||||
fields['timestamp'] = time.time() * 1000
|
||||
fields['value'] = 222.333
|
||||
try:
|
||||
resp = monasca_client.metrics.create(**fields)
|
||||
except exc.HTTPException as he:
|
||||
print('HTTPException code=%s message=%s' % (he.code, he.message))
|
||||
else:
|
||||
print(resp)
|
||||
print('Successfully created metric')
|
||||
|
||||
print('Giving the DB time to update...')
|
||||
time.sleep(5)
|
||||
|
||||
# metric-list
|
||||
name = 'metric1'
|
||||
dimensions = None
|
||||
fields = {}
|
||||
if name:
|
||||
fields['name'] = name
|
||||
if dimensions:
|
||||
fields['dimensions'] = dimensions
|
||||
try:
|
||||
body = monasca_client.metrics.list(**fields)
|
||||
except exc.HTTPException as he:
|
||||
print('HTTPException code=%s message=%s' % (he.code, he.message))
|
||||
else:
|
||||
print(body)
|
@ -1,136 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||
#
|
||||
# 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 getopt
|
||||
import os
|
||||
import sys
|
||||
|
||||
from monascaclient import client
|
||||
|
||||
|
||||
def usage():
|
||||
usage = """
|
||||
Requires services.osrc variables in bash environment (OS_USERNAME etc).
|
||||
|
||||
check_monasca -d <dimension> -v <value>
|
||||
-h --help Prints this
|
||||
-d dimension Dimension to filter on
|
||||
-v value Value of dimension
|
||||
|
||||
Examples
|
||||
|
||||
check_monasca -d hostname -v test-c0-m1-mgmt # Retrieve all alarms for a host
|
||||
check_monasca -d service -v nova # Retrieve all nova alarms
|
||||
"""
|
||||
print(usage)
|
||||
|
||||
|
||||
def get_keystone_creds():
|
||||
creds = {'username': os.environ['OS_USERNAME'], 'password': os.environ['OS_PASSWORD'],
|
||||
'auth_url': os.environ['OS_AUTH_URL'], 'project_name': os.environ['OS_PROJECT_NAME'],
|
||||
'endpoint': os.environ['OS_MONASCA_URL'], 'os_cacert': os.environ['OS_CACERT']}
|
||||
return creds
|
||||
|
||||
|
||||
def format_alarm(alarm):
|
||||
output = "%s %s ( Metric = %s)" % (
|
||||
alarm['metrics'][0]['dimensions']['hostname'],
|
||||
alarm['alarm_definition']['name'],
|
||||
alarm['metrics'][0]['name'])
|
||||
if "process." in alarm['metrics'][0]['name']:
|
||||
output += "-%s," % (alarm['metrics'][0]['dimensions']['process_name'])
|
||||
if "disk." in alarm['metrics'][0]['name']:
|
||||
output += "-%s," % (alarm['metrics'][0]['dimensions']['mount_point'])
|
||||
output += ","
|
||||
return output
|
||||
|
||||
|
||||
def main(argv):
|
||||
# Initialise Variables
|
||||
warns = 0
|
||||
crits = 0
|
||||
warns_output = ""
|
||||
crits_output = ""
|
||||
dimension = ""
|
||||
dim_value = ""
|
||||
|
||||
# Test parameters
|
||||
try:
|
||||
opts, args = getopt.getopt(argv, "h::d:v:", ["dimension=", "value="])
|
||||
except getopt.GetoptError:
|
||||
usage()
|
||||
sys.exit(2)
|
||||
for opt, arg in opts:
|
||||
if opt == '-h':
|
||||
usage()
|
||||
sys.exit()
|
||||
elif opt in ("-d", "--dimension"):
|
||||
dimension = arg
|
||||
elif opt in ("-v", "--value"):
|
||||
dim_value = arg
|
||||
|
||||
if dimension == "" or dim_value == "":
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
# Set the api version of monasca-api
|
||||
api_version = '2_0'
|
||||
creds = get_keystone_creds()
|
||||
|
||||
# Build request
|
||||
dimensions = {}
|
||||
dimensions[dimension] = dim_value
|
||||
|
||||
fields = {}
|
||||
fields['metric_dimensions'] = dimensions
|
||||
monasca_client = client.Client(api_version, **creds)
|
||||
body = monasca_client.alarms.list(**fields)
|
||||
|
||||
# Process retrieved alarms
|
||||
# Note Monasca has state and severity, these are mapped to Nagios values as
|
||||
# State ALARM and severity = LOW or MEDIUM is Nagios Warning
|
||||
# State = UNDERTERMINED is Nagios Warning
|
||||
# State ALARM and severity = HIGH it Nagios Critical
|
||||
|
||||
for alarm in body:
|
||||
if alarm['lifecycle_state'] != "RESOLVED":
|
||||
if (alarm['state'] == "ALARM" and
|
||||
(alarm['alarm_definition']['severity'] == "LOW" or
|
||||
alarm['alarm_definition']['severity'] == "MEDIUM")):
|
||||
warns += 1
|
||||
warns_output += format_alarm(alarm)
|
||||
if alarm['state'] == "UNDETERMINED":
|
||||
warns += 1
|
||||
warns_output += format_alarm(alarm)
|
||||
if alarm['state'] == "ALARM" and alarm['alarm_definition']['severity'] == "HIGH":
|
||||
crits += 1
|
||||
crits_output += format_alarm(alarm)
|
||||
|
||||
if warns == 0 and crits == 0:
|
||||
print("OK")
|
||||
return
|
||||
elif warns > 0 and crits == 0:
|
||||
print(str(warns) + " WARNING - " + warns_output)
|
||||
sys.exit(1)
|
||||
elif crits > 0:
|
||||
print(str(crits) + " CRITICAL - " + crits_output + str(warns) + " WARNING - " + warns_output)
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
@ -1,36 +0,0 @@
|
||||
Nagios style monasca plugin
|
||||
===========================
|
||||
|
||||
check_monasca.py is a Nagios style plugin to query a monasca endpoint based dimensions and values. It is best called via a wrapper script that will set the following environment variables.
|
||||
|
||||
OS_USERNAME - a keystone user
|
||||
OS_PASSWORD - user password
|
||||
OS_PROJECT_NAME - Default
|
||||
OS_AUTH_URL - Keystone URL
|
||||
OS_MONASCA_URL ( note monasca URL should be something like http://192.168.1.10:8070/v2.0 )
|
||||
|
||||
Then the script should be called with the relevant dimensions and values.
|
||||
|
||||
e.g
|
||||
|
||||
check_monasca.py -d service -v nova - for all nova alarms
|
||||
check_monasca.py -d hostname -v server1 - for all alarms relating to server1.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
(C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP
|
||||
|
||||
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.
|
@ -1,70 +0,0 @@
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
|
||||
Patches method that transforms error responses.
|
||||
That is required to handle different format monasca follows.
|
||||
|
||||
"""
|
||||
|
||||
from keystoneauth1 import exceptions as exc
|
||||
from keystoneauth1.exceptions import http
|
||||
|
||||
|
||||
def mon_exc_from_response(response, method, url):
|
||||
req_id = response.headers.get('x-openstack-request-id')
|
||||
|
||||
kwargs = {
|
||||
'http_status': response.status_code,
|
||||
'response': response,
|
||||
'method': method,
|
||||
'url': url,
|
||||
'request_id': req_id,
|
||||
}
|
||||
if 'retry-after' in response.headers:
|
||||
kwargs['retry_after'] = response.headers['retry-after']
|
||||
|
||||
content_type = response.headers.get('Content-Type', '')
|
||||
if content_type.startswith('application/json'):
|
||||
try:
|
||||
body = response.json()
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
if isinstance(body, dict):
|
||||
if isinstance(body.get('error'), dict):
|
||||
error = body['error']
|
||||
kwargs['message'] = error.get('message')
|
||||
kwargs['details'] = error.get('details')
|
||||
elif {'description', 'title'} <= set(body):
|
||||
# monasca-api error response structure
|
||||
kwargs['message'] = body.get('title')
|
||||
kwargs['details'] = body.get('description')
|
||||
elif content_type.startswith('text/'):
|
||||
kwargs['details'] = response.text
|
||||
|
||||
try:
|
||||
cls = http._code_map[response.status_code]
|
||||
except KeyError:
|
||||
if 500 <= response.status_code < 600:
|
||||
cls = exc.HttpServerError
|
||||
elif 400 <= response.status_code < 500:
|
||||
cls = exc.HTTPClientError
|
||||
else:
|
||||
cls = exc.HttpError
|
||||
return cls(**kwargs)
|
||||
|
||||
|
||||
exc.from_response = mon_exc_from_response
|
@ -1,137 +0,0 @@
|
||||
# (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP
|
||||
# Copyright 2017 Fujitsu LIMITED
|
||||
#
|
||||
# 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 warnings
|
||||
|
||||
from keystoneauth1 import identity
|
||||
from keystoneauth1 import session
|
||||
|
||||
from monascaclient.osc import migration
|
||||
from monascaclient import version
|
||||
|
||||
|
||||
_NO_VALUE_MARKER = object()
|
||||
|
||||
|
||||
def Client(api_version, *args, **kwargs):
|
||||
|
||||
handle_deprecated(args, kwargs)
|
||||
|
||||
auth = _get_auth_handler(kwargs)
|
||||
sess = _get_session(auth, kwargs)
|
||||
|
||||
client = migration.make_client(
|
||||
api_version=api_version,
|
||||
session=sess,
|
||||
endpoint=kwargs.get('endpoint'),
|
||||
service_type=kwargs.get('service_type', 'monitoring')
|
||||
)
|
||||
|
||||
return client
|
||||
|
||||
|
||||
def handle_deprecated(args, kwargs):
|
||||
"""Handles all deprecations
|
||||
|
||||
Method goes through passed args and kwargs
|
||||
and handles all values that are invalid from POV
|
||||
of current client but:
|
||||
|
||||
* has their counterparts
|
||||
* are candidates to be dropped
|
||||
|
||||
"""
|
||||
kwargs.update(_handle_deprecated_args(args))
|
||||
_handle_deprecated_kwargs(kwargs)
|
||||
|
||||
|
||||
def _handle_deprecated_kwargs(kwargs):
|
||||
|
||||
depr_map = {
|
||||
'tenant_name': ('project_name', lambda x: x),
|
||||
'insecure': ('verify', lambda x: not x)
|
||||
}
|
||||
|
||||
for key, new_key_transform in depr_map.items():
|
||||
val = kwargs.get(key, _NO_VALUE_MARKER)
|
||||
if val != _NO_VALUE_MARKER:
|
||||
new_key = new_key_transform[0]
|
||||
new_handler = new_key_transform[1]
|
||||
|
||||
warnings.warn(
|
||||
'Usage of {old_key} has been deprecated in favour '
|
||||
'of {new_key}. monascaclient will place value of {old_key} '
|
||||
'under {new_key}'.format(old_key=key, new_key=new_key),
|
||||
DeprecationWarning
|
||||
)
|
||||
|
||||
kwargs[new_key] = new_handler(val)
|
||||
del kwargs[key]
|
||||
|
||||
|
||||
def _handle_deprecated_args(args):
|
||||
kwargs_update = {}
|
||||
if args is not None and len(args) > 0:
|
||||
warnings.warn(
|
||||
'Usage or args is deprecated for the sake of '
|
||||
'explicit configuration of the client using '
|
||||
'named arguments (**kwargs). '
|
||||
'That argument will be removed in future releases.',
|
||||
DeprecationWarning
|
||||
)
|
||||
# have all permissible args set here
|
||||
kwargs_update.update({
|
||||
'endpoint': args[0]
|
||||
})
|
||||
return kwargs_update
|
||||
|
||||
|
||||
def _get_session(auth, kwargs):
|
||||
return session.Session(auth=auth,
|
||||
app_name='monascaclient',
|
||||
app_version=version.version_string,
|
||||
cert=kwargs.get('cert', None),
|
||||
timeout=kwargs.get('timeout', None),
|
||||
verify=kwargs.get('verify', True))
|
||||
|
||||
|
||||
def _get_auth_handler(kwargs):
|
||||
if 'token' in kwargs:
|
||||
auth = identity.Token(
|
||||
auth_url=kwargs.get('auth_url', None),
|
||||
token=kwargs.get('token', None),
|
||||
project_id=kwargs.get('project_id', None),
|
||||
project_name=kwargs.get('project_name', None),
|
||||
project_domain_id=kwargs.get('project_domain_id', None),
|
||||
project_domain_name=kwargs.get('project_domain_name', None)
|
||||
)
|
||||
elif {'username', 'password'} <= set(kwargs):
|
||||
auth = identity.Password(
|
||||
auth_url=kwargs.get('auth_url', None),
|
||||
username=kwargs.get('username', None),
|
||||
password=kwargs.get('password', None),
|
||||
project_id=kwargs.get('project_id', None),
|
||||
project_name=kwargs.get('project_name', None),
|
||||
project_domain_id=kwargs.get('project_domain_id', None),
|
||||
project_domain_name=kwargs.get('project_domain_name', None),
|
||||
user_domain_id=kwargs.get('user_domain_id', None),
|
||||
user_domain_name=kwargs.get('user_domain_name', None)
|
||||
)
|
||||
else:
|
||||
raise Exception('monascaclient can be configured with either '
|
||||
'"token" or "username:password" but neither of '
|
||||
'them was found in passed arguments.')
|
||||
return auth
|
@ -1,65 +0,0 @@
|
||||
# (C) Copyright 2014, 2015 Hewlett Packard Enterprise Development Company LP
|
||||
# Copyright 2017 Fujitsu LIMITED
|
||||
#
|
||||
# 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 six.moves.urllib import parse
|
||||
|
||||
|
||||
class MonascaManager(object):
|
||||
base_url = None
|
||||
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
def _parse_body(self, body):
|
||||
if type(body) is dict:
|
||||
self.next = None
|
||||
for link in body['links']:
|
||||
if link['rel'] == 'next':
|
||||
self.next = link['href']
|
||||
return body['elements']
|
||||
else:
|
||||
return body
|
||||
|
||||
def _list(self, path, dim_key=None, **kwargs):
|
||||
"""Get a list of metrics."""
|
||||
url_str = self.base_url + path
|
||||
if dim_key and dim_key in kwargs:
|
||||
dim_str = self.get_dimensions_url_string(kwargs[dim_key])
|
||||
kwargs[dim_key] = dim_str
|
||||
|
||||
if kwargs:
|
||||
url_str += '?%s' % parse.urlencode(kwargs, True)
|
||||
|
||||
body = self.client.list(
|
||||
path=url_str
|
||||
)
|
||||
|
||||
return self._parse_body(body)
|
||||
|
||||
@staticmethod
|
||||
def get_dimensions_url_string(dimensions):
|
||||
dim_list = list()
|
||||
for k, v in dimensions.items():
|
||||
# In case user specifies a dimension multiple times
|
||||
if isinstance(v, (list, tuple)):
|
||||
v = v[-1]
|
||||
if v:
|
||||
dim_str = k + ':' + v
|
||||
else:
|
||||
dim_str = k
|
||||
dim_list.append(dim_str)
|
||||
return ','.join(dim_list)
|
@ -1,200 +0,0 @@
|
||||
# (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# 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 __future__ import print_function
|
||||
|
||||
import numbers
|
||||
|
||||
import prettytable
|
||||
import yaml
|
||||
|
||||
from osc_lib import exceptions as exc
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
supported_formats = {
|
||||
"json": lambda x: jsonutils.dumps(x, indent=2),
|
||||
"yaml": yaml.safe_dump
|
||||
}
|
||||
|
||||
|
||||
# Decorator for cli-args
|
||||
def arg(*args, **kwargs):
|
||||
def _decorator(func):
|
||||
# Because of the semantics of decorator composition if we just append
|
||||
# to the options list positional options will appear to be backwards.
|
||||
func.__dict__.setdefault('arguments', []).insert(0, (args, kwargs))
|
||||
return func
|
||||
return _decorator
|
||||
|
||||
|
||||
def json_formatter(js):
|
||||
return (jsonutils.dumps(js, indent=2, ensure_ascii=False)).encode('utf-8')
|
||||
|
||||
|
||||
def print_list(objs, fields, field_labels=None, formatters=None, sortby=None):
|
||||
if formatters is None:
|
||||
formatters = {}
|
||||
|
||||
field_labels = field_labels or fields
|
||||
pt = prettytable.PrettyTable([f for f in field_labels],
|
||||
caching=False, print_empty=False)
|
||||
pt.align = 'l'
|
||||
|
||||
for o in objs:
|
||||
row = []
|
||||
for field in fields:
|
||||
if field in formatters:
|
||||
row.append(formatters[field](o))
|
||||
elif isinstance(field, int):
|
||||
row.append(o[field])
|
||||
else:
|
||||
data = getattr(o, field, None) or ''
|
||||
row.append(data)
|
||||
pt.add_row(row)
|
||||
if sortby is None:
|
||||
print(pt.get_string().encode('utf-8'))
|
||||
else:
|
||||
print(pt.get_string(sortby=field_labels[sortby]).encode('utf-8'))
|
||||
|
||||
|
||||
def print_dict(d, formatters=None):
|
||||
if formatters is None:
|
||||
formatters = {}
|
||||
pt = prettytable.PrettyTable(['Property', 'Value'],
|
||||
caching=False, print_empty=False)
|
||||
pt.align = 'l'
|
||||
|
||||
for field in d.keys():
|
||||
if field in formatters:
|
||||
pt.add_row([field, formatters[field](d[field])])
|
||||
else:
|
||||
pt.add_row([field, d[field]])
|
||||
print(pt.get_string(sortby='Property').encode('utf-8'))
|
||||
|
||||
|
||||
def format_parameters(params):
|
||||
'''Reformat parameters into dict of format expected by the API.'''
|
||||
|
||||
if not params:
|
||||
return {}
|
||||
|
||||
# expect multiple invocations of --parameters but fall back
|
||||
# to ; delimited if only one --parameters is specified
|
||||
if len(params) == 1:
|
||||
if params[0].find(';') != -1: # found
|
||||
params = params[0].split(';')
|
||||
else:
|
||||
params = params[0].split(',')
|
||||
|
||||
parameters = {}
|
||||
for p in params:
|
||||
try:
|
||||
(n, v) = p.split('=', 1)
|
||||
except ValueError:
|
||||
msg = '%s(%s). %s.' % ('Malformed parameter', p,
|
||||
'Use the key=value format')
|
||||
raise exc.CommandError(msg)
|
||||
|
||||
if n not in parameters:
|
||||
parameters[n] = v
|
||||
else:
|
||||
if not isinstance(parameters[n], list):
|
||||
parameters[n] = [parameters[n]]
|
||||
parameters[n].append(v)
|
||||
|
||||
return parameters
|
||||
|
||||
|
||||
def format_dimensions_query(dims):
|
||||
if not dims:
|
||||
return {}
|
||||
|
||||
# expect multiple invocations of --parameters but fall back
|
||||
# to ; delimited if only one --parameters is specified
|
||||
if len(dims) == 1:
|
||||
if dims[0].find(';') != -1: # found
|
||||
dims = dims[0].split(';')
|
||||
else:
|
||||
dims = dims[0].split(',')
|
||||
|
||||
dimensions = {}
|
||||
for p in dims:
|
||||
try:
|
||||
(n, v) = p.split('=', 1)
|
||||
except ValueError:
|
||||
n = p
|
||||
v = ""
|
||||
|
||||
dimensions[n] = v
|
||||
|
||||
return dimensions
|
||||
|
||||
|
||||
def format_dimensions(dict):
|
||||
return 'dimensions: {\n' + format_dict(dict) + '\n}'
|
||||
|
||||
|
||||
def format_expression_data(data):
|
||||
# takes an dictionary containing a dict
|
||||
string_list = list()
|
||||
for k, v in data.items():
|
||||
if k == 'dimensions':
|
||||
dim_str = format_dimensions(v)
|
||||
string_list.append(dim_str)
|
||||
else:
|
||||
if isinstance(v, numbers.Number):
|
||||
d_str = k + ': ' + str(v)
|
||||
else:
|
||||
d_str = k + ': ' + v
|
||||
string_list.append(d_str)
|
||||
return '\n'.join(string_list)
|
||||
|
||||
|
||||
def format_dictlist(dict_list):
|
||||
# takes list of dictionaries to format for output
|
||||
string_list = list()
|
||||
for mdict in dict_list:
|
||||
kv_list = list()
|
||||
for k, v in sorted(mdict.items()):
|
||||
kv_str = k + ':' + str(v)
|
||||
kv_list.append(kv_str)
|
||||
# a string of comma separated k:v
|
||||
this_dict_str = ','.join(kv_list)
|
||||
string_list.append(this_dict_str)
|
||||
return '\n'.join(string_list)
|
||||
|
||||
|
||||
def format_dict(dict):
|
||||
# takes a dictionary to format for output
|
||||
dstring_list = list()
|
||||
for k, v in dict.items():
|
||||
if isinstance(v, numbers.Number):
|
||||
d_str = k + ': ' + str(v)
|
||||
else:
|
||||
d_str = k + ': ' + v
|
||||
dstring_list.append(d_str)
|
||||
return '\n'.join(dstring_list)
|
||||
|
||||
|
||||
def format_list(in_list):
|
||||
string_list = list()
|
||||
for k in in_list:
|
||||
if isinstance(k, unicode):
|
||||
key = k.encode('utf-8')
|
||||
else:
|
||||
key = k
|
||||
string_list.append(key)
|
||||
return '\n'.join(string_list)
|
@ -1,169 +0,0 @@
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 logging
|
||||
import six
|
||||
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils
|
||||
|
||||
from monascaclient import version
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
# NOTE(trebskit) this will be moved to another module
|
||||
# once initial migration is up
|
||||
# the point is to show how many code can we spare
|
||||
# in order to get the client working with minimum effort needed
|
||||
VERSION_MAP = {
|
||||
'2_0': 'monascaclient.v2_0.client.Client'
|
||||
}
|
||||
|
||||
|
||||
def make_client(api_version, session=None,
|
||||
endpoint=None, service_type='monitoring'):
|
||||
"""Returns an monitoring API client."""
|
||||
|
||||
client_cls = utils.get_client_class('monitoring', api_version, VERSION_MAP)
|
||||
c = client_cls(
|
||||
session=session,
|
||||
service_type=service_type,
|
||||
endpoint=endpoint,
|
||||
app_name='monascaclient',
|
||||
app_version=version.version_string,
|
||||
)
|
||||
|
||||
return c
|
||||
|
||||
|
||||
def create_command_class(name, func_module):
|
||||
"""Dynamically creates subclass of MigratingCommand.
|
||||
|
||||
Method takes name of the function, module it is part of
|
||||
and builds the subclass of :py:class:`MigratingCommand`.
|
||||
Having a subclass of :py:class:`cliff.command.Command` is mandatory
|
||||
for the osc-lib integration.
|
||||
|
||||
:param name: name of the function
|
||||
:type name: basestring
|
||||
:param func_module: the module function is part of
|
||||
:type func_module: module
|
||||
:return: command name, subclass of :py:class:`MigratingCommand`
|
||||
:rtype: tuple(basestring, class)
|
||||
|
||||
"""
|
||||
|
||||
cmd_name = name[3:].replace('_', '-')
|
||||
callback = getattr(func_module, name)
|
||||
desc = callback.__doc__ or ''
|
||||
help = desc.strip().split('\n')[0]
|
||||
|
||||
arguments = getattr(callback, 'arguments', [])
|
||||
|
||||
body = {
|
||||
'_args': arguments,
|
||||
'_callback': staticmethod(callback),
|
||||
'_description': desc,
|
||||
'_epilog': desc,
|
||||
'_help': help
|
||||
}
|
||||
|
||||
claz = type('%sCommand' % cmd_name.title().replace('-', ''),
|
||||
(MigratingCommand,), body)
|
||||
|
||||
return cmd_name, claz
|
||||
|
||||
|
||||
class MigratingCommandMeta(command.CommandMeta):
|
||||
"""Overwrite module name based on osc_lib.CommandMeta requirements."""
|
||||
|
||||
def __new__(mcs, name, bases, cls_dict):
|
||||
# NOTE(trebskit) little dirty, but should suffice for migration period
|
||||
cls_dict['__module__'] = 'monascaclient.v2_0.shell'
|
||||
return super(MigratingCommandMeta, mcs).__new__(mcs, name,
|
||||
bases, cls_dict)
|
||||
|
||||
|
||||
@six.add_metaclass(MigratingCommandMeta)
|
||||
class MigratingCommand(command.Command):
|
||||
"""MigratingCommand is temporary command.
|
||||
|
||||
MigratingCommand allows to map function defined
|
||||
shell commands from :py:module:`monascaclient.v2_0.shell`
|
||||
into :py:class:`command.Command` instances.
|
||||
|
||||
Note:
|
||||
This class is temporary solution during migrating
|
||||
to osc_lib and will be removed when all
|
||||
shell commands are migrated to cliff commands.
|
||||
|
||||
"""
|
||||
|
||||
_help = None
|
||||
_args = None
|
||||
_callback = None
|
||||
|
||||
def __init__(self, app, app_args, cmd_name=None):
|
||||
super(MigratingCommand, self).__init__(app, app_args, cmd_name)
|
||||
self._client = None
|
||||
self._endpoint = None
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
return self._callback(self.mon_client, parsed_args)
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(MigratingCommand, self).get_parser(prog_name)
|
||||
for (args, kwargs) in self._args:
|
||||
parser.add_argument(*args, **kwargs)
|
||||
parser.add_argument('-j', '--json',
|
||||
action='store_true',
|
||||
help='output raw json response')
|
||||
return parser
|
||||
|
||||
@property
|
||||
def mon_client(self):
|
||||
if not self._client:
|
||||
self.log.debug('Initializing mon-client')
|
||||
self._client = make_client(api_version=self.mon_version,
|
||||
endpoint=self.mon_url,
|
||||
session=self.app.client_manager.session)
|
||||
return self._client
|
||||
|
||||
@property
|
||||
def mon_version(self):
|
||||
return self.app_args.monasca_api_version
|
||||
|
||||
@property
|
||||
def mon_url(self):
|
||||
if self._endpoint:
|
||||
return self._endpoint
|
||||
|
||||
app_args = self.app_args
|
||||
cm = self.app.client_manager
|
||||
|
||||
endpoint = app_args.monasca_api_url
|
||||
|
||||
if not endpoint:
|
||||
req_data = {
|
||||
'service_type': 'monitoring',
|
||||
'region_name': cm.region_name,
|
||||
'interface': cm.interface,
|
||||
}
|
||||
LOG.debug('Discovering monasca endpoint using %s' % req_data)
|
||||
endpoint = cm.get_endpoint_for_service_type(**req_data)
|
||||
else:
|
||||
LOG.debug('Using supplied endpoint=%s' % endpoint)
|
||||
|
||||
self._endpoint = endpoint
|
||||
return self._endpoint
|
@ -1,117 +0,0 @@
|
||||
# (C) Copyright 2014-2015 Hewlett Packard Enterprise Development Company LP
|
||||
# Copyright 2017 Fujitsu LIMITED
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Command-line interface to the monasca-client API.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import locale
|
||||
import sys
|
||||
|
||||
from osc_lib.api import auth
|
||||
from osc_lib.cli import client_config as cloud_config
|
||||
from osc_lib import shell
|
||||
from osc_lib import utils as utils
|
||||
from oslo_utils import importutils
|
||||
import six
|
||||
|
||||
from monascaclient.osc import migration
|
||||
from monascaclient import version as mc_version
|
||||
|
||||
|
||||
class MonascaShell(shell.OpenStackShell):
|
||||
def __init__(self):
|
||||
super(MonascaShell, self).__init__(
|
||||
description=__doc__.strip(),
|
||||
version=mc_version.version_string
|
||||
)
|
||||
self.cloud_config = None
|
||||
|
||||
def initialize_app(self, argv):
|
||||
super(MonascaShell, self).initialize_app(argv)
|
||||
self.cloud_config = cloud_config.OSC_Config(
|
||||
override_defaults={
|
||||
'interface': None,
|
||||
'auth_type': self._auth_type,
|
||||
},
|
||||
)
|
||||
|
||||
def build_option_parser(self, description, version):
|
||||
parser = super(MonascaShell, self).build_option_parser(
|
||||
description,
|
||||
version
|
||||
)
|
||||
parser = auth.build_auth_plugins_option_parser(parser)
|
||||
parser = self._append_monasca_args(parser)
|
||||
return parser
|
||||
|
||||
@staticmethod
|
||||
def _append_monasca_args(parser):
|
||||
parser.add_argument('--monasca-api-url',
|
||||
default=utils.env('MONASCA_API_URL'),
|
||||
help='Defaults to env[MONASCA_API_URL].')
|
||||
parser.add_argument('--monasca_api_url',
|
||||
help=argparse.SUPPRESS)
|
||||
parser.add_argument('--monasca-api-version',
|
||||
default=utils.env(
|
||||
'MONASCA_API_VERSION',
|
||||
default='2_0'),
|
||||
help='Defaults to env[MONASCA_API_VERSION] or 2_0')
|
||||
parser.add_argument('--monasca_api_version',
|
||||
help=argparse.SUPPRESS)
|
||||
return parser
|
||||
|
||||
def _load_commands(self):
|
||||
version = self.options.monasca_api_version
|
||||
|
||||
submodule = importutils.import_versioned_module('monascaclient',
|
||||
version,
|
||||
'shell')
|
||||
|
||||
self._find_actions(submodule)
|
||||
|
||||
def _find_actions(self, actions_module):
|
||||
for attr in (a for a in dir(actions_module) if a.startswith('do_')):
|
||||
name, clazz = migration.create_command_class(attr, actions_module)
|
||||
|
||||
if 'help' == name:
|
||||
# help requires no auth
|
||||
clazz.auth_required = False
|
||||
|
||||
self.command_manager.add_command(name, clazz)
|
||||
|
||||
|
||||
def main(args=None):
|
||||
try:
|
||||
if args is None:
|
||||
args = sys.argv[1:]
|
||||
if six.PY2:
|
||||
# Emulate Py3, decode argv into Unicode based on locale so that
|
||||
# commands always see arguments as text instead of binary data
|
||||
encoding = locale.getpreferredencoding()
|
||||
if encoding:
|
||||
args = map(lambda arg: arg.decode(encoding), args)
|
||||
MonascaShell().run(args)
|
||||
except Exception as e:
|
||||
if '--debug' in args or '-d' in args:
|
||||
raise
|
||||
else:
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv[1:]))
|
@ -1,138 +0,0 @@
|
||||
# (C) Copyright 2014-2017 Hewlett Packard Enterprise Development LP
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 warnings
|
||||
|
||||
import mock
|
||||
from oslotest import base
|
||||
|
||||
from monascaclient import client
|
||||
|
||||
|
||||
class TestMonascaClient(base.BaseTestCase):
|
||||
|
||||
@mock.patch('monascaclient.client.migration')
|
||||
@mock.patch('monascaclient.client._get_auth_handler')
|
||||
@mock.patch('monascaclient.client._get_session')
|
||||
def test_should_warn_when_passing_args(self, _, __, ___):
|
||||
|
||||
api_version = mock.Mock()
|
||||
endpoint = mock.Mock()
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter('always')
|
||||
|
||||
client.Client(api_version, endpoint)
|
||||
|
||||
self.assertEqual(1, len(w))
|
||||
self.assertEqual(DeprecationWarning, w[0].category)
|
||||
self.assertRegex(
|
||||
str(w[0].message),
|
||||
'explicit configuration of the client using'
|
||||
)
|
||||
|
||||
@mock.patch('monascaclient.client.migration')
|
||||
@mock.patch('monascaclient.client._get_auth_handler')
|
||||
@mock.patch('monascaclient.client._get_session')
|
||||
def test_should_not_warn_when_passing_no_args(self, _, __, ___):
|
||||
api_version = mock.Mock()
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter('always')
|
||||
client.Client(api_version)
|
||||
self.assertEqual(0, len(w))
|
||||
|
||||
@mock.patch('monascaclient.client.migration')
|
||||
@mock.patch('monascaclient.client._get_auth_handler')
|
||||
@mock.patch('monascaclient.client._get_session')
|
||||
def test_should_override_endpoint_if_passed_as_arg(self, get_session,
|
||||
get_auth, _):
|
||||
api_version = mock.Mock()
|
||||
endpoint = mock.Mock()
|
||||
endpoint_fake = mock.Mock()
|
||||
auth_val = mock.Mock()
|
||||
|
||||
get_auth.return_value = auth_val
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter('always')
|
||||
client.Client(api_version, endpoint, endpoint=endpoint_fake)
|
||||
self.assertEqual(1, len(w))
|
||||
|
||||
get_auth.assert_called_once_with({
|
||||
'endpoint': endpoint
|
||||
})
|
||||
get_session.assert_called_once_with(auth_val, {
|
||||
'endpoint': endpoint
|
||||
})
|
||||
|
||||
@mock.patch('monascaclient.client.migration')
|
||||
@mock.patch('monascaclient.client._get_auth_handler')
|
||||
@mock.patch('monascaclient.client._get_session')
|
||||
def test_should_override_tenant_name_with_project_name(self,
|
||||
_,
|
||||
get_auth,
|
||||
__):
|
||||
api_version = mock.Mock()
|
||||
auth_val = mock.Mock()
|
||||
tenant_name = mock.Mock()
|
||||
project_name = tenant_name
|
||||
|
||||
get_auth.return_value = auth_val
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter('always')
|
||||
client.Client(api_version, tenant_name=tenant_name)
|
||||
|
||||
self.assertEqual(1, len(w))
|
||||
self.assertEqual(DeprecationWarning, w[0].category)
|
||||
self.assertRegex(
|
||||
str(w[0].message),
|
||||
'Usage of tenant_name has been deprecated in favour '
|
||||
)
|
||||
|
||||
get_auth.assert_called_once_with({
|
||||
'project_name': project_name
|
||||
})
|
||||
|
||||
@mock.patch('monascaclient.client.migration')
|
||||
@mock.patch('monascaclient.client._get_auth_handler')
|
||||
@mock.patch('monascaclient.client._get_session')
|
||||
def test_should_override_insecure_with_negated_verify(self,
|
||||
_,
|
||||
get_auth,
|
||||
__):
|
||||
api_version = mock.Mock()
|
||||
auth_val = mock.Mock()
|
||||
get_auth.return_value = auth_val
|
||||
|
||||
for insecure in [True, False]:
|
||||
warnings.resetwarnings()
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter('always')
|
||||
client.Client(api_version, insecure=insecure)
|
||||
|
||||
self.assertEqual(1, len(w))
|
||||
self.assertEqual(DeprecationWarning, w[0].category)
|
||||
self.assertRegex(
|
||||
str(w[0].message),
|
||||
'Usage of insecure has been deprecated in favour of'
|
||||
)
|
||||
|
||||
get_auth.assert_called_once_with({
|
||||
'verify': not insecure
|
||||
})
|
||||
get_auth.reset_mock()
|
@ -1,61 +0,0 @@
|
||||
# (C) Copyright 2014-2017 Hewlett Packard Enterprise Development LP
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 oslotest import base
|
||||
|
||||
from monascaclient import shell
|
||||
|
||||
|
||||
class TestMonascaShell(base.BaseTestCase):
|
||||
|
||||
@mock.patch('monascaclient.shell.auth')
|
||||
def test_should_use_auth_plugin_option_parser(self, auth):
|
||||
auth.build_auth_plugins_option_parser = apop = mock.Mock()
|
||||
shell.MonascaShell().run([])
|
||||
apop.assert_called_once()
|
||||
|
||||
def test_should_specify_monasca_args(self):
|
||||
expected_args = [
|
||||
'--monasca-api-url',
|
||||
'--monasca-api-version',
|
||||
'--monasca_api_url',
|
||||
'--monasca_api_version',
|
||||
]
|
||||
|
||||
parser = mock.Mock()
|
||||
parser.add_argument = aa = mock.Mock()
|
||||
shell.MonascaShell._append_monasca_args(parser)
|
||||
|
||||
aa.assert_called()
|
||||
for mc in aa.mock_calls:
|
||||
name = mc[1][0]
|
||||
self.assertIn(name, expected_args)
|
||||
|
||||
@mock.patch('monascaclient.shell.importutils')
|
||||
def test_should_load_commands_based_on_api_version(self, iu):
|
||||
iu.import_versioned_module = ivm = mock.Mock()
|
||||
|
||||
instance = shell.MonascaShell()
|
||||
instance.options = mock.Mock()
|
||||
instance.options.monasca_api_version = version = mock.Mock()
|
||||
|
||||
instance._find_actions = mock.Mock()
|
||||
|
||||
instance._load_commands()
|
||||
|
||||
ivm.assert_called_once_with('monascaclient', version, 'shell')
|
@ -1,134 +0,0 @@
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 oslotest import base
|
||||
|
||||
from monascaclient.osc import migration as migr
|
||||
from monascaclient.v2_0 import alarm_definitions as ad
|
||||
from monascaclient.v2_0 import shell
|
||||
|
||||
|
||||
class FakeV2Client(object):
|
||||
def __init__(self):
|
||||
super(FakeV2Client, self).__init__()
|
||||
self.alarm_definitions = mock.Mock(
|
||||
spec=ad.AlarmDefinitionsManager)
|
||||
|
||||
|
||||
class TestAlarmDefinitionShellV2(base.BaseTestCase):
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_should_update(self, mc):
|
||||
mc.return_value = c = FakeV2Client()
|
||||
|
||||
ad_id = '0495340b-58fd-4e1c-932b-5e6f9cc96490'
|
||||
ad_name = 'alarm_name'
|
||||
ad_desc = 'test_alarm_definition'
|
||||
ad_expr = 'avg(Test_Metric_1)>=10'
|
||||
ad_action_id = '16012650-0b62-4692-9103-2d04fe81cc93'
|
||||
ad_action_enabled = 'True'
|
||||
ad_match_by = 'hostname'
|
||||
ad_severity = 'CRITICAL'
|
||||
|
||||
raw_args = [
|
||||
ad_id, ad_name, ad_desc, ad_expr,
|
||||
ad_action_id, ad_action_id, ad_action_id, ad_action_enabled,
|
||||
ad_match_by, ad_severity
|
||||
]
|
||||
name, cmd_clazz = migr.create_command_class(
|
||||
'do_alarm_definition_update',
|
||||
shell
|
||||
)
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
|
||||
parser = cmd.get_parser(name)
|
||||
parsed_args = parser.parse_args(raw_args)
|
||||
cmd.run(parsed_args)
|
||||
|
||||
c.alarm_definitions.update.assert_called_once_with(
|
||||
actions_enabled=True,
|
||||
alarm_actions=[ad_action_id],
|
||||
alarm_id=ad_id,
|
||||
description=ad_desc,
|
||||
expression=ad_expr,
|
||||
match_by=[ad_match_by],
|
||||
name=ad_name,
|
||||
ok_actions=[ad_action_id],
|
||||
severity=ad_severity,
|
||||
undetermined_actions=[ad_action_id]
|
||||
)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_should_patch_name(self, mc):
|
||||
ad_id = '0495340b-58fd-4e1c-932b-5e6f9cc96490'
|
||||
ad_name = 'patch_name'
|
||||
|
||||
raw_args = '{0} --name {1}'.format(ad_id, ad_name).split(' ')
|
||||
self._patch_test(mc, raw_args, alarm_id=ad_id, name=ad_name)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_should_patch_actions(self, mc):
|
||||
ad_id = '0495340b-58fd-4e1c-932b-5e6f9cc96490'
|
||||
ad_action_id = '16012650-0b62-4692-9103-2d04fe81cc93'
|
||||
|
||||
actions = ['alarm-actions', 'ok-actions',
|
||||
'undetermined-actions']
|
||||
for action in actions:
|
||||
raw_args = ('{0} --{1} {2}'.format(ad_id, action, ad_action_id)
|
||||
.split(' '))
|
||||
self._patch_test(mc, raw_args, **{
|
||||
'alarm_id': ad_id,
|
||||
action.replace('-', '_'): [ad_action_id]
|
||||
})
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_should_patch_severity(self, mc):
|
||||
ad_id = '0495340b-58fd-4e1c-932b-5e6f9cc96490'
|
||||
|
||||
severity_types = ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL']
|
||||
for st in severity_types:
|
||||
raw_args = ('{0} --severity {1}'.format(ad_id, st)
|
||||
.split(' '))
|
||||
self._patch_test(mc, raw_args, alarm_id=ad_id, severity=st)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_should_not_patch_unknown_severity(self, mc):
|
||||
ad_id = '0495340b-58fd-4e1c-932b-5e6f9cc96490'
|
||||
|
||||
st = 'foo'
|
||||
raw_args = ('{0} --severity {1}'.format(ad_id, st)
|
||||
.split(' '))
|
||||
self._patch_test(mc, raw_args, called=False)
|
||||
|
||||
@staticmethod
|
||||
def _patch_test(mc, args, called=True, **kwargs):
|
||||
mc.return_value = c = FakeV2Client()
|
||||
|
||||
name, cmd_clazz = migr.create_command_class(
|
||||
'do_alarm_definition_patch',
|
||||
shell
|
||||
)
|
||||
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
|
||||
parser = cmd.get_parser(name)
|
||||
parsed_args = parser.parse_args(args)
|
||||
cmd.run(parsed_args)
|
||||
|
||||
if called:
|
||||
c.alarm_definitions.patch.assert_called_once_with(**kwargs)
|
||||
else:
|
||||
c.alarm_definitions.patch.assert_not_called()
|
@ -1,85 +0,0 @@
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 oslotest import base
|
||||
|
||||
from monascaclient.osc import migration as migr
|
||||
from monascaclient.v2_0 import metrics
|
||||
from monascaclient.v2_0 import shell
|
||||
|
||||
|
||||
class FakeV2Client(object):
|
||||
def __init__(self):
|
||||
super(FakeV2Client, self).__init__()
|
||||
self.metrics = mock.Mock(spec=metrics.MetricsManager)
|
||||
|
||||
|
||||
class TestMetricsShellV2(base.BaseTestCase):
|
||||
|
||||
def test_bad_metrics(self):
|
||||
raw_args_list = [
|
||||
['metric1'],
|
||||
['123'],
|
||||
['']
|
||||
]
|
||||
name, cmd_clazz = migr.create_command_class('do_metric_create',
|
||||
shell)
|
||||
|
||||
for raw_args in raw_args_list:
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
parser = cmd.get_parser(name)
|
||||
self.assertRaises(SystemExit, parser.parse_args, raw_args)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_metric_create(self, mc):
|
||||
mc.return_value = c = FakeV2Client()
|
||||
|
||||
raw_args = 'metric1 123 --time 1395691090'.split(' ')
|
||||
name, cmd_clazz = migr.create_command_class('do_metric_create',
|
||||
shell)
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
|
||||
parser = cmd.get_parser(name)
|
||||
parsed_args = parser.parse_args(raw_args)
|
||||
cmd.run(parsed_args)
|
||||
|
||||
data = {'timestamp': 1395691090,
|
||||
'name': 'metric1',
|
||||
'value': 123.0}
|
||||
|
||||
c.metrics.create.assert_called_once_with(**data)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_metric_create_with_project_id(self, mc):
|
||||
mc.return_value = c = FakeV2Client()
|
||||
|
||||
project_id = 'd48e63e76a5c4e05ba26a1185f31d4aa'
|
||||
raw_args = ('metric1 123 --time 1395691090 --project-id %s'
|
||||
% project_id).split(' ')
|
||||
name, cmd_clazz = migr.create_command_class('do_metric_create',
|
||||
shell)
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
|
||||
parser = cmd.get_parser(name)
|
||||
parsed_args = parser.parse_args(raw_args)
|
||||
cmd.run(parsed_args)
|
||||
|
||||
data = {'timestamp': 1395691090,
|
||||
'name': 'metric1',
|
||||
'tenant_id': project_id,
|
||||
'value': 123.0}
|
||||
|
||||
c.metrics.create.assert_called_once_with(**data)
|
@ -1,52 +0,0 @@
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 oslotest import base
|
||||
|
||||
from monascaclient.osc import migration as migr
|
||||
from monascaclient.v2_0 import notificationtypes
|
||||
from monascaclient.v2_0 import shell
|
||||
|
||||
|
||||
class FakeV2Client(object):
|
||||
|
||||
def __init__(self):
|
||||
super(FakeV2Client, self).__init__()
|
||||
self.notificationtypes = mock.Mock(
|
||||
spec=notificationtypes.NotificationTypesManager)
|
||||
|
||||
|
||||
class TestNotificationsTypesShellV2(base.BaseTestCase):
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_notification_types_list(self, mc):
|
||||
mc.return_value = c = FakeV2Client()
|
||||
c.notificationtypes.list.return_value = [
|
||||
{"type": "WEBHOOK"},
|
||||
{"type": "EMAIL"},
|
||||
{"type": "PAGERDUTY"}
|
||||
]
|
||||
|
||||
raw_args = []
|
||||
name, cmd_clazz = migr.create_command_class('do_notification_type_list',
|
||||
shell)
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
|
||||
parser = cmd.get_parser(name)
|
||||
parsed_args = parser.parse_args(raw_args)
|
||||
cmd.run(parsed_args)
|
||||
|
||||
c.notificationtypes.list.assert_called_once()
|
@ -1,160 +0,0 @@
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 oslotest import base
|
||||
|
||||
from monascaclient.osc import migration as migr
|
||||
from monascaclient.v2_0 import notifications
|
||||
from monascaclient.v2_0 import shell
|
||||
|
||||
|
||||
class FakeV2Client(object):
|
||||
|
||||
def __init__(self):
|
||||
super(FakeV2Client, self).__init__()
|
||||
self.notifications = mock.Mock(spec=notifications.NotificationsManager)
|
||||
|
||||
|
||||
class TestNotificationsShellV2(base.BaseTestCase):
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_notification_create_email(self, mc):
|
||||
mc.return_value = c = FakeV2Client()
|
||||
|
||||
raw_args = ['email1', 'EMAIL', 'john.doe@hp.com']
|
||||
name, cmd_clazz = migr.create_command_class('do_notification_create',
|
||||
shell)
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
|
||||
parser = cmd.get_parser(name)
|
||||
parsed_args = parser.parse_args(raw_args)
|
||||
cmd.run(parsed_args)
|
||||
|
||||
data = {'name': 'email1',
|
||||
'type': 'EMAIL',
|
||||
'address': 'john.doe@hp.com'}
|
||||
|
||||
c.notifications.create.assert_called_once_with(**data)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_notification_create_webhook(self, mc):
|
||||
mc.return_value = c = FakeV2Client()
|
||||
|
||||
raw_args = ['mypost', 'WEBHOOK', 'http://localhost:8080']
|
||||
name, cmd_clazz = migr.create_command_class('do_notification_create',
|
||||
shell)
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
|
||||
parser = cmd.get_parser(name)
|
||||
parsed_args = parser.parse_args(raw_args)
|
||||
cmd.run(parsed_args)
|
||||
|
||||
data = {'name': 'mypost',
|
||||
'type': 'WEBHOOK',
|
||||
'address': 'http://localhost:8080'}
|
||||
|
||||
c.notifications.create.assert_called_once_with(**data)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_good_notifications_patch(self, mc):
|
||||
args = '--type EMAIL --address john.doe@hpe.com --period 0'
|
||||
data = {'type': 'EMAIL',
|
||||
'address': 'john.doe@hpe.com',
|
||||
'period': 0}
|
||||
self._patch_test(mc, args, data)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_good_notifications_patch_just_name(self, mc):
|
||||
name = 'fred'
|
||||
args = '--name ' + name
|
||||
data = {'name': name}
|
||||
self._patch_test(mc, args, data)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_good_notifications_patch_just_address(self, mc):
|
||||
address = 'fred@fl.com'
|
||||
args = '--address ' + address
|
||||
data = {'address': address}
|
||||
self._patch_test(mc, args, data)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_good_notifications_patch_just_period(self, mc):
|
||||
period = 0
|
||||
args = '--period ' + str(period)
|
||||
data = {'period': period}
|
||||
self._patch_test(mc, args, data)
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_bad_notifications_patch(self, mc):
|
||||
mc.return_value = c = FakeV2Client()
|
||||
|
||||
id_str = '0495340b-58fd-4e1c-932b-5e6f9cc96490'
|
||||
raw_args = ('{0} --type EMAIL --address john.doe@hpe.com '
|
||||
'--period 60').format(id_str).split(' ')
|
||||
name, cmd_clazz = migr.create_command_class('do_notification_patch',
|
||||
shell)
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
|
||||
parser = cmd.get_parser(name)
|
||||
parsed_args = parser.parse_args(raw_args)
|
||||
cmd.run(parsed_args)
|
||||
|
||||
c.notifications.patch.assert_not_called()
|
||||
|
||||
@mock.patch('monascaclient.osc.migration.make_client')
|
||||
def test_good_notifications_update(self, mc):
|
||||
mc.return_value = c = FakeV2Client()
|
||||
|
||||
id_str = '0495340b-58fd-4e1c-932b-5e6f9cc96491'
|
||||
raw_args = ('{0} notification_updated_name '
|
||||
'EMAIL john.doe@hpe.com 0').format(id_str).split(' ')
|
||||
name, cmd_clazz = migr.create_command_class('do_notification_update',
|
||||
shell)
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
|
||||
parser = cmd.get_parser(name)
|
||||
parsed_args = parser.parse_args(raw_args)
|
||||
|
||||
cmd.run(parsed_args)
|
||||
|
||||
data = {
|
||||
'name': 'notification_updated_name',
|
||||
'type': 'EMAIL',
|
||||
'address': 'john.doe@hpe.com',
|
||||
'period': 0,
|
||||
'notification_id': id_str
|
||||
}
|
||||
|
||||
c.notifications.update.assert_called_once_with(**data)
|
||||
|
||||
@staticmethod
|
||||
def _patch_test(mc, args, data):
|
||||
mc.return_value = c = FakeV2Client()
|
||||
|
||||
id_str = '0495340b-58fd-4e1c-932b-5e6f9cc96490'
|
||||
raw_args = '{0} {1}'.format(id_str, args).split(' ')
|
||||
name, cmd_clazz = migr.create_command_class('do_notification_patch',
|
||||
shell)
|
||||
cmd = cmd_clazz(mock.Mock(), mock.Mock())
|
||||
|
||||
parser = cmd.get_parser(name)
|
||||
parsed_args = parser.parse_args(raw_args)
|
||||
cmd.run(parsed_args)
|
||||
|
||||
# add notification_id to data
|
||||
data['notification_id'] = id_str
|
||||
|
||||
c.notifications.patch.assert_called_once_with(**data)
|
@ -1,18 +0,0 @@
|
||||
# (C) Copyright 2014 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# 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.
|
||||
|
||||
__all__ = ['Client']
|
||||
|
||||
from monascaclient.v2_0.client import Client
|
@ -1,69 +0,0 @@
|
||||
# (C) Copyright 2014-2015 Hewlett Packard Enterprise Development Company LP
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 monascaclient.common import monasca_manager
|
||||
|
||||
|
||||
class AlarmDefinitionsManager(monasca_manager.MonascaManager):
|
||||
base_url = '/alarm-definitions'
|
||||
|
||||
def create(self, **kwargs):
|
||||
"""Create an alarm definition."""
|
||||
resp = self.client.create(url=self.base_url,
|
||||
json=kwargs)
|
||||
return resp
|
||||
|
||||
def get(self, **kwargs):
|
||||
"""Get the details for a specific alarm definition."""
|
||||
|
||||
# NOTE(trebskit) should actually be find_one, but
|
||||
# monasca does not support expected response format
|
||||
|
||||
url = '%s/%s' % (self.base_url, kwargs['alarm_id'])
|
||||
resp = self.client.list(path=url)
|
||||
return resp
|
||||
|
||||
def list(self, **kwargs):
|
||||
"""Get a list of alarm definitions."""
|
||||
return self._list('', 'dimensions', **kwargs)
|
||||
|
||||
def delete(self, **kwargs):
|
||||
"""Delete a specific alarm definition."""
|
||||
url_str = self.base_url + '/%s' % kwargs['alarm_id']
|
||||
resp = self.client.delete(url_str)
|
||||
return resp
|
||||
|
||||
def update(self, **kwargs):
|
||||
"""Update a specific alarm definition."""
|
||||
url_str = self.base_url + '/%s' % kwargs['alarm_id']
|
||||
del kwargs['alarm_id']
|
||||
|
||||
resp = self.client.create(url=url_str,
|
||||
method='PUT',
|
||||
json=kwargs)
|
||||
|
||||
return resp
|
||||
|
||||
def patch(self, **kwargs):
|
||||
"""Patch a specific alarm definition."""
|
||||
url_str = self.base_url + '/%s' % kwargs['alarm_id']
|
||||
del kwargs['alarm_id']
|
||||
|
||||
resp = self.client.create(url=url_str,
|
||||
method='PATCH',
|
||||
json=kwargs)
|
||||
|
||||
return resp
|
@ -1,97 +0,0 @@
|
||||
# (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company LP
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 six.moves.urllib import parse
|
||||
|
||||
from monascaclient.common import monasca_manager
|
||||
|
||||
|
||||
class AlarmsManager(monasca_manager.MonascaManager):
|
||||
base_url = '/alarms'
|
||||
|
||||
def get(self, **kwargs):
|
||||
"""Get the details for a specific alarm."""
|
||||
|
||||
# NOTE(trebskit) should actually be find_one, but
|
||||
# monasca does not support expected response format
|
||||
|
||||
url = '%s/%s' % (self.base_url, kwargs['alarm_id'])
|
||||
resp = self.client.list(path=url)
|
||||
return resp
|
||||
|
||||
def list(self, **kwargs):
|
||||
"""Get a list of alarms."""
|
||||
return self._list('', 'metric_dimensions', **kwargs)
|
||||
|
||||
def delete(self, **kwargs):
|
||||
"""Delete a specific alarm."""
|
||||
url_str = self.base_url + '/%s' % kwargs['alarm_id']
|
||||
resp = self.client.delete(url_str)
|
||||
return resp
|
||||
|
||||
def update(self, **kwargs):
|
||||
"""Update a specific alarm."""
|
||||
url_str = self.base_url + '/%s' % kwargs['alarm_id']
|
||||
del kwargs['alarm_id']
|
||||
|
||||
body = self.client.create(url=url_str,
|
||||
method='PUT',
|
||||
json=kwargs)
|
||||
|
||||
return body
|
||||
|
||||
def patch(self, **kwargs):
|
||||
"""Patch a specific alarm."""
|
||||
url_str = self.base_url + '/%s' % kwargs['alarm_id']
|
||||
del kwargs['alarm_id']
|
||||
|
||||
resp = self.client.create(url=url_str,
|
||||
method='PATCH',
|
||||
json=kwargs)
|
||||
|
||||
return resp
|
||||
|
||||
def count(self, **kwargs):
|
||||
url_str = self.base_url + '/count'
|
||||
if 'metric_dimensions' in kwargs:
|
||||
dimstr = self.get_dimensions_url_string(
|
||||
kwargs['metric_dimensions'])
|
||||
kwargs['metric_dimensions'] = dimstr
|
||||
|
||||
if kwargs:
|
||||
url_str = url_str + '?%s' % parse.urlencode(kwargs, True)
|
||||
body = self.client.list(url_str)
|
||||
return body
|
||||
|
||||
def history(self, **kwargs):
|
||||
"""History of a specific alarm."""
|
||||
url_str = self.base_url + '/%s/state-history' % kwargs['alarm_id']
|
||||
del kwargs['alarm_id']
|
||||
if kwargs:
|
||||
url_str = url_str + '?%s' % parse.urlencode(kwargs, True)
|
||||
resp = self.client.list(url_str)
|
||||
return resp['elements'] if type(resp) is dict else resp
|
||||
|
||||
def history_list(self, **kwargs):
|
||||
"""History list of alarm state."""
|
||||
url_str = self.base_url + '/state-history/'
|
||||
if 'dimensions' in kwargs:
|
||||
dimstr = self.get_dimensions_url_string(kwargs['dimensions'])
|
||||
kwargs['dimensions'] = dimstr
|
||||
if kwargs:
|
||||
url_str = url_str + '?%s' % parse.urlencode(kwargs, True)
|
||||
resp = self.client.list(url_str)
|
||||
return resp['elements'] if type(resp) is dict else resp
|
@ -1,40 +0,0 @@
|
||||
# (C) Copyright 2014-2015 Hewlett Packard Enterprise Development Company LP
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 osc_lib.api import api
|
||||
|
||||
from monascaclient.v2_0 import alarm_definitions as ad
|
||||
from monascaclient.v2_0 import alarms
|
||||
from monascaclient.v2_0 import metrics
|
||||
from monascaclient.v2_0 import notifications
|
||||
from monascaclient.v2_0 import notificationtypes as nt
|
||||
|
||||
|
||||
class Client(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize a new http client for the monasca API."""
|
||||
|
||||
client = MonascaApi(*args, **kwargs)
|
||||
|
||||
self.metrics = metrics.MetricsManager(client)
|
||||
self.notifications = notifications.NotificationsManager(client)
|
||||
self.alarms = alarms.AlarmsManager(client)
|
||||
self.alarm_definitions = ad.AlarmDefinitionsManager(client)
|
||||
self.notificationtypes = nt.NotificationTypesManager(client)
|
||||
|
||||
|
||||
class MonascaApi(api.BaseAPI):
|
||||
SERVICE_TYPE = "monitoring"
|
@ -1,56 +0,0 @@
|
||||
# (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 monascaclient.common import monasca_manager
|
||||
|
||||
|
||||
class MetricsManager(monasca_manager.MonascaManager):
|
||||
base_url = '/metrics'
|
||||
|
||||
def create(self, **kwargs):
|
||||
"""Create a metric."""
|
||||
url_str = self.base_url
|
||||
if 'tenant_id' in kwargs:
|
||||
url_str = url_str + '?tenant_id=%s' % kwargs['tenant_id']
|
||||
del kwargs['tenant_id']
|
||||
|
||||
data = kwargs['jsonbody'] if 'jsonbody' in kwargs else kwargs
|
||||
body = self.client.create(url=url_str, json=data)
|
||||
return body
|
||||
|
||||
def list(self, **kwargs):
|
||||
"""Get a list of metrics."""
|
||||
return self._list('', 'dimensions', **kwargs)
|
||||
|
||||
def list_names(self, **kwargs):
|
||||
"""Get a list of metric names."""
|
||||
return self._list('/names', 'dimensions', **kwargs)
|
||||
|
||||
def list_measurements(self, **kwargs):
|
||||
"""Get a list of measurements based on metric definition filters."""
|
||||
return self._list('/measurements', 'dimensions', **kwargs)
|
||||
|
||||
def list_statistics(self, **kwargs):
|
||||
"""Get a list of measurement statistics based on metric def filters."""
|
||||
return self._list('/statistics', 'dimensions', **kwargs)
|
||||
|
||||
def list_dimension_names(self, **kwargs):
|
||||
"""Get a list of metric dimension names."""
|
||||
return self._list('/dimensions/names', **kwargs)
|
||||
|
||||
def list_dimension_values(self, **kwargs):
|
||||
"""Get a list of metric dimension values."""
|
||||
return self._list('/dimensions/names/values', **kwargs)
|
@ -1,68 +0,0 @@
|
||||
# (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 monascaclient.common import monasca_manager
|
||||
|
||||
|
||||
class NotificationsManager(monasca_manager.MonascaManager):
|
||||
base_url = '/notification-methods'
|
||||
|
||||
def create(self, **kwargs):
|
||||
"""Create a notification."""
|
||||
body = self.client.create(url=self.base_url,
|
||||
json=kwargs)
|
||||
return body
|
||||
|
||||
def get(self, **kwargs):
|
||||
"""Get the details for a specific notification."""
|
||||
|
||||
# NOTE(trebskit) should actually be find_one, but
|
||||
# monasca does not support expected response format
|
||||
|
||||
url = '%s/%s' % (self.base_url, kwargs['notification_id'])
|
||||
resp = self.client.list(path=url)
|
||||
return resp
|
||||
|
||||
def list(self, **kwargs):
|
||||
"""Get a list of notifications."""
|
||||
return self._list('', **kwargs)
|
||||
|
||||
def delete(self, **kwargs):
|
||||
"""Delete a notification."""
|
||||
url = self.base_url + '/%s' % kwargs['notification_id']
|
||||
resp = self.client.delete(url=url)
|
||||
return resp
|
||||
|
||||
def update(self, **kwargs):
|
||||
"""Update a notification."""
|
||||
url_str = self.base_url + '/%s' % kwargs['notification_id']
|
||||
del kwargs['notification_id']
|
||||
|
||||
resp = self.client.create(url=url_str,
|
||||
method='PUT',
|
||||
json=kwargs)
|
||||
return resp
|
||||
|
||||
def patch(self, **kwargs):
|
||||
"""Patch a notification."""
|
||||
url_str = self.base_url + '/%s' % kwargs['notification_id']
|
||||
del kwargs['notification_id']
|
||||
|
||||
resp = self.client.create(url=url_str,
|
||||
method='PATCH',
|
||||
json=kwargs)
|
||||
|
||||
return resp
|
@ -1,25 +0,0 @@
|
||||
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 monascaclient.common import monasca_manager
|
||||
|
||||
|
||||
class NotificationTypesManager(monasca_manager.MonascaManager):
|
||||
base_url = '/notification-methods/types'
|
||||
|
||||
def list(self, **kwargs):
|
||||
"""Get a list of notifications."""
|
||||
return self._list('', **kwargs)
|
File diff suppressed because it is too large
Load Diff
@ -1,20 +0,0 @@
|
||||
# Copyright 2017 FUJITSU LIMITED
|
||||
#
|
||||
# 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 pbr import version
|
||||
|
||||
__all__ = ['version_info', 'version_string']
|
||||
|
||||
version_info = version.VersionInfo('python-monascaclient')
|
||||
version_string = version_info.version_string()
|
@ -1,16 +0,0 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
osc-lib>=1.7.0 # Apache-2.0
|
||||
|
||||
oslo.serialization!=2.19.1,>=1.10.0 # Apache-2.0
|
||||
oslo.utils>=3.20.0 # Apache-2.0
|
||||
|
||||
Babel!=2.4.0,>=2.3.4 # BSD
|
||||
iso8601>=0.1.11 # MIT
|
||||
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
PrettyTable<0.8,>=0.7.1 # BSD
|
||||
PyYAML>=3.10.0 # MIT
|
||||
|
||||
six>=1.9.0 # MIT
|
120
run_tests.sh
120
run_tests.sh
@ -1,120 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
BASE_DIR=`dirname $0`
|
||||
|
||||
function usage {
|
||||
echo "Usage: $0 [OPTION]..."
|
||||
echo "Run monascaclient test suite(s)"
|
||||
echo ""
|
||||
echo " -V, --virtual-env Use virtualenv. Install automatically if not present."
|
||||
echo " (Default is to run tests in local environment)"
|
||||
echo " -F, --force Force a clean re-build of the virtual environment. Useful when dependencies have been added."
|
||||
echo " -f, --func Functional tests have been removed."
|
||||
echo " -u, --unit Run unit tests (default when nothing specified)"
|
||||
echo " -p, --pep8 Run pep8 tests"
|
||||
echo " --all Run pep8 and unit tests"
|
||||
echo " -c, --coverage Generate coverage report"
|
||||
echo " -d, --debug Run tests with testtools instead of testr. This allows you to use the debugger."
|
||||
echo " -h, --help Print this usage message"
|
||||
exit
|
||||
}
|
||||
|
||||
# must not assign -a as an option, needed for selecting custom attributes
|
||||
no_venv=1
|
||||
function process_option {
|
||||
case "$1" in
|
||||
-V|--virtual-env) no_venv=0;;
|
||||
-F|--force) force=1;;
|
||||
-f|--func) test_func=1;;
|
||||
-u|--unit) test_unit=1;;
|
||||
-p|--pep8) test_pep8=1;;
|
||||
--all) test_unit=1; test_pep8=1;;
|
||||
-c|--coverage) coverage=1;;
|
||||
-d|--debug) debug=1;;
|
||||
-h|--help) usage;;
|
||||
*) args="$args $1"; test_unit=1;;
|
||||
esac
|
||||
}
|
||||
|
||||
venv=.venv
|
||||
with_venv=tools/with_venv.sh
|
||||
wrapper=""
|
||||
debug=0
|
||||
|
||||
function run_tests {
|
||||
echo 'Running tests'
|
||||
|
||||
if [ $debug -eq 1 ]; then
|
||||
echo "Debugging..."
|
||||
if [ "$args" = "" ]; then
|
||||
# Default to running all tests if specific test is not
|
||||
# provided.
|
||||
testrargs="discover ./monascaclient/tests"
|
||||
fi
|
||||
${wrapper} python -m testtools.run $args $testrargs
|
||||
|
||||
# Short circuit because all of the testr and coverage stuff
|
||||
# below does not make sense when running testtools.run for
|
||||
# debugging purposes.
|
||||
return $?
|
||||
fi
|
||||
|
||||
# Just run the test suites in current environment
|
||||
if [ -n "$args" ] ; then
|
||||
args="-t $args"
|
||||
fi
|
||||
${wrapper} python setup.py testr --slowest $args
|
||||
}
|
||||
|
||||
function run_pep8 {
|
||||
echo "Running flake8..."
|
||||
bash -c "${wrapper} flake8"
|
||||
}
|
||||
|
||||
# run unit tests with pep8 when no arguments are specified
|
||||
# otherwise process CLI options
|
||||
if [[ $# == 0 ]]; then
|
||||
test_pep8=1
|
||||
test_unit=1
|
||||
else
|
||||
for arg in "$@"; do
|
||||
process_option $arg
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$no_venv" == 0 ]; then
|
||||
# Remove the virtual environment if --force used
|
||||
if [ "$force" == 1 ]; then
|
||||
echo "Cleaning virtualenv..."
|
||||
rm -rf ${venv}
|
||||
fi
|
||||
if [ -e ${venv} ]; then
|
||||
wrapper="${with_venv}"
|
||||
else
|
||||
# Automatically install the virtualenv
|
||||
python tools/install_venv.py
|
||||
wrapper="${with_venv}"
|
||||
fi
|
||||
fi
|
||||
|
||||
result=0
|
||||
|
||||
# If functional or unit tests have been selected, run them
|
||||
if [ "$test_unit" == 1 ] || [ "$debug" == 1 ] ; then
|
||||
run_tests
|
||||
result=$?
|
||||
fi
|
||||
|
||||
# Run pep8 if it was selected
|
||||
if [ "$test_pep8" == 1 ]; then
|
||||
run_pep8
|
||||
fi
|
||||
|
||||
# Generate coverage report
|
||||
if [ "$coverage" == 1 ]; then
|
||||
echo "Generating coverage report in ./cover"
|
||||
${wrapper} python setup.py testr --coverage --slowest
|
||||
${wrapper} python -m coverage report --show-missing
|
||||
fi
|
||||
|
||||
exit $result
|
33
setup.cfg
33
setup.cfg
@ -1,33 +0,0 @@
|
||||
[metadata]
|
||||
name = python-monascaclient
|
||||
summary = Monasca API Client Library
|
||||
description-file = README.rst
|
||||
author = OpenStack
|
||||
author-email = openstack-dev@lists.openstack.org
|
||||
home-page = https://github.com/openstack/python-monascaclient
|
||||
classifier =
|
||||
Environment :: Console
|
||||
Intended Audience :: Information Technology
|
||||
Intended Audience :: System Administrators
|
||||
License :: OSI Approved :: Apache Software License
|
||||
Operating System :: POSIX :: Linux
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 2
|
||||
Programming Language :: Python :: 2.7
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.5
|
||||
|
||||
[files]
|
||||
packages = monascaclient
|
||||
data_files =
|
||||
share = tools/monasca.bash_completion
|
||||
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
monasca = monascaclient.shell:main
|
||||
|
||||
[pbr]
|
||||
autodoc_index_modules = True
|
||||
|
||||
[wheel]
|
||||
universal = 1
|
29
setup.py
29
setup.py
@ -1,29 +0,0 @@
|
||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
||||
import setuptools
|
||||
|
||||
# In python < 2.7.4, a lazy loading of package `pbr` will break
|
||||
# setuptools if some other modules registered functions in `atexit`.
|
||||
# solution from: http://bugs.python.org/issue15881#msg170215
|
||||
try:
|
||||
import multiprocessing # noqa
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr>=2.0.0'],
|
||||
pbr=True)
|
@ -1,12 +0,0 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
|
||||
bandit>=1.1.0 # Apache-2.0
|
||||
coverage!=4.4,>=4.0 # Apache-2.0
|
||||
oslotest>=1.10.0 # Apache-2.0
|
||||
os-testr>=0.8.0 # Apache-2.0
|
||||
testrepository>=0.0.18 # Apache-2.0/BSD
|
||||
testscenarios>=0.4 # Apache-2.0/BSD
|
||||
testtools>=1.4.0 # MIT
|
@ -1,76 +0,0 @@
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Copyright 2010 OpenStack Foundation
|
||||
# Copyright 2013 IBM Corp.
|
||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 os
|
||||
import sys
|
||||
|
||||
import install_venv_common as install_venv # flake8: noqa
|
||||
|
||||
from six.moves import configparser as ConfigParser
|
||||
|
||||
|
||||
def print_help(project, venv, root):
|
||||
help = """
|
||||
%(project)s development environment setup is complete.
|
||||
|
||||
%(project)s development uses virtualenv to track and manage Python
|
||||
dependencies while in development and testing.
|
||||
|
||||
To activate the %(project)s virtualenv for the extent of your current
|
||||
shell session you can run:
|
||||
|
||||
$ source %(venv)s/bin/activate
|
||||
|
||||
Or, if you prefer, you can run commands in the virtualenv on a case by
|
||||
case basis by running:
|
||||
|
||||
$ %(root)s/tools/with_venv.sh <your command>
|
||||
"""
|
||||
print(help % dict(project=project, venv=venv, root=root))
|
||||
|
||||
|
||||
def main(argv):
|
||||
root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
if os.environ.get('tools_path'):
|
||||
root = os.environ['tools_path']
|
||||
venv = os.path.join(root, '.venv')
|
||||
if os.environ.get('venv'):
|
||||
venv = os.environ['venv']
|
||||
|
||||
pip_requires = os.path.join(root, 'requirements.txt')
|
||||
test_requires = os.path.join(root, 'test-requirements.txt')
|
||||
py_version = "python%s.%s" % (sys.version_info[0], sys.version_info[1])
|
||||
setup_cfg = ConfigParser.ConfigParser()
|
||||
setup_cfg.read('setup.cfg')
|
||||
project = setup_cfg.get('metadata', 'name')
|
||||
|
||||
install = install_venv.InstallVenv(
|
||||
root, venv, pip_requires, test_requires, py_version, project)
|
||||
options = install.parse_args(argv)
|
||||
install.check_python_version()
|
||||
install.check_dependencies()
|
||||
install.create_virtualenv(no_site_packages=options.no_site_packages)
|
||||
install.install_dependencies()
|
||||
#install.post_process()
|
||||
print_help(project, venv, root)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
@ -1,172 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# Copyright 2013 IBM Corp.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Provides methods needed by installation script for OpenStack development
|
||||
virtual environments.
|
||||
|
||||
Since this script is used to bootstrap a virtualenv from the system's Python
|
||||
environment, it should be kept strictly compatible with Python 2.6.
|
||||
|
||||
Synced in from openstack-common
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import optparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
class InstallVenv(object):
|
||||
|
||||
def __init__(self, root, venv, requirements,
|
||||
test_requirements, py_version,
|
||||
project):
|
||||
self.root = root
|
||||
self.venv = venv
|
||||
self.requirements = requirements
|
||||
self.test_requirements = test_requirements
|
||||
self.py_version = py_version
|
||||
self.project = project
|
||||
|
||||
def die(self, message, *args):
|
||||
print(message % args, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def check_python_version(self):
|
||||
if sys.version_info < (2, 6):
|
||||
self.die("Need Python Version >= 2.6")
|
||||
|
||||
def run_command_with_code(self, cmd, redirect_output=True,
|
||||
check_exit_code=True):
|
||||
"""Runs a command in an out-of-process shell.
|
||||
|
||||
Returns the output of that command. Working directory is self.root.
|
||||
"""
|
||||
if redirect_output:
|
||||
stdout = subprocess.PIPE
|
||||
else:
|
||||
stdout = None
|
||||
|
||||
proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout)
|
||||
output = proc.communicate()[0]
|
||||
if check_exit_code and proc.returncode != 0:
|
||||
self.die('Command "%s" failed.\n%s', ' '.join(cmd), output)
|
||||
return (output, proc.returncode)
|
||||
|
||||
def run_command(self, cmd, redirect_output=True, check_exit_code=True):
|
||||
return self.run_command_with_code(cmd, redirect_output,
|
||||
check_exit_code)[0]
|
||||
|
||||
def get_distro(self):
|
||||
if (os.path.exists('/etc/fedora-release') or
|
||||
os.path.exists('/etc/redhat-release')):
|
||||
return Fedora(
|
||||
self.root, self.venv, self.requirements,
|
||||
self.test_requirements, self.py_version, self.project)
|
||||
else:
|
||||
return Distro(
|
||||
self.root, self.venv, self.requirements,
|
||||
self.test_requirements, self.py_version, self.project)
|
||||
|
||||
def check_dependencies(self):
|
||||
self.get_distro().install_virtualenv()
|
||||
|
||||
def create_virtualenv(self, no_site_packages=True):
|
||||
"""Creates the virtual environment and installs PIP.
|
||||
|
||||
Creates the virtual environment and installs PIP only into the
|
||||
virtual environment.
|
||||
"""
|
||||
if not os.path.isdir(self.venv):
|
||||
print('Creating venv...', end=' ')
|
||||
if no_site_packages:
|
||||
self.run_command(['virtualenv', '-q', '--no-site-packages',
|
||||
self.venv])
|
||||
else:
|
||||
self.run_command(['virtualenv', '-q', self.venv])
|
||||
print('done.')
|
||||
else:
|
||||
print("venv already exists...")
|
||||
pass
|
||||
|
||||
def pip_install(self, *args):
|
||||
self.run_command(['tools/with_venv.sh',
|
||||
'pip', 'install', '--upgrade'] + list(args),
|
||||
redirect_output=False)
|
||||
|
||||
def install_dependencies(self):
|
||||
print('Installing dependencies with pip (this can take a while)...')
|
||||
|
||||
# First things first, make sure our venv has the latest pip and
|
||||
# setuptools and pbr
|
||||
self.pip_install('pip>=1.4')
|
||||
self.pip_install('setuptools')
|
||||
self.pip_install('pbr')
|
||||
|
||||
self.pip_install('-r', self.requirements, '-r', self.test_requirements)
|
||||
|
||||
def parse_args(self, argv):
|
||||
"""Parses command-line arguments."""
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option('-n', '--no-site-packages',
|
||||
action='store_true',
|
||||
help="Do not inherit packages from global Python "
|
||||
"install")
|
||||
return parser.parse_args(argv[1:])[0]
|
||||
|
||||
|
||||
class Distro(InstallVenv):
|
||||
|
||||
def check_cmd(self, cmd):
|
||||
return bool(self.run_command(['which', cmd],
|
||||
check_exit_code=False).strip())
|
||||
|
||||
def install_virtualenv(self):
|
||||
if self.check_cmd('virtualenv'):
|
||||
return
|
||||
|
||||
if self.check_cmd('easy_install'):
|
||||
print('Installing virtualenv via easy_install...', end=' ')
|
||||
if self.run_command(['easy_install', 'virtualenv']):
|
||||
print('Succeeded')
|
||||
return
|
||||
else:
|
||||
print('Failed')
|
||||
|
||||
self.die('ERROR: virtualenv not found.\n\n%s development'
|
||||
' requires virtualenv, please install it using your'
|
||||
' favorite package management tool' % self.project)
|
||||
|
||||
|
||||
class Fedora(Distro):
|
||||
"""This covers all Fedora-based distributions.
|
||||
|
||||
Includes: Fedora, RHEL, CentOS, Scientific Linux
|
||||
"""
|
||||
|
||||
def check_pkg(self, pkg):
|
||||
return self.run_command_with_code(['rpm', '-q', pkg],
|
||||
check_exit_code=False)[1] == 0
|
||||
|
||||
def install_virtualenv(self):
|
||||
if self.check_cmd('virtualenv'):
|
||||
return
|
||||
|
||||
if not self.check_pkg('python-virtualenv'):
|
||||
self.die("Please install 'python-virtualenv'.")
|
||||
|
||||
super(Fedora, self).install_virtualenv()
|
@ -1,27 +0,0 @@
|
||||
# bash completion for openstack monasca
|
||||
|
||||
_monasca_opts="" # lazy init
|
||||
_monasca_flags="" # lazy init
|
||||
_monasca_opts_exp="" # lazy init
|
||||
_monasca()
|
||||
{
|
||||
local cur prev kbc
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
|
||||
if [ "x$_monasca_opts" == "x" ] ; then
|
||||
kbc="`monasca bash-completion | sed -e "s/ -h / /"`"
|
||||
_monasca_opts="`echo "$kbc" | sed -e "s/--[a-z0-9_-]*//g" -e "s/[ ][ ]*/ /g"`"
|
||||
_monasca_flags="`echo " $kbc" | sed -e "s/ [^-][^-][a-z0-9_-]*//g" -e "s/[ ][ ]*/ /g"`"
|
||||
_monasca_opts_exp="`echo $_monasca_opts | sed -e "s/[ ]/|/g"`"
|
||||
fi
|
||||
|
||||
if [[ " ${COMP_WORDS[@]} " =~ " "($_monasca_opts_exp)" " && "$prev" != "help" ]] ; then
|
||||
COMPREPLY=($(compgen -W "${_monasca_flags}" -- ${cur}))
|
||||
else
|
||||
COMPREPLY=($(compgen -W "${_monasca_opts}" -- ${cur}))
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
complete -o default -F _monasca monasca
|
@ -1,30 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Enforce the requirement that dependencies are listed in the input
|
||||
# files in alphabetical order.
|
||||
|
||||
# FIXME(dhellmann): This doesn't deal with URL requirements very
|
||||
# well. We should probably sort those on the egg-name, rather than the
|
||||
# full line.
|
||||
|
||||
function check_file {
|
||||
typeset f=$1
|
||||
|
||||
# We don't care about comment lines.
|
||||
grep -v '^#' $f > ${f}.unsorted
|
||||
sort -i -f ${f}.unsorted > ${f}.sorted
|
||||
diff -c ${f}.unsorted ${f}.sorted
|
||||
rc=$?
|
||||
rm -f ${f}.sorted ${f}.unsorted
|
||||
return $rc
|
||||
}
|
||||
|
||||
exit_code=0
|
||||
for filename in $@; do
|
||||
check_file $filename
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Please list requirements in $filename in alphabetical order" 1>&2
|
||||
exit_code=1
|
||||
fi
|
||||
done
|
||||
exit $exit_code
|
@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Client constraint file contains this client version pin that is in conflict
|
||||
# with installing the client from source. We should remove the version pin in
|
||||
# the constraints file before applying it for from-source installation.
|
||||
|
||||
CONSTRAINTS_FILE=$1
|
||||
shift 1
|
||||
|
||||
set -e
|
||||
|
||||
# NOTE(tonyb): Place this in the tox enviroment's log dir so it will get
|
||||
# published to logs.openstack.org for easy debugging.
|
||||
localfile="$VIRTUAL_ENV/log/upper-constraints.txt"
|
||||
|
||||
if [[ $CONSTRAINTS_FILE != http* ]]; then
|
||||
CONSTRAINTS_FILE=file://$CONSTRAINTS_FILE
|
||||
fi
|
||||
# NOTE(tonyb): need to add curl to bindep.txt if the project supports bindep
|
||||
curl $CONSTRAINTS_FILE --insecure --progress-bar --output $localfile
|
||||
|
||||
pip install -c$localfile openstack-requirements
|
||||
|
||||
# This is the main purpose of the script: Allow local installation of
|
||||
# the current repo. It is listed in constraints file and thus any
|
||||
# install will be constrained and we need to unconstrain it.
|
||||
edit-constraints $localfile -- $CLIENT_NAME
|
||||
|
||||
pip install -c$localfile -U $*
|
||||
exit $?
|
@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
command -v tox > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo 'This script requires "tox" to run.'
|
||||
echo 'You can install it with "pip install tox".'
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
tox -evenv -- $@
|
82
tox.ini
82
tox.ini
@ -1,82 +0,0 @@
|
||||
[tox]
|
||||
envlist = py{27,35},pypy,cover,pep8
|
||||
minversion = 2.5
|
||||
skipsdist = True
|
||||
|
||||
[testenv]
|
||||
setenv =
|
||||
VIRTUAL_ENV={envdir}
|
||||
BRANCH_NAME=master
|
||||
CLIENT_NAME=python-monascaclient
|
||||
OS_TEST_PATH=monascaclient/tests
|
||||
passenv = *_proxy
|
||||
*_PROXY
|
||||
usedevelop = True
|
||||
install_command =
|
||||
{toxinidir}/tools/tox_install.sh {env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
whitelist_externals = bash
|
||||
find
|
||||
rm
|
||||
commands =
|
||||
find . -type f -name "*.pyc" -delete
|
||||
rm -Rf .testrepository/times.dbm
|
||||
|
||||
[testenv:py27]
|
||||
basepython = python2.7
|
||||
commands =
|
||||
{[testenv]commands}
|
||||
ostestr {posargs}
|
||||
|
||||
[testenv:py35]
|
||||
basepython = python3.5
|
||||
commands =
|
||||
{[testenv]commands}
|
||||
ostestr {posargs}
|
||||
|
||||
[testenv:pypy]
|
||||
basepython = pypy
|
||||
commands =
|
||||
{[testenv]commands}
|
||||
ostestr {posargs}
|
||||
|
||||
[testenv:cover]
|
||||
basepython = python2.7
|
||||
commands =
|
||||
{[testenv]commands}
|
||||
coverage erase
|
||||
python setup.py test --coverage --testr-args='{posargs}' --coverage-package-name=monascaclient
|
||||
coverage report
|
||||
|
||||
[testenv:debug]
|
||||
commands =
|
||||
{[testenv]commands}
|
||||
oslo_debug_helper -t {env:OS_TEST_PATH} {posargs}
|
||||
|
||||
[testenv:pep8]
|
||||
skip_install = True
|
||||
usedevelop = False
|
||||
commands =
|
||||
{[testenv:flake8]commands}
|
||||
{[testenv:bandit]commands}
|
||||
|
||||
[testenv:flake8]
|
||||
skip_install = True
|
||||
usedevelop = False
|
||||
commands =
|
||||
flake8 monascaclient
|
||||
|
||||
[testenv:bandit]
|
||||
skip_install = True
|
||||
usedevelop = False
|
||||
commands =
|
||||
bandit -r monascaclient -n5 -x {env:OS_TEST_PATH}
|
||||
|
||||
[testenv:venv]
|
||||
commands = {posargs}
|
||||
|
||||
[flake8]
|
||||
show-source = True
|
||||
max-line-length = 120
|
||||
builtins = _
|
||||
exclude=.venv,.git,.tox,dist,client_api_example.py,*lib/python*,*egg,build
|
Loading…
Reference in New Issue
Block a user