python-monascaclient-1.10.0/0000775000175100017510000000000013231417275015761 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/releasenotes/0000775000175100017510000000000013231417275020452 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/releasenotes/notes/0000775000175100017510000000000013231417275021602 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/releasenotes/notes/openstack_docs-5cfec48411370070.yaml0000666000175100017510000000046113231417032027525 0ustar zuulzuul00000000000000--- prelude: > Documentation done right by Openstack process. issues: - | Removed the case where command documentation (held previously in markdown) is out-of-sync with the command itself. upgrade: - | Added details about using the CLI variant. Documented the usage of Python API. python-monascaclient-1.10.0/releasenotes/locale/0000775000175100017510000000000013231417275021711 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/releasenotes/locale/.gitkeep0000666000175100017510000000000013231417032023321 0ustar zuulzuul00000000000000python-monascaclient-1.10.0/releasenotes/source/0000775000175100017510000000000013231417275021752 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/releasenotes/source/conf.py0000666000175100017510000000427613231417032023253 0ustar zuulzuul00000000000000# -*- coding: utf-8 -*- # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. needs_sphinx = '1.6' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'openstackdocstheme', 'reno.sphinxext' ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. source_encoding = 'utf-8' # The master toctree document. master_doc = 'index' # General information about the project. repository_name = u'openstack/python-monascaclient' project = u'Monasca Client ReleaseNotes Docs' # Release notes do not need a version number in the title, they # cover multiple releases. version = '' release = '' bug_project = u'880' bug_tag = u'' copyright = u'2014-present, OpenStack Foundation' author = u'OpenStack Foundation' # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'openstackdocs' # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%Y-%m-%d %H:%M' # Output file base name for HTML help builder. htmlhelp_basename = 'MonascaClientReleaseNotesDoc' # -- Options for LaTeX output --------------------------------------------- latex_documents = [( master_doc, 'MonascaClientReleaseNotes.tex', u'Monasca Client Release Notes', [author], 'manual' )] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'monascaclientreleasenotes', u'Monasca Client Release Notes', [author], 1) ] # -- Options for Internationalization output ------------------------------ locale_dirs = ['locale/'] python-monascaclient-1.10.0/releasenotes/source/unreleased.rst0000666000175100017510000000016013231417032024621 0ustar zuulzuul00000000000000============================== Current Series Release Notes ============================== .. release-notes:: python-monascaclient-1.10.0/releasenotes/source/index.rst0000666000175100017510000000021713231417032023604 0ustar zuulzuul00000000000000============================ Monitoring API Release Notes ============================ Contents: .. toctree:: :maxdepth: 1 unreleased python-monascaclient-1.10.0/PKG-INFO0000664000175100017510000012603613231417275017066 0ustar zuulzuul00000000000000Metadata-Version: 1.1 Name: python-monascaclient Version: 1.10.0 Summary: Monasca API Client Library Home-page: https://docs.openstack.org/python-monascaclient/latest/ Author: OpenStack Author-email: openstack-dev@lists.openstack.org License: UNKNOWN Description-Content-Type: UNKNOWN Description: ======================== 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 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. Usage ===== You'll find complete documentation on the shell by running ``monasca help``:: usage: monasca [--version] [-v | -q] [--log-file LOG_FILE] [-h] [--debug] [--os-cloud ] [--os-region-name ] [--os-cacert ] [--os-cert ] [--os-key ] [--verify | --insecure] [--os-default-domain ] [--os-interface ] [--timing] [--os-beta-command] [--os-auth-type ] [--os-code ] [--os-protocol ] [--os-project-name ] [--os-trust-id ] [--os-domain-name ] [--os-user-domain-id ] [--os-access-token-type ] [--os-default-domain-name ] [--os-access-token-endpoint ] [--os-access-token ] [--os-domain-id ] [--os-user-domain-name ] [--os-openid-scope ] [--os-user-id ] [--os-identity-provider ] [--os-username ] [--os-auth-url ] [--os-client-secret ] [--os-default-domain-id ] [--os-discovery-endpoint ] [--os-client-id ] [--os-project-domain-name ] [--os-project-domain-id ] [--os-password ] [--os-redirect-uri ] [--os-endpoint ] [--os-token ] [--os-passcode ] [--os-project-id ] [--monasca-api-url MONASCA_API_URL] [--monasca-api-version MONASCA_API_VERSION] Command-line interface to the OpenStack APIs optional arguments: --version show program's version number and exit -v, --verbose Increase verbosity of output. Can be repeated. -q, --quiet Suppress output except warnings and errors. --log-file LOG_FILE Specify a file to log output. Disabled by default. -h, --help Show help message and exit. --debug Show tracebacks on errors. --os-cloud Cloud name in clouds.yaml (Env: OS_CLOUD) --os-region-name Authentication region name (Env: OS_REGION_NAME) --os-cacert CA certificate bundle file (Env: OS_CACERT) --os-cert Client certificate bundle file (Env: OS_CERT) --os-key Client certificate key file (Env: OS_KEY) --verify Verify server certificate (default) --insecure Disable server certificate verification --os-default-domain Default domain ID, default=default. (Env: OS_DEFAULT_DOMAIN) --os-interface Select an interface type. Valid interface types: [admin, public, internal]. (Env: OS_INTERFACE) --timing Print API call timing info --os-beta-command Enable beta commands which are subject to change --os-auth-type Select an authentication type. Available types: v2token, admin_token, v3oidcauthcode, v2password, v3password, v3oidcaccesstoken, v3oidcpassword, token, v3oidcclientcredentials, v3tokenlessauth, v3token, v3totp, password. Default: selected based on --os- username/--os-token (Env: OS_AUTH_TYPE) --os-code With v3oidcauthcode: OAuth 2.0 Authorization Code (Env: OS_CODE) --os-protocol With v3oidcauthcode: Protocol for federated plugin With v3oidcaccesstoken: Protocol for federated plugin With v3oidcpassword: Protocol for federated plugin With v3oidcclientcredentials: Protocol for federated plugin (Env: OS_PROTOCOL) --os-project-name With v3oidcauthcode: Project name to scope to With v3password: Project name to scope to With v3oidcaccesstoken: Project name to scope to With v3oidcpassword: Project name to scope to With token: Project name to scope to With v3oidcclientcredentials: Project name to scope to With v3tokenlessauth: Project name to scope to With v3token: Project name to scope to With v3totp: Project name to scope to With password: Project name to scope to (Env: OS_PROJECT_NAME) --os-trust-id With v2token: Trust ID With v3oidcauthcode: Trust ID With v2password: Trust ID With v3password: Trust ID With v3oidcaccesstoken: Trust ID With v3oidcpassword: Trust ID With token: Trust ID With v3oidcclientcredentials: Trust ID With v3token: Trust ID With v3totp: Trust ID With password: Trust ID (Env: OS_TRUST_ID) --os-domain-name With v3oidcauthcode: Domain name to scope to With v3password: Domain name to scope to With v3oidcaccesstoken: Domain name to scope to With v3oidcpassword: Domain name to scope to With token: Domain name to scope to With v3oidcclientcredentials: Domain name to scope to With v3tokenlessauth: Domain name to scope to With v3token: Domain name to scope to With v3totp: Domain name to scope to With password: Domain name to scope to (Env: OS_DOMAIN_NAME) --os-user-domain-id With v3password: User's domain id With v3totp: User's domain id With password: User's domain id (Env: OS_USER_DOMAIN_ID) --os-access-token-type With v3oidcauthcode: OAuth 2.0 Authorization Server Introspection token type, it is used to decide which type of token will be used when processing token introspection. Valid values are: "access_token" or "id_token" With v3oidcpassword: OAuth 2.0 Authorization Server Introspection token type, it is used to decide which type of token will be used when processing token introspection. Valid values are: "access_token" or "id_token" With v3oidcclientcredentials: OAuth 2.0 Authorization Server Introspection token type, it is used to decide which type of token will be used when processing token introspection. Valid values are: "access_token" or "id_token" (Env: OS_ACCESS_TOKEN_TYPE) --os-default-domain-name With token: Optional domain name to use with v3 API and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. With password: Optional domain name to use with v3 API and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. (Env: OS_DEFAULT_DOMAIN_NAME) --os-access-token-endpoint With v3oidcauthcode: OpenID Connect Provider Token Endpoint. Note that if a discovery document is being passed this option will override the endpoint provided by the server in the discovery document. With v3oidcpassword: OpenID Connect Provider Token Endpoint. Note that if a discovery document is being passed this option will override the endpoint provided by the server in the discovery document. With v3oidcclientcredentials: OpenID Connect Provider Token Endpoint. Note that if a discovery document is being passed this option will override the endpoint provided by the server in the discovery document. (Env: OS_ACCESS_TOKEN_ENDPOINT) --os-access-token With v3oidcaccesstoken: OAuth 2.0 Access Token (Env: OS_ACCESS_TOKEN) --os-domain-id With v3oidcauthcode: Domain ID to scope to With v3password: Domain ID to scope to With v3oidcaccesstoken: Domain ID to scope to With v3oidcpassword: Domain ID to scope to With token: Domain ID to scope to With v3oidcclientcredentials: Domain ID to scope to With v3tokenlessauth: Domain ID to scope to With v3token: Domain ID to scope to With v3totp: Domain ID to scope to With password: Domain ID to scope to (Env: OS_DOMAIN_ID) --os-user-domain-name With v3password: User's domain name With v3totp: User's domain name With password: User's domain name (Env: OS_USER_DOMAIN_NAME) --os-openid-scope With v3oidcauthcode: OpenID Connect scope that is requested from authorization server. Note that the OpenID Connect specification states that "openid" must be always specified. With v3oidcpassword: OpenID Connect scope that is requested from authorization server. Note that the OpenID Connect specification states that "openid" must be always specified. With v3oidcclientcredentials: OpenID Connect scope that is requested from authorization server. Note that the OpenID Connect specification states that "openid" must be always specified. (Env: OS_OPENID_SCOPE) --os-user-id With v2password: User ID to login with With v3password: User ID With v3totp: User ID With password: User id (Env: OS_USER_ID) --os-identity-provider With v3oidcauthcode: Identity Provider's name With v3oidcaccesstoken: Identity Provider's name With v3oidcpassword: Identity Provider's name With v3oidcclientcredentials: Identity Provider's name (Env: OS_IDENTITY_PROVIDER) --os-username With v2password: Username to login with With v3password: Username With v3oidcpassword: Username With v3totp: Username With password: Username (Env: OS_USERNAME) --os-auth-url With v2token: Authentication URL With v3oidcauthcode: Authentication URL With v2password: Authentication URL With v3password: Authentication URL With v3oidcaccesstoken: Authentication URL With v3oidcpassword: Authentication URL With token: Authentication URL With v3oidcclientcredentials: Authentication URL With v3tokenlessauth: Authentication URL With v3token: Authentication URL With v3totp: Authentication URL With password: Authentication URL (Env: OS_AUTH_URL) --os-client-secret With v3oidcauthcode: OAuth 2.0 Client Secret With v3oidcpassword: OAuth 2.0 Client Secret With v3oidcclientcredentials: OAuth 2.0 Client Secret (Env: OS_CLIENT_SECRET) --os-default-domain-id With token: Optional domain ID to use with v3 and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. With password: Optional domain ID to use with v3 and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. (Env: OS_DEFAULT_DOMAIN_ID) --os-discovery-endpoint With v3oidcauthcode: OpenID Connect Discovery Document URL. The discovery document will be used to obtain the values of the access token endpoint and the authentication endpoint. This URL should look like https://idp.example.org/.well-known/openid- configuration With v3oidcpassword: OpenID Connect Discovery Document URL. The discovery document will be used to obtain the values of the access token endpoint and the authentication endpoint. This URL should look like https://idp.example.org/.well-known/openid- configuration With v3oidcclientcredentials: OpenID Connect Discovery Document URL. The discovery document will be used to obtain the values of the access token endpoint and the authentication endpoint. This URL should look like https://idp.example.org/.well-known /openid-configuration (Env: OS_DISCOVERY_ENDPOINT) --os-client-id With v3oidcauthcode: OAuth 2.0 Client ID With v3oidcpassword: OAuth 2.0 Client ID With v3oidcclientcredentials: OAuth 2.0 Client ID (Env: OS_CLIENT_ID) --os-project-domain-name With v3oidcauthcode: Domain name containing project With v3password: Domain name containing project With v3oidcaccesstoken: Domain name containing project With v3oidcpassword: Domain name containing project With token: Domain name containing project With v3oidcclientcredentials: Domain name containing project With v3tokenlessauth: Domain name containing project With v3token: Domain name containing project With v3totp: Domain name containing project With password: Domain name containing project (Env: OS_PROJECT_DOMAIN_NAME) --os-project-domain-id With v3oidcauthcode: Domain ID containing project With v3password: Domain ID containing project With v3oidcaccesstoken: Domain ID containing project With v3oidcpassword: Domain ID containing project With token: Domain ID containing project With v3oidcclientcredentials: Domain ID containing project With v3tokenlessauth: Domain ID containing project With v3token: Domain ID containing project With v3totp: Domain ID containing project With password: Domain ID containing project (Env: OS_PROJECT_DOMAIN_ID) --os-password With v2password: Password to use With v3password: User's password With v3oidcpassword: Password With password: User's password (Env: OS_PASSWORD) --os-redirect-uri With v3oidcauthcode: OpenID Connect Redirect URL (Env: OS_REDIRECT_URI) --os-endpoint With admin_token: The endpoint that will always be used (Env: OS_ENDPOINT) --os-token With v2token: Token With admin_token: The token that will always be used With token: Token to authenticate with With v3token: Token to authenticate with (Env: OS_TOKEN) --os-passcode With v3totp: User's TOTP passcode (Env: OS_PASSCODE) --os-project-id With v3oidcauthcode: Project ID to scope to With v3password: Project ID to scope to With v3oidcaccesstoken: Project ID to scope to With v3oidcpassword: Project ID to scope to With token: Project ID to scope to With v3oidcclientcredentials: Project ID to scope to With v3tokenlessauth: Project ID to scope to With v3token: Project ID to scope to With v3totp: Project ID to scope to With password: Project ID to scope to (Env: OS_PROJECT_ID) --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 Commands: alarm-count Count alarms. 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 transition history. alarm-history-list List alarms state history. alarm-list List alarms for this tenant. alarm-patch Patch the alarm state. alarm-show Describe the alarm. alarm-update Update the alarm state. complete print bash completion command dimension-name-list List names of metric dimensions. dimension-value-list List names of metric dimensions. help print detailed help for another command 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-type-list List notification types supported by monasca. notification-update Update notification. Bash Completion --------------- Basic command tab completion can be enabled by sourcing the bash completion script. :: monasca completion >> /usr/local/share/monasca.bash_completion Metrics Examples ---------------- Note: To see complete usage: 'monasca help' and 'monasca help ' 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 ' 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 ' 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. There are three possible approaches, at the moment, you can take to use the client directly. On high level, these approaches can be described as: * using **username** and **password** * using **token** * using existing _` Username & password ------------------- Following approach allows to initialize the monascaclient in a traditional way. It requires **username** and **password**. Initialization of the client can be threfore executed with:: c = mon_client.Client(api_version='2_0', username=os.environ.get('OS_USERNAME', 'mini-mon'), password=os.environ.get('OS_PASSWORD', 'password'), auth_url=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1/identity'), project_name=os.environ.get('OS_PROJECT_NAME', 'mini-mon'), endpoint='http://127.0.0.1:8070/v2.0') Token ----- In order to use the monasclient 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/. Once **token** is available, a monascaclient can be initialized with following code:: c = mon_client.Client(api_version='2_0', endpoint='http://127.0.0.1:8070/v2.0' token=token_id, auth_url=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1/identity'), project_name=os.environ.get('OS_PROJECT_NAME', 'mini-mon')) Session ------- Usage of the monasclient with existing session can be expressed with following code:: from keystoneauth1 import session from keystoneauth1 import identity auth = identity.Token(auth_url=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1/identity'), token=token_id, project_name=os.environ.get('OS_PROJECT_NAME', 'mini-mon')) sess = session.Session(auth=auth) c = client.Client(api_version='2_0', endpoint='http://127.0.0.1:8070/v2.0' session=sess) The session object construction is much broader topic. It involves picking one of the following authorization methods: * Password * Token Alternatively, if Keystone version is known, you may choose: * V2Password or V3Password * V2Token of V3Token * V3OidcClientCredentials * V3OidcPassword * V3OidcAuthorizationCode * V3OidcAccessToken * V3TOTP * V3TokenlessAuth For more details about each one of those methods, please visit `official documentation `_. License ======= (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. Platform: UNKNOWN Classifier: Environment :: Console Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.5 python-monascaclient-1.10.0/.testr.conf0000666000175100017510000000057513231417032020047 0ustar zuulzuul00000000000000[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(?:\.|_)([^_]+) python-monascaclient-1.10.0/CONTRIBUTING.rst0000666000175100017510000000121313231417032020410 0ustar zuulzuul00000000000000If 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 python-monascaclient-1.10.0/AUTHORS0000664000175100017510000000471113231417273017032 0ustar zuulzuul00000000000000Andreas Jaeger Angelo Mendonca Anh Tran Artur Basiak Cao Xuan Hoang Christian Berendt Cindy O Neill Craig Bryant Craig Bryant Dao Cong Tien Deepak Dexter Fryar Dirk Mueller Doug Hellmann Eyal Flavio Percoco Haiwei Xu Igor Ataide Jamie Lennox Jeremy Liu Jeremy Stanley Joachim Barheine Joe Keen Joe Keen KATO Tomoyuki Kaiyan Sheng Longgeek Luong Anh Tuan Mark Reynolds Michael James Hoppal Nguyen Tuong Thanh Ondřej Nový Paulo Ewerton Rob Raymond Roland Hochmuth Ronald Bradford Ryan Bak Ryan Brandt SamKirsch10 Shinya Kawabata Stefan Caraiman Steve Martinelli Sumit Jamgade Swapnil Kulkarni (coolsvap) Thomas Goirand Tim Kuhlman Tomasz Trębski Tomasz Trębski Tony Breeds Victor Ion Munteanu Witold Bedyk ZhiQiang Fan Zuul bklei cindy oneill gecong1973 gengchc2 haali1 henriquetruta howardlee kornicameister lingyongxu oneilcin rajat29 venkatamahesh xhzhf python-monascaclient-1.10.0/requirements.txt0000666000175100017510000000072713231417032021244 0ustar zuulzuul00000000000000# 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.8.0 # Apache-2.0 oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0 oslo.utils>=3.33.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 # MIT six>=1.10.0 # MIT python-monascaclient-1.10.0/monascaclient/0000775000175100017510000000000013231417275020601 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/version.py0000666000175100017510000000136613231417032022637 0ustar zuulzuul00000000000000# 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() python-monascaclient-1.10.0/monascaclient/shell.py0000666000175100017510000000770213231417032022261 0ustar zuulzuul00000000000000# (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 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.set_defaults(cloud=None) 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:])) python-monascaclient-1.10.0/monascaclient/client.py0000666000175100017510000001256713231417032022435 0ustar zuulzuul00000000000000# (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 logging import warnings from keystoneauth1 import identity from keystoneauth1 import session as k_session from osc_lib import session as o_session from monascaclient.osc import migration from monascaclient import version LOG = logging.getLogger(__name__) _NO_VALUE_MARKER = object() def Client(api_version, *args, **kwargs): handle_deprecated(args, kwargs) client = migration.make_client( api_version=api_version, session=_session(kwargs), endpoint=kwargs.get('endpoint'), service_type=kwargs.get('service_type', 'monitoring') ) return client def _session(kwargs): """Returns or reuses session. Method takes care of providing instance of session object for the client. :param kwargs: all params (without api_version) client was initialized with :type kwargs: dict :returns: session object :rtype union(keystoneauth1.session.Session, osc_lib.session.TimingSession) """ if 'session' in kwargs: LOG.debug('Reusing session') sess = kwargs.get('session') expected_cls = (k_session.Session, o_session.TimingSession) if not isinstance(sess, expected_cls): msg = ('session should be an instance of [%s, %s]' % expected_cls) LOG.error(msg) raise RuntimeError(msg) else: LOG.debug('Initializing new session') auth = _get_auth_handler(kwargs) sess = _get_session(auth, kwargs) return sess 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 k_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 python-monascaclient-1.10.0/monascaclient/common/0000775000175100017510000000000013231417275022071 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/common/utils.py0000666000175100017510000001315713231417032023603 0ustar zuulzuul00000000000000# (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) python-monascaclient-1.10.0/monascaclient/common/__init__.py0000666000175100017510000000000013231417032024161 0ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/common/monasca_manager.py0000666000175100017510000000373113231417032025553 0ustar zuulzuul00000000000000# (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) python-monascaclient-1.10.0/monascaclient/__init__.py0000666000175100017510000000445513231417032022713 0ustar zuulzuul00000000000000# 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 python-monascaclient-1.10.0/monascaclient/tests/0000775000175100017510000000000013231417275021743 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/tests/test_client.py0000666000175100017510000001472013231417032024627 0ustar zuulzuul00000000000000# (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() @mock.patch('monascaclient.client.migration') @mock.patch('monascaclient.client._get_auth_handler') @mock.patch('monascaclient.client._get_session') def test_should_reuse_the_session_if_initialized_with_one(self, get_session, get_auth, _): from keystoneauth1 import session as k_session api_version = mock.Mock() session = mock.Mock(spec=k_session.Session) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') client.Client(api_version, session=session) self.assertEqual(0, len(w)) get_auth.assert_not_called() get_session.assert_not_called() @mock.patch('monascaclient.client.migration') @mock.patch('monascaclient.client._get_auth_handler') @mock.patch('monascaclient.client._get_session') def test_should_error_if_session_is_not_in_correct_type(self, _, __, ___): api_version = mock.Mock() for cls in [str, int, float]: session = mock.Mock(spec=cls) self.assertRaises(RuntimeError, client.Client, api_version, session=session) python-monascaclient-1.10.0/monascaclient/tests/__init__.py0000666000175100017510000000000013231417032024033 0ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/tests/v2_0/0000775000175100017510000000000013231417275022511 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/tests/v2_0/__init__.py0000666000175100017510000000000013231417032024601 0ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/tests/v2_0/shell/0000775000175100017510000000000013231417275023620 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/tests/v2_0/shell/test_alarm_definitions.py0000666000175100017510000001107113231417032030711 0ustar zuulzuul00000000000000# 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() python-monascaclient-1.10.0/monascaclient/tests/v2_0/shell/test_notifications.py0000666000175100017510000001321413231417032030074 0ustar zuulzuul00000000000000# 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) python-monascaclient-1.10.0/monascaclient/tests/v2_0/shell/__init__.py0000666000175100017510000000000013231417032025710 0ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/tests/v2_0/shell/test_notification_types.py0000666000175100017510000000326313231417032031140 0ustar zuulzuul00000000000000# 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() python-monascaclient-1.10.0/monascaclient/tests/v2_0/shell/test_metrics.py0000666000175100017510000000556313231417032026701 0ustar zuulzuul00000000000000# 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) python-monascaclient-1.10.0/monascaclient/tests/test_shell.py0000666000175100017510000000367513231417032024467 0ustar zuulzuul00000000000000# (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') python-monascaclient-1.10.0/monascaclient/v2_0/0000775000175100017510000000000013231417275021347 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/v2_0/metrics.py0000666000175100017510000000411213231417032023356 0ustar zuulzuul00000000000000# (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) python-monascaclient-1.10.0/monascaclient/v2_0/alarms.py0000666000175100017510000000650513231417032023177 0ustar zuulzuul00000000000000# (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 python-monascaclient-1.10.0/monascaclient/v2_0/notificationtypes.py0000666000175100017510000000162613231417032025472 0ustar zuulzuul00000000000000# (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) python-monascaclient-1.10.0/monascaclient/v2_0/alarm_definitions.py0000666000175100017510000000446213231417032025407 0ustar zuulzuul00000000000000# (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 python-monascaclient-1.10.0/monascaclient/v2_0/shell.py0000666000175100017510000016762613231417032023043 0ustar zuulzuul00000000000000# (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 datetime import json import numbers import time from keystoneauth1 import exceptions as k_exc from osc_lib import exceptions as osc_exc from monascaclient.common import utils from oslo_serialization import jsonutils # Alarm valid types severity_types = ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'] state_types = ['UNDETERMINED', 'ALARM', 'OK'] enabled_types = ['True', 'true', 'False', 'false'] group_by_types = ['alarm_definition_id', 'name', 'state', 'severity', 'link', 'lifecycle_state', 'metric_name', 'dimension_name', 'dimension_value'] allowed_notification_sort_by = {'id', 'name', 'type', 'address', 'created_at', 'updated_at'} allowed_alarm_sort_by = {'alarm_id', 'alarm_definition_id', 'alarm_definition_name', 'state', 'severity', 'lifecycle_state', 'link', 'state_updated_timestamp', 'updated_timestamp', 'created_timestamp'} allowed_definition_sort_by = {'id', 'name', 'severity', 'updated_at', 'created_at'} # Notification valid types notification_types = ['EMAIL', 'WEBHOOK', 'PAGERDUTY'] @utils.arg('name', metavar='', help='Name of the metric to create.') @utils.arg('--dimensions', metavar='', help='key value pair used to create a metric dimension. ' 'This can be specified multiple times, or once with parameters ' 'separated by a comma. ' 'Dimensions need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.', action='append') @utils.arg('--value-meta', metavar='', help='key value pair for extra information about a value. ' 'This can be specified multiple times, or once with parameters ' 'separated by a comma. ' 'value_meta need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.', action='append') @utils.arg('--time', metavar='', default=time.time() * 1000, type=int, help='Metric timestamp in milliseconds. Default: current timestamp.') @utils.arg('--project-id', metavar='', help='The Project ID to create metric on behalf of. ' 'Requires monitoring-delegate role in keystone.') @utils.arg('value', metavar='', type=float, help='Metric value.') def do_metric_create(mc, args): '''Create metric.''' fields = {} fields['name'] = args.name if args.dimensions: fields['dimensions'] = utils.format_parameters(args.dimensions) fields['timestamp'] = args.time fields['value'] = args.value if args.value_meta: fields['value_meta'] = utils.format_parameters(args.value_meta) if args.project_id: fields['tenant_id'] = args.project_id try: mc.metrics.create(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print('Successfully created metric') @utils.arg('jsonbody', metavar='', type=json.loads, help='The raw JSON body in single quotes. See api doc.') def do_metric_create_raw(mc, args): '''Create metric from raw json body.''' try: mc.metrics.create(**args.jsonbody) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print('Successfully created metric') @utils.arg('--dimensions', metavar='', help='key value pair used to specify a metric dimension. ' 'This can be specified multiple times, or once with parameters ' 'separated by a comma. ' 'Dimensions need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.', action='append') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum limit.') @utils.arg('--tenant-id', metavar='', help="Retrieve data for the specified tenant/project id instead of " "the tenant/project from the user's Keystone credentials.") def do_metric_name_list(mc, args): '''List names of metrics.''' fields = {} if args.dimensions: fields['dimensions'] = utils.format_dimensions_query(args.dimensions) if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset if args.tenant_id: fields['tenant_id'] = args.tenant_id try: metric_names = mc.metrics.list_names(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(metric_names)) return if isinstance(metric_names, list): utils.print_list(metric_names, ['Name'], formatters={'Name': lambda x: x['name']}) @utils.arg('--name', metavar='', help='Name of the metric to list.') @utils.arg('--dimensions', metavar='', help='key value pair used to specify a metric dimension. ' 'This can be specified multiple times, or once with parameters ' 'separated by a comma. ' 'Dimensions need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.', action='append') @utils.arg('--starttime', metavar='', help='measurements >= UTC time. format: 2014-01-01T00:00:00Z. OR Format: -120 (previous 120 minutes).') @utils.arg('--endtime', metavar='', help='measurements <= UTC time. format: 2014-01-01T00:00:00Z.') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum limit.') @utils.arg('--tenant-id', metavar='', help="Retrieve data for the specified tenant/project id instead of " "the tenant/project from the user's Keystone credentials.") def do_metric_list(mc, args): '''List metrics for this tenant.''' fields = {} if args.name: fields['name'] = args.name if args.dimensions: fields['dimensions'] = utils.format_dimensions_query(args.dimensions) if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset if args.starttime: _translate_starttime(args) fields['start_time'] = args.starttime if args.endtime: fields['end_time'] = args.endtime if args.tenant_id: fields['tenant_id'] = args.tenant_id try: metric = mc.metrics.list(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(metric)) return cols = ['name', 'dimensions'] formatters = { 'name': lambda x: x['name'], 'dimensions': lambda x: utils.format_dict(x['dimensions']), } if isinstance(metric, list): # print the list utils.print_list(metric, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works metric_list = list() metric_list.append(metric) utils.print_list( metric_list, cols, formatters=formatters) @utils.arg('--metric-name', metavar='', help='Name of the metric to report dimension name list.', action='append') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum ' 'limit.') @utils.arg('--tenant-id', metavar='', help="Retrieve data for the specified tenant/project id instead of " "the tenant/project from the user's Keystone credentials.") def do_dimension_name_list(mc, args): '''List names of metric dimensions.''' fields = {} if args.metric_name: fields['metric_name'] = args.metric_name if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset if args.tenant_id: fields['tenant_id'] = args.tenant_id try: dimension_names = mc.metrics.list_dimension_names(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) if args.json: print(utils.json_formatter(dimension_names)) return if isinstance(dimension_names, list): utils.print_list(dimension_names, ['Dimension Names'], formatters={ 'Dimension Names': lambda x: x['dimension_name']}) @utils.arg('dimension_name', metavar='', help='Name of the dimension to list dimension values.') @utils.arg('--metric-name', metavar='', help='Name of the metric to report dimension value list.', action='append') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum ' 'limit.') @utils.arg('--tenant-id', metavar='', help="Retrieve data for the specified tenant/project id instead of " "the tenant/project from the user's Keystone credentials.") def do_dimension_value_list(mc, args): '''List names of metric dimensions.''' fields = {} fields['dimension_name'] = args.dimension_name if args.metric_name: fields['metric_name'] = args.metric_name if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset if args.tenant_id: fields['tenant_id'] = args.tenant_id try: dimension_values = mc.metrics.list_dimension_values(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) if args.json: print(utils.json_formatter(dimension_values)) return if isinstance(dimension_values, list): utils.print_list(dimension_values, ['Dimension Values'], formatters={ 'Dimension Values': lambda x: x['dimension_value']}) def format_measure_timestamp(measurements): # returns newline separated times for the timestamp column return '\n'.join([str(m[0]) for m in measurements]) def format_measure_value(measurements): # returns newline separated values for the value column return '\n'.join(['{:12.3f}'.format(m[1]) for m in measurements]) def format_value_meta(measurements): # returns newline separated values for the value column measure_string_list = list() for measure in measurements: if len(measure) < 3: measure_string = "" else: meta_string_list = [] for k, v in measure[2].items(): if isinstance(v, numbers.Number): m_str = k + ': ' + str(v) else: m_str = k + ': ' + v meta_string_list.append(m_str) measure_string = ','.join(meta_string_list) measure_string_list.append(measure_string) return '\n'.join(measure_string_list) def format_statistic_timestamp(statistics, columns, name): # returns newline separated times for the timestamp column time_index = 0 if statistics: time_index = columns.index(name) time_list = list() for timestamp in statistics: time_list.append(str(timestamp[time_index])) return '\n'.join(time_list) def format_statistic_value(statistics, columns, stat_type): # find the index for column name stat_index = 0 if statistics: stat_index = columns.index(stat_type) value_list = list() for stat in statistics: value_str = '{:12.3f}'.format(stat[stat_index]) value_list.append(value_str) return '\n'.join(value_list) def format_metric_name(metrics): # returns newline separated metric names for the column metric_string_list = list() for metric in metrics: metric_name = metric['name'] metric_dimensions = metric['dimensions'] metric_string_list.append(metric_name) # need to line up with dimensions column rng = len(metric_dimensions) for i in range(rng): if i == rng - 1: # last one break metric_string_list.append(" ") return '\n'.join(metric_string_list) def format_metric_dimensions(metrics): # returns newline separated dimension key values for the column metric_string_list = list() for metric in metrics: metric_dimensions = metric['dimensions'] for k, v in metric_dimensions.items(): if isinstance(v, numbers.Number): d_str = k + ': ' + str(v) else: d_str = k + ': ' + v metric_string_list.append(d_str) return '\n'.join(metric_string_list) @utils.arg('name', metavar='', help='Name of the metric to list measurements.') @utils.arg('--dimensions', metavar='', help='key value pair used to specify a metric dimension. ' 'This can be specified multiple times, or once with parameters ' 'separated by a comma. ' 'Dimensions need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.', action='append') @utils.arg('starttime', metavar='', help='measurements >= UTC time. format: 2014-01-01T00:00:00Z. OR Format: -120 (previous 120 minutes).') @utils.arg('--endtime', metavar='', help='measurements <= UTC time. format: 2014-01-01T00:00:00Z.') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum limit.') @utils.arg('--merge_metrics', action='store_const', const=True, help='Merge multiple metrics into a single result.') @utils.arg('--group_by', metavar='', help='Select which keys to use for grouping. A \'*\' groups by all keys.') @utils.arg('--tenant-id', metavar='', help="Retrieve data for the specified tenant/project id instead of " "the tenant/project from the user's Keystone credentials.") def do_measurement_list(mc, args): '''List measurements for the specified metric.''' fields = {} fields['name'] = args.name if args.dimensions: fields['dimensions'] = utils.format_dimensions_query(args.dimensions) _translate_starttime(args) fields['start_time'] = args.starttime if args.endtime: fields['end_time'] = args.endtime if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset if args.merge_metrics: fields['merge_metrics'] = args.merge_metrics if args.group_by: fields['group_by'] = args.group_by if args.tenant_id: fields['tenant_id'] = args.tenant_id try: metric = mc.metrics.list_measurements(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(metric)) return cols = ['name', 'dimensions', 'timestamp', 'value', 'value_meta'] formatters = { 'name': lambda x: x['name'], 'dimensions': lambda x: utils.format_dict(x['dimensions']), 'timestamp': lambda x: format_measure_timestamp(x['measurements']), 'value': lambda x: format_measure_value(x['measurements']), 'value_meta': lambda x: format_value_meta(x['measurements']), } if isinstance(metric, list): # print the list utils.print_list(metric, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works metric_list = list() metric_list.append(metric) utils.print_list( metric_list, cols, formatters=formatters) @utils.arg('name', metavar='', help='Name of the metric to report measurement statistics.') @utils.arg('statistics', metavar='', help='Statistics is one or more (separated by commas) of ' '[AVG, MIN, MAX, COUNT, SUM].') @utils.arg('--dimensions', metavar='', help='key value pair used to specify a metric dimension. ' 'This can be specified multiple times, or once with parameters ' 'separated by a comma. ' 'Dimensions need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.', action='append') @utils.arg('starttime', metavar='', help='measurements >= UTC time. format: 2014-01-01T00:00:00Z. OR Format: -120 (previous 120 minutes).') @utils.arg('--endtime', metavar='', help='measurements <= UTC time. format: 2014-01-01T00:00:00Z.') @utils.arg('--period', metavar='', help='number of seconds per interval (default is 300)') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum limit.') @utils.arg('--merge_metrics', action='store_const', const=True, help='Merge multiple metrics into a single result.') @utils.arg('--group_by', metavar='', help='Select which keys to use for grouping. A \'*\' groups by all keys.') @utils.arg('--tenant-id', metavar='', help="Retrieve data for the specified tenant/project id instead of " "the tenant/project from the user's Keystone credentials.") def do_metric_statistics(mc, args): '''List measurement statistics for the specified metric.''' statistic_types = ['AVG', 'MIN', 'MAX', 'COUNT', 'SUM'] statlist = args.statistics.split(',') for stat in statlist: if stat.upper() not in statistic_types: errmsg = ('Invalid type, not one of [' + ', '.join(statistic_types) + ']') raise osc_exc.CommandError(errmsg) fields = {} fields['name'] = args.name if args.dimensions: fields['dimensions'] = utils.format_dimensions_query(args.dimensions) _translate_starttime(args) fields['start_time'] = args.starttime if args.endtime: fields['end_time'] = args.endtime if args.period: fields['period'] = args.period fields['statistics'] = args.statistics if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset if args.merge_metrics: fields['merge_metrics'] = args.merge_metrics if args.group_by: fields['group_by'] = args.group_by if args.tenant_id: fields['tenant_id'] = args.tenant_id try: metric = mc.metrics.list_statistics(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(metric)) return cols = ['name', 'dimensions'] # add dynamic column names if metric: column_names = metric[0]['columns'] for name in column_names: cols.append(name) else: # when empty set, print_list needs a col cols.append('timestamp') formatters = { 'name': lambda x: x['name'], 'dimensions': lambda x: utils.format_dict(x['dimensions']), 'timestamp': lambda x: format_statistic_timestamp(x['statistics'], x['columns'], 'timestamp'), 'avg': lambda x: format_statistic_value(x['statistics'], x['columns'], 'avg'), 'min': lambda x: format_statistic_value(x['statistics'], x['columns'], 'min'), 'max': lambda x: format_statistic_value(x['statistics'], x['columns'], 'max'), 'count': lambda x: format_statistic_value(x['statistics'], x['columns'], 'count'), 'sum': lambda x: format_statistic_value(x['statistics'], x['columns'], 'sum'), } if isinstance(metric, list): # print the list utils.print_list(metric, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works metric_list = list() metric_list.append(metric) utils.print_list( metric_list, cols, formatters=formatters) def _validate_notification_period(period, notification_type): if notification_type != 'WEBHOOK' and period != 0: print("Invalid period, can only be non zero for webhooks") return False return True @utils.arg('name', metavar='', help='Name of the notification to create.') @utils.arg('type', metavar='', help='The notification type. Type must be EMAIL, WEBHOOK, or PAGERDUTY.') @utils.arg('address', metavar='
', help='A valid EMAIL Address, URL, or SERVICE KEY.') @utils.arg('--period', metavar='', type=int, default=0, help='A period for the notification method. Can only be non zero with webhooks') def do_notification_create(mc, args): '''Create notification.''' fields = {} fields['name'] = args.name fields['type'] = args.type fields['address'] = args.address if args.period: if not _validate_notification_period(args.period, args.type.upper()): return fields['period'] = args.period try: notification = mc.notifications.create(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print(jsonutils.dumps(notification, indent=2)) @utils.arg('id', metavar='', help='The ID of the notification.') def do_notification_show(mc, args): '''Describe the notification.''' fields = {} fields['notification_id'] = args.id try: notification = mc.notifications.get(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(notification)) return formatters = { 'name': utils.json_formatter, 'id': utils.json_formatter, 'type': utils.json_formatter, 'address': utils.json_formatter, 'period': utils.json_formatter, 'links': utils.format_dictlist, } utils.print_dict(notification, formatters=formatters) @utils.arg('--sort-by', metavar='', help='Fields to sort by as a comma separated list. Valid values are id, ' 'name, type, address, created_at, updated_at. ' 'Fields may be followed by "asc" or "desc", ex "address desc", ' 'to set the direction of sorting.') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum limit.') def do_notification_list(mc, args): '''List notifications for this tenant.''' fields = {} if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset if args.sort_by: sort_by = args.sort_by.split(',') for field in sort_by: field_values = field.lower().split() if len(field_values) > 2: print("Invalid sort_by value {}".format(field)) if field_values[0] not in allowed_notification_sort_by: print("Sort-by field name {} is not in [{}]".format(field_values[0], allowed_notification_sort_by)) return if len(field_values) > 1 and field_values[1] not in ['asc', 'desc']: print("Invalid value {}, must be asc or desc".format(field_values[1])) fields['sort_by'] = args.sort_by try: notification = mc.notifications.list(**fields) except osc_exc.ClientException as he: raise osc_exc.CommandError( 'ClientException code=%s message=%s' % (he.code, he.message)) else: if args.json: print(utils.json_formatter(notification)) return cols = ['name', 'id', 'type', 'address', 'period'] formatters = { 'name': lambda x: x['name'], 'id': lambda x: x['id'], 'type': lambda x: x['type'], 'address': lambda x: x['address'], 'period': lambda x: x['period'], } if isinstance(notification, list): utils.print_list( notification, cols, formatters=formatters) else: notif_list = list() notif_list.append(notification) utils.print_list(notif_list, cols, formatters=formatters) @utils.arg('id', metavar='', help='The ID of the notification.') def do_notification_delete(mc, args): '''Delete notification.''' fields = {} fields['notification_id'] = args.id try: mc.notifications.delete(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print('Successfully deleted notification') @utils.arg('id', metavar='', help='The ID of the notification.') @utils.arg('name', metavar='', help='Name of the notification.') @utils.arg('type', metavar='', help='The notification type. Type must be either EMAIL, WEBHOOK, or PAGERDUTY.') @utils.arg('address', metavar='
', help='A valid EMAIL Address, URL, or SERVICE KEY.') @utils.arg('period', metavar='', type=int, help='A period for the notification method. Can only be non zero with webhooks') def do_notification_update(mc, args): '''Update notification.''' fields = {} fields['notification_id'] = args.id fields['name'] = args.name fields['type'] = args.type fields['address'] = args.address if not _validate_notification_period(args.period, args.type.upper()): return fields['period'] = args.period try: notification = mc.notifications.update(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print(jsonutils.dumps(notification, indent=2)) @utils.arg('id', metavar='', help='The ID of the notification.') @utils.arg('--name', metavar='', help='Name of the notification.') @utils.arg('--type', metavar='', help='The notification type. Type must be either EMAIL, WEBHOOK, or PAGERDUTY.') @utils.arg('--address', metavar='
', help='A valid EMAIL Address, URL, or SERVICE KEY.') @utils.arg('--period', metavar='', type=int, help='A period for the notification method. Can only be non zero with webhooks') def do_notification_patch(mc, args): '''Patch notification.''' fields = {} fields['notification_id'] = args.id if args.name: fields['name'] = args.name if args.type: fields['type'] = args.type if args.address: fields['address'] = args.address if args.period or args.period == 0: if args.type and not _validate_notification_period( args.period, args.type.upper()): return fields['period'] = args.period try: notification = mc.notifications.patch(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print(jsonutils.dumps(notification, indent=2)) def _validate_severity(severity): if severity.upper() not in severity_types: errmsg = ('Invalid severity, not one of [' + ', '.join(severity_types) + ']') print(errmsg) return False return True @utils.arg('name', metavar='', help='Name of the alarm definition to create.') @utils.arg('--description', metavar='', help='Description of the alarm.') @utils.arg('expression', metavar='', help='The alarm expression to evaluate. Quoted.') @utils.arg('--severity', metavar='', help='Severity is one of [LOW, MEDIUM, HIGH, CRITICAL].') @utils.arg('--match-by', metavar='', help='The metric dimensions to use to create unique alarms. ' 'One or more dimension key names separated by a comma. ' 'Key names need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.') @utils.arg('--alarm-actions', metavar='', help='The notification method to use when an alarm state is ALARM. ' 'This param may be specified multiple times.', action='append') @utils.arg('--ok-actions', metavar='', help='The notification method to use when an alarm state is OK. ' 'This param may be specified multiple times.', action='append') @utils.arg('--undetermined-actions', metavar='', help='The notification method to use when an alarm state is ' 'UNDETERMINED. This param may be specified multiple times.', action='append') def do_alarm_definition_create(mc, args): '''Create an alarm definition.''' fields = {} fields['name'] = args.name if args.description: fields['description'] = args.description fields['expression'] = args.expression if args.alarm_actions: fields['alarm_actions'] = args.alarm_actions if args.ok_actions: fields['ok_actions'] = args.ok_actions if args.undetermined_actions: fields['undetermined_actions'] = args.undetermined_actions if args.severity: if not _validate_severity(args.severity): return fields['severity'] = args.severity if args.match_by: fields['match_by'] = args.match_by.split(',') try: alarm = mc.alarm_definitions.create(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print(jsonutils.dumps(alarm, indent=2)) @utils.arg('id', metavar='', help='The ID of the alarm definition.') def do_alarm_definition_show(mc, args): '''Describe the alarm definition.''' fields = {} fields['alarm_id'] = args.id try: alarm = mc.alarm_definitions.get(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(alarm)) return # print out detail of a single alarm formatters = { 'name': utils.json_formatter, 'id': utils.json_formatter, 'expression': utils.json_formatter, 'expression_data': utils.format_expression_data, 'match_by': utils.json_formatter, 'actions_enabled': utils.json_formatter, 'alarm_actions': utils.json_formatter, 'ok_actions': utils.json_formatter, 'severity': utils.json_formatter, 'undetermined_actions': utils.json_formatter, 'description': utils.json_formatter, 'links': utils.format_dictlist, } utils.print_dict(alarm, formatters=formatters) @utils.arg('--name', metavar='', help='Name of the alarm definition.') @utils.arg('--dimensions', metavar='', help='key value pair used to specify a metric dimension. ' 'This can be specified multiple times, or once with parameters ' 'separated by a comma. ' 'Dimensions need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.', action='append') @utils.arg('--severity', metavar='', help='Severity is one of ["LOW", "MEDIUM", "HIGH", "CRITICAL"].') @utils.arg('--sort-by', metavar='', help='Fields to sort by as a comma separated list. Valid values are id, ' 'name, severity, created_at, updated_at. ' 'Fields may be followed by "asc" or "desc", ex "severity desc", ' 'to set the direction of sorting.') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum limit.') def do_alarm_definition_list(mc, args): '''List alarm definitions for this tenant.''' fields = {} if args.name: fields['name'] = args.name if args.dimensions: fields['dimensions'] = utils.format_dimensions_query(args.dimensions) if args.severity: if not _validate_severity(args.severity): return fields['severity'] = args.severity if args.sort_by: sort_by = args.sort_by.split(',') for field in sort_by: field_values = field.split() if len(field_values) > 2: print("Invalid sort_by value {}".format(field)) if field_values[0] not in allowed_definition_sort_by: print("Sort-by field name {} is not in [{}]".format(field_values[0], allowed_definition_sort_by)) return if len(field_values) > 1 and field_values[1] not in ['asc', 'desc']: print("Invalid value {}, must be asc or desc".format(field_values[1])) fields['sort_by'] = args.sort_by if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset try: alarm = mc.alarm_definitions.list(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(alarm)) return cols = ['name', 'id', 'expression', 'match_by', 'actions_enabled'] formatters = { 'name': lambda x: x['name'], 'id': lambda x: x['id'], 'expression': lambda x: x['expression'], 'match_by': lambda x: utils.format_list(x['match_by']), 'actions_enabled': lambda x: x['actions_enabled'], } if isinstance(alarm, list): # print the list utils.print_list(alarm, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works alarm_list = list() alarm_list.append(alarm) utils.print_list(alarm_list, cols, formatters=formatters) @utils.arg('id', metavar='', help='The ID of the alarm definition.') def do_alarm_definition_delete(mc, args): '''Delete the alarm definition.''' fields = {} fields['alarm_id'] = args.id try: mc.alarm_definitions.delete(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print('Successfully deleted alarm definition') @utils.arg('id', metavar='', help='The ID of the alarm definition.') @utils.arg('name', metavar='', help='Name of the alarm definition.') @utils.arg('description', metavar='', help='Description of the alarm.') @utils.arg('expression', metavar='', help='The alarm expression to evaluate. Quoted.') @utils.arg('alarm_actions', metavar='', help='The notification method(s) to use when an alarm state is ALARM ' 'as a comma separated list.') @utils.arg('ok_actions', metavar='', help='The notification method(s) to use when an alarm state is OK ' 'as a comma separated list.') @utils.arg('undetermined_actions', metavar='', help='The notification method(s) to use when an alarm state is UNDETERMINED ' 'as a comma separated list.') @utils.arg('actions_enabled', metavar='', help='The actions-enabled boolean is one of [true,false]') @utils.arg('match_by', metavar='', help='The metric dimensions to use to create unique alarms. ' 'One or more dimension key names separated by a comma. ' 'Key names need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.') @utils.arg('severity', metavar='', help='Severity is one of [LOW, MEDIUM, HIGH, CRITICAL].') def do_alarm_definition_update(mc, args): '''Update the alarm definition.''' fields = {} fields['alarm_id'] = args.id fields['name'] = args.name fields['description'] = args.description fields['expression'] = args.expression fields['alarm_actions'] = _arg_split_patch_update(args.alarm_actions) fields['ok_actions'] = _arg_split_patch_update(args.ok_actions) fields['undetermined_actions'] = _arg_split_patch_update(args.undetermined_actions) if args.actions_enabled not in enabled_types: errmsg = ('Invalid value, not one of [' + ', '.join(enabled_types) + ']') print(errmsg) return fields['actions_enabled'] = args.actions_enabled in ['true', 'True'] fields['match_by'] = _arg_split_patch_update(args.match_by) if not _validate_severity(args.severity): return fields['severity'] = args.severity try: alarm = mc.alarm_definitions.update(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print(jsonutils.dumps(alarm, indent=2)) @utils.arg('id', metavar='', help='The ID of the alarm definition.') @utils.arg('--name', metavar='', help='Name of the alarm definition.') @utils.arg('--description', metavar='', help='Description of the alarm.') @utils.arg('--expression', metavar='', help='The alarm expression to evaluate. Quoted.') @utils.arg('--alarm-actions', metavar='', help='The notification method to use when an alarm state is ALARM. ' 'This param may be specified multiple times.', action='append') @utils.arg('--ok-actions', metavar='', help='The notification method to use when an alarm state is OK. ' 'This param may be specified multiple times.', action='append') @utils.arg('--undetermined-actions', metavar='', help='The notification method to use when an alarm state is ' 'UNDETERMINED. This param may be specified multiple times.', action='append') @utils.arg('--actions-enabled', metavar='', help='The actions-enabled boolean is one of [true,false].') @utils.arg('--severity', metavar='', help='Severity is one of [LOW, MEDIUM, HIGH, CRITICAL].') def do_alarm_definition_patch(mc, args): '''Patch the alarm definition.''' fields = {} fields['alarm_id'] = args.id if args.name: fields['name'] = args.name if args.description: fields['description'] = args.description if args.expression: fields['expression'] = args.expression if args.alarm_actions: fields['alarm_actions'] = _arg_split_patch_update(args.alarm_actions, patch=True) if args.ok_actions: fields['ok_actions'] = _arg_split_patch_update(args.ok_actions, patch=True) if args.undetermined_actions: fields['undetermined_actions'] = _arg_split_patch_update(args.undetermined_actions, patch=True) if args.actions_enabled: if args.actions_enabled not in enabled_types: errmsg = ('Invalid value, not one of [' + ', '.join(enabled_types) + ']') print(errmsg) return fields['actions_enabled'] = args.actions_enabled in ['true', 'True'] if args.severity: if not _validate_severity(args.severity): return fields['severity'] = args.severity try: alarm = mc.alarm_definitions.patch(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print(jsonutils.dumps(alarm, indent=2)) @utils.arg('--alarm-definition-id', metavar='', help='The ID of the alarm definition.') @utils.arg('--metric-name', metavar='', help='Name of the metric.') @utils.arg('--metric-dimensions', metavar='', help='key value pair used to specify a metric dimension or ' 'just key to select all values of that dimension.' 'This can be specified multiple times, or once with parameters ' 'separated by a comma. ' 'Dimensions need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.', action='append') @utils.arg('--state', metavar='', help='ALARM_STATE is one of [UNDETERMINED, OK, ALARM].') @utils.arg('--severity', metavar='', help='Severity is one of ["LOW", "MEDIUM", "HIGH", "CRITICAL"].') @utils.arg('--state-updated-start-time', metavar='', help='Return all alarms whose state was updated on or after the time specified.') @utils.arg('--lifecycle-state', metavar='', help='The lifecycle state of the alarm.') @utils.arg('--link', metavar='', help='The link to external data associated with the alarm.') @utils.arg('--sort-by', metavar='', help='Fields to sort by as a comma separated list. Valid values are alarm_id, ' 'alarm_definition_id, state, severity, lifecycle_state, link, ' 'state_updated_timestamp, updated_timestamp, created_timestamp. ' 'Fields may be followed by "asc" or "desc", ex "severity desc", ' 'to set the direction of sorting.') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum limit.') def do_alarm_list(mc, args): '''List alarms for this tenant.''' fields = {} if args.alarm_definition_id: fields['alarm_definition_id'] = args.alarm_definition_id if args.metric_name: fields['metric_name'] = args.metric_name if args.metric_dimensions: fields['metric_dimensions'] = utils.format_dimensions_query(args.metric_dimensions) if args.state: if args.state.upper() not in state_types: errmsg = ('Invalid state, not one of [' + ', '.join(state_types) + ']') print(errmsg) return fields['state'] = args.state if args.severity: if not _validate_severity(args.severity): return fields['severity'] = args.severity if args.state_updated_start_time: fields['state_updated_start_time'] = args.state_updated_start_time if args.lifecycle_state: fields['lifecycle_state'] = args.lifecycle_state if args.link: fields['link'] = args.link if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset if args.sort_by: sort_by = args.sort_by.split(',') for field in sort_by: field_values = field.lower().split() if len(field_values) > 2: print("Invalid sort_by value {}".format(field)) if field_values[0] not in allowed_alarm_sort_by: print("Sort-by field name {} is not in [{}]".format(field_values[0], allowed_alarm_sort_by)) return if len(field_values) > 1 and field_values[1] not in ['asc', 'desc']: print("Invalid value {}, must be asc or desc".format(field_values[1])) fields['sort_by'] = args.sort_by try: alarm = mc.alarms.list(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(alarm)) return cols = ['id', 'alarm_definition_id', 'alarm_definition_name', 'metric_name', 'metric_dimensions', 'severity', 'state', 'lifecycle_state', 'link', 'state_updated_timestamp', 'updated_timestamp', "created_timestamp"] formatters = { 'id': lambda x: x['id'], 'alarm_definition_id': lambda x: x['alarm_definition']['id'], 'alarm_definition_name': lambda x: x['alarm_definition']['name'], 'metric_name': lambda x: format_metric_name(x['metrics']), 'metric_dimensions': lambda x: format_metric_dimensions(x['metrics']), 'severity': lambda x: x['alarm_definition']['severity'], 'state': lambda x: x['state'], 'lifecycle_state': lambda x: x['lifecycle_state'], 'link': lambda x: x['link'], 'state_updated_timestamp': lambda x: x['state_updated_timestamp'], 'updated_timestamp': lambda x: x['updated_timestamp'], 'created_timestamp': lambda x: x['created_timestamp'], } if isinstance(alarm, list): # print the list utils.print_list(alarm, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works alarm_list = list() alarm_list.append(alarm) utils.print_list(alarm_list, cols, formatters=formatters) @utils.arg('id', metavar='', help='The ID of the alarm.') def do_alarm_show(mc, args): '''Describe the alarm.''' fields = {} fields['alarm_id'] = args.id try: alarm = mc.alarms.get(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(alarm)) return # print out detail of a single alarm formatters = { 'id': utils.json_formatter, 'alarm_definition': utils.json_formatter, 'metrics': utils.json_formatter, 'state': utils.json_formatter, 'links': utils.format_dictlist, } utils.print_dict(alarm, formatters=formatters) @utils.arg('id', metavar='', help='The ID of the alarm.') @utils.arg('state', metavar='', help='ALARM_STATE is one of [UNDETERMINED, OK, ALARM].') @utils.arg('lifecycle_state', metavar='', help='The lifecycle state of the alarm.') @utils.arg('link', metavar='', help='A link to an external resource with information about the alarm.') def do_alarm_update(mc, args): '''Update the alarm state.''' fields = {} fields['alarm_id'] = args.id if args.state.upper() not in state_types: errmsg = ('Invalid state, not one of [' + ', '.join(state_types) + ']') print(errmsg) return fields['state'] = args.state fields['lifecycle_state'] = args.lifecycle_state fields['link'] = args.link try: alarm = mc.alarms.update(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print(jsonutils.dumps(alarm, indent=2)) @utils.arg('id', metavar='', help='The ID of the alarm.') @utils.arg('--state', metavar='', help='ALARM_STATE is one of [UNDETERMINED, OK, ALARM].') @utils.arg('--lifecycle-state', metavar='', help='The lifecycle state of the alarm.') @utils.arg('--link', metavar='', help='A link to an external resource with information about the alarm.') def do_alarm_patch(mc, args): '''Patch the alarm state.''' fields = {} fields['alarm_id'] = args.id if args.state: if args.state.upper() not in state_types: errmsg = ('Invalid state, not one of [' + ', '.join(state_types) + ']') print(errmsg) return fields['state'] = args.state if args.lifecycle_state: fields['lifecycle_state'] = args.lifecycle_state if args.link: fields['link'] = args.link try: alarm = mc.alarms.patch(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print(jsonutils.dumps(alarm, indent=2)) @utils.arg('id', metavar='', help='The ID of the alarm.') def do_alarm_delete(mc, args): '''Delete the alarm.''' fields = {} fields['alarm_id'] = args.id try: mc.alarms.delete(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: print('Successfully deleted alarm') def output_alarm_history(args, alarm_history): if args.json: print(utils.json_formatter(alarm_history)) return # format output cols = ['alarm_id', 'new_state', 'old_state', 'reason', 'reason_data', 'metric_name', 'metric_dimensions', 'timestamp'] formatters = { 'alarm_id': lambda x: x['alarm_id'], 'new_state': lambda x: x['new_state'], 'old_state': lambda x: x['old_state'], 'reason': lambda x: x['reason'], 'reason_data': lambda x: x['reason_data'], 'metric_name': lambda x: format_metric_name(x['metrics']), 'metric_dimensions': lambda x: format_metric_dimensions(x['metrics']), 'timestamp': lambda x: x['timestamp'], } if isinstance(alarm_history, list): # print the list utils.print_list(alarm_history, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works alarm_list = list() alarm_list.append(alarm_history) utils.print_list(alarm_list, cols, formatters=formatters) @utils.arg('--alarm-definition-id', metavar='', help='The ID of the alarm definition.') @utils.arg('--metric-name', metavar='', help='Name of the metric.') @utils.arg('--metric-dimensions', metavar='', help='key value pair used to specify a metric dimension or ' 'just key to select all values of that dimension.' 'This can be specified multiple times, or once with parameters ' 'separated by a comma. ' 'Dimensions need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.', action='append') @utils.arg('--state', metavar='', help='ALARM_STATE is one of [UNDETERMINED, OK, ALARM].') @utils.arg('--severity', metavar='', help='Severity is one of ["LOW", "MEDIUM", "HIGH", "CRITICAL"].') @utils.arg('--state-updated-start-time', metavar='', help='Return all alarms whose state was updated on or after the time specified.') @utils.arg('--lifecycle-state', metavar='', help='The lifecycle state of the alarm.') @utils.arg('--link', metavar='', help='The link to external data associated with the alarm.') @utils.arg('--group-by', metavar='', help='Comma separated list of one or more fields to group the results by. ' 'Group by is one or more of [alarm_definition_id, name, state, link, ' 'lifecycle_state, metric_name, dimension_name, dimension_value].') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum limit.') def do_alarm_count(mc, args): '''Count alarms.''' fields = {} if args.alarm_definition_id: fields['alarm_definition_id'] = args.alarm_definition_id if args.metric_name: fields['metric_name'] = args.metric_name if args.metric_dimensions: fields['metric_dimensions'] = utils.format_dimensions_query(args.metric_dimensions) if args.state: if args.state.upper() not in state_types: errmsg = ('Invalid state, not one of [' + ', '.join(state_types) + ']') print(errmsg) return fields['state'] = args.state if args.severity: if not _validate_severity(args.severity): return fields['severity'] = args.severity if args.state_updated_start_time: fields['state_updated_start_time'] = args.state_updated_start_time if args.lifecycle_state: fields['lifecycle_state'] = args.lifecycle_state if args.link: fields['link'] = args.link if args.group_by: group_by = args.group_by.split(',') if not set(group_by).issubset(set(group_by_types)): errmsg = ('Invalid group-by, one or more values not in [' + ','.join(group_by_types) + ']') print(errmsg) return fields['group_by'] = args.group_by if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset try: counts = mc.alarms.count(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(counts)) return cols = counts['columns'] utils.print_list(counts['counts'], [i for i in range(len(cols))], field_labels=cols) @utils.arg('id', metavar='', help='The ID of the alarm.') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum limit.') def do_alarm_history(mc, args): '''Alarm state transition history.''' fields = {} fields['alarm_id'] = args.id if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset try: alarm = mc.alarms.history(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: output_alarm_history(args, alarm) @utils.arg('--dimensions', metavar='', help='key value pair used to specify a metric dimension. ' 'This can be specified multiple times, or once with parameters ' 'separated by a comma. ' 'Dimensions need quoting when they contain special chars [&,(,),{,},>,<] ' 'that confuse the CLI parser.', action='append') @utils.arg('--starttime', metavar='', help='measurements >= UTC time. format: 2014-01-01T00:00:00Z. OR format: -120 (previous 120 minutes).') @utils.arg('--endtime', metavar='', help='measurements <= UTC time. format: 2014-01-01T00:00:00Z.') @utils.arg('--offset', metavar='', help='The offset used to paginate the return data.') @utils.arg('--limit', metavar='', help='The amount of data to be returned up to the API maximum limit.') def do_alarm_history_list(mc, args): '''List alarms state history.''' fields = {} if args.dimensions: fields['dimensions'] = utils.format_parameters(args.dimensions) if args.starttime: _translate_starttime(args) fields['start_time'] = args.starttime if args.endtime: fields['end_time'] = args.endtime if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset try: alarm = mc.alarms.history_list(**fields) except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: output_alarm_history(args, alarm) def do_notification_type_list(mc, args): '''List notification types supported by monasca.''' try: notification_types = mc.notificationtypes.list() except (osc_exc.ClientException, k_exc.HttpError) as he: raise osc_exc.CommandError('%s\n%s' % (he.message, he.details)) else: if args.json: print(utils.json_formatter(notification_types)) return else: formatters = {'types': lambda x: x["type"]} # utils.print_list(notification_types['types'], ["types"], formatters=formatters) utils.print_list(notification_types, ["types"], formatters=formatters) def _translate_starttime(args): if args.starttime[0] == '-': deltaT = time.time() + (int(args.starttime) * 60) utc = str(datetime.datetime.utcfromtimestamp(deltaT)) utc = utc.replace(" ", "T")[:-7] + 'Z' args.starttime = utc def _arg_split_patch_update(arg, patch=False): if patch: arg = ','.join(arg) if not arg or arg == "[]": arg_split = [] else: arg_split = arg.split(',') return arg_split python-monascaclient-1.10.0/monascaclient/v2_0/client.py0000666000175100017510000000270113231417032023170 0ustar zuulzuul00000000000000# (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" python-monascaclient-1.10.0/monascaclient/v2_0/__init__.py0000666000175100017510000000125613231417032023455 0ustar zuulzuul00000000000000# (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 python-monascaclient-1.10.0/monascaclient/v2_0/notifications.py0000666000175100017510000000441513231417032024567 0ustar zuulzuul00000000000000# (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 python-monascaclient-1.10.0/monascaclient/osc/0000775000175100017510000000000013231417275021365 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/monascaclient/osc/migration.py0000666000175100017510000001234113231417032023722 0ustar zuulzuul00000000000000# 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 python-monascaclient-1.10.0/monascaclient/osc/__init__.py0000666000175100017510000000000013231417032023455 0ustar zuulzuul00000000000000python-monascaclient-1.10.0/tox.ini0000666000175100017510000000524013231417032017266 0ustar zuulzuul00000000000000[tox] envlist = py{27,35},pypy,cover,pep8 minversion = 2.5 skipsdist = True [testenv] setenv = VIRTUAL_ENV={envdir} OS_TEST_PATH=monascaclient/tests PYTHONWARNINGS=default::DeprecationWarning passenv = *_proxy *_PROXY usedevelop = True install_command = pip install {opts} {packages} deps = -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} -r{toxinidir}/test-requirements.txt whitelist_externals = bash find rm commands = find {toxinidir} -type f -name "*.pyc" -delete rm -Rf {toxinidir}/.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 --omit=monascaclient/tests/* 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:checkniceness]commands} [testenv:flake8] skip_install = True usedevelop = False commands = {[testenv]commands} flake8 monascaclient [testenv:bandit] skip_install = True usedevelop = False commands = {[testenv]commands} bandit -r monascaclient -n5 -x {env:OS_TEST_PATH} [testenv:docs] description = Builds full monascaclient documentation commands = {[testenv]commands} {[testenv:devdocs]commands} {[testenv:releasenotes]commands} [testenv:devdocs] description = Builds developer documentation commands = rm -rf {toxinidir}/doc/build {toxinidir}/doc/source/contributor/api python setup.py build_sphinx [testenv:releasenotes] description = Called from CI script to test and publish the Release Notes commands = rm -rf releasenotes/build sphinx-build -a -E -d {toxinidir}/releasenotes/build/doctrees -b html {toxinidir}/releasenotes/source {toxinidir}/releasenotes/build/html [testenv:checkniceness] description = Validates (pep-like) documenation commands = {[testenv]commands} doc8 --file-encoding utf-8 {toxinidir}/doc doc8 --file-encoding utf-8 {toxinidir}/releasenotes [testenv:venv] commands = {posargs} [hacking] import_exceptions = six.moves [flake8] show-source = True max-line-length = 120 builtins = _ exclude=.venv,.git,.tox,dist,client_api_example.py,*lib/python*,*egg,build python-monascaclient-1.10.0/test-requirements.txt0000666000175100017510000000114013231417032022207 0ustar zuulzuul00000000000000# 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>=3.2.0 # Apache-2.0 os-testr>=1.0.0 # Apache-2.0 testrepository>=0.0.18 # Apache-2.0/BSD testscenarios>=0.4 # Apache-2.0/BSD testtools>=2.2.0 # MIT # documentation doc8>=0.6.0 # Apache-2.0 sphinx!=1.6.6,>=1.6.2 # BSD reno>=2.5.0 # Apache-2.0 openstackdocstheme>=1.17.0 # Apache-2.0 python-monascaclient-1.10.0/README.rst0000666000175100017510000011157113231417032017447 0ustar zuulzuul00000000000000======================== 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 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. Usage ===== You'll find complete documentation on the shell by running ``monasca help``:: usage: monasca [--version] [-v | -q] [--log-file LOG_FILE] [-h] [--debug] [--os-cloud ] [--os-region-name ] [--os-cacert ] [--os-cert ] [--os-key ] [--verify | --insecure] [--os-default-domain ] [--os-interface ] [--timing] [--os-beta-command] [--os-auth-type ] [--os-code ] [--os-protocol ] [--os-project-name ] [--os-trust-id ] [--os-domain-name ] [--os-user-domain-id ] [--os-access-token-type ] [--os-default-domain-name ] [--os-access-token-endpoint ] [--os-access-token ] [--os-domain-id ] [--os-user-domain-name ] [--os-openid-scope ] [--os-user-id ] [--os-identity-provider ] [--os-username ] [--os-auth-url ] [--os-client-secret ] [--os-default-domain-id ] [--os-discovery-endpoint ] [--os-client-id ] [--os-project-domain-name ] [--os-project-domain-id ] [--os-password ] [--os-redirect-uri ] [--os-endpoint ] [--os-token ] [--os-passcode ] [--os-project-id ] [--monasca-api-url MONASCA_API_URL] [--monasca-api-version MONASCA_API_VERSION] Command-line interface to the OpenStack APIs optional arguments: --version show program's version number and exit -v, --verbose Increase verbosity of output. Can be repeated. -q, --quiet Suppress output except warnings and errors. --log-file LOG_FILE Specify a file to log output. Disabled by default. -h, --help Show help message and exit. --debug Show tracebacks on errors. --os-cloud Cloud name in clouds.yaml (Env: OS_CLOUD) --os-region-name Authentication region name (Env: OS_REGION_NAME) --os-cacert CA certificate bundle file (Env: OS_CACERT) --os-cert Client certificate bundle file (Env: OS_CERT) --os-key Client certificate key file (Env: OS_KEY) --verify Verify server certificate (default) --insecure Disable server certificate verification --os-default-domain Default domain ID, default=default. (Env: OS_DEFAULT_DOMAIN) --os-interface Select an interface type. Valid interface types: [admin, public, internal]. (Env: OS_INTERFACE) --timing Print API call timing info --os-beta-command Enable beta commands which are subject to change --os-auth-type Select an authentication type. Available types: v2token, admin_token, v3oidcauthcode, v2password, v3password, v3oidcaccesstoken, v3oidcpassword, token, v3oidcclientcredentials, v3tokenlessauth, v3token, v3totp, password. Default: selected based on --os- username/--os-token (Env: OS_AUTH_TYPE) --os-code With v3oidcauthcode: OAuth 2.0 Authorization Code (Env: OS_CODE) --os-protocol With v3oidcauthcode: Protocol for federated plugin With v3oidcaccesstoken: Protocol for federated plugin With v3oidcpassword: Protocol for federated plugin With v3oidcclientcredentials: Protocol for federated plugin (Env: OS_PROTOCOL) --os-project-name With v3oidcauthcode: Project name to scope to With v3password: Project name to scope to With v3oidcaccesstoken: Project name to scope to With v3oidcpassword: Project name to scope to With token: Project name to scope to With v3oidcclientcredentials: Project name to scope to With v3tokenlessauth: Project name to scope to With v3token: Project name to scope to With v3totp: Project name to scope to With password: Project name to scope to (Env: OS_PROJECT_NAME) --os-trust-id With v2token: Trust ID With v3oidcauthcode: Trust ID With v2password: Trust ID With v3password: Trust ID With v3oidcaccesstoken: Trust ID With v3oidcpassword: Trust ID With token: Trust ID With v3oidcclientcredentials: Trust ID With v3token: Trust ID With v3totp: Trust ID With password: Trust ID (Env: OS_TRUST_ID) --os-domain-name With v3oidcauthcode: Domain name to scope to With v3password: Domain name to scope to With v3oidcaccesstoken: Domain name to scope to With v3oidcpassword: Domain name to scope to With token: Domain name to scope to With v3oidcclientcredentials: Domain name to scope to With v3tokenlessauth: Domain name to scope to With v3token: Domain name to scope to With v3totp: Domain name to scope to With password: Domain name to scope to (Env: OS_DOMAIN_NAME) --os-user-domain-id With v3password: User's domain id With v3totp: User's domain id With password: User's domain id (Env: OS_USER_DOMAIN_ID) --os-access-token-type With v3oidcauthcode: OAuth 2.0 Authorization Server Introspection token type, it is used to decide which type of token will be used when processing token introspection. Valid values are: "access_token" or "id_token" With v3oidcpassword: OAuth 2.0 Authorization Server Introspection token type, it is used to decide which type of token will be used when processing token introspection. Valid values are: "access_token" or "id_token" With v3oidcclientcredentials: OAuth 2.0 Authorization Server Introspection token type, it is used to decide which type of token will be used when processing token introspection. Valid values are: "access_token" or "id_token" (Env: OS_ACCESS_TOKEN_TYPE) --os-default-domain-name With token: Optional domain name to use with v3 API and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. With password: Optional domain name to use with v3 API and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. (Env: OS_DEFAULT_DOMAIN_NAME) --os-access-token-endpoint With v3oidcauthcode: OpenID Connect Provider Token Endpoint. Note that if a discovery document is being passed this option will override the endpoint provided by the server in the discovery document. With v3oidcpassword: OpenID Connect Provider Token Endpoint. Note that if a discovery document is being passed this option will override the endpoint provided by the server in the discovery document. With v3oidcclientcredentials: OpenID Connect Provider Token Endpoint. Note that if a discovery document is being passed this option will override the endpoint provided by the server in the discovery document. (Env: OS_ACCESS_TOKEN_ENDPOINT) --os-access-token With v3oidcaccesstoken: OAuth 2.0 Access Token (Env: OS_ACCESS_TOKEN) --os-domain-id With v3oidcauthcode: Domain ID to scope to With v3password: Domain ID to scope to With v3oidcaccesstoken: Domain ID to scope to With v3oidcpassword: Domain ID to scope to With token: Domain ID to scope to With v3oidcclientcredentials: Domain ID to scope to With v3tokenlessauth: Domain ID to scope to With v3token: Domain ID to scope to With v3totp: Domain ID to scope to With password: Domain ID to scope to (Env: OS_DOMAIN_ID) --os-user-domain-name With v3password: User's domain name With v3totp: User's domain name With password: User's domain name (Env: OS_USER_DOMAIN_NAME) --os-openid-scope With v3oidcauthcode: OpenID Connect scope that is requested from authorization server. Note that the OpenID Connect specification states that "openid" must be always specified. With v3oidcpassword: OpenID Connect scope that is requested from authorization server. Note that the OpenID Connect specification states that "openid" must be always specified. With v3oidcclientcredentials: OpenID Connect scope that is requested from authorization server. Note that the OpenID Connect specification states that "openid" must be always specified. (Env: OS_OPENID_SCOPE) --os-user-id With v2password: User ID to login with With v3password: User ID With v3totp: User ID With password: User id (Env: OS_USER_ID) --os-identity-provider With v3oidcauthcode: Identity Provider's name With v3oidcaccesstoken: Identity Provider's name With v3oidcpassword: Identity Provider's name With v3oidcclientcredentials: Identity Provider's name (Env: OS_IDENTITY_PROVIDER) --os-username With v2password: Username to login with With v3password: Username With v3oidcpassword: Username With v3totp: Username With password: Username (Env: OS_USERNAME) --os-auth-url With v2token: Authentication URL With v3oidcauthcode: Authentication URL With v2password: Authentication URL With v3password: Authentication URL With v3oidcaccesstoken: Authentication URL With v3oidcpassword: Authentication URL With token: Authentication URL With v3oidcclientcredentials: Authentication URL With v3tokenlessauth: Authentication URL With v3token: Authentication URL With v3totp: Authentication URL With password: Authentication URL (Env: OS_AUTH_URL) --os-client-secret With v3oidcauthcode: OAuth 2.0 Client Secret With v3oidcpassword: OAuth 2.0 Client Secret With v3oidcclientcredentials: OAuth 2.0 Client Secret (Env: OS_CLIENT_SECRET) --os-default-domain-id With token: Optional domain ID to use with v3 and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. With password: Optional domain ID to use with v3 and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. (Env: OS_DEFAULT_DOMAIN_ID) --os-discovery-endpoint With v3oidcauthcode: OpenID Connect Discovery Document URL. The discovery document will be used to obtain the values of the access token endpoint and the authentication endpoint. This URL should look like https://idp.example.org/.well-known/openid- configuration With v3oidcpassword: OpenID Connect Discovery Document URL. The discovery document will be used to obtain the values of the access token endpoint and the authentication endpoint. This URL should look like https://idp.example.org/.well-known/openid- configuration With v3oidcclientcredentials: OpenID Connect Discovery Document URL. The discovery document will be used to obtain the values of the access token endpoint and the authentication endpoint. This URL should look like https://idp.example.org/.well-known /openid-configuration (Env: OS_DISCOVERY_ENDPOINT) --os-client-id With v3oidcauthcode: OAuth 2.0 Client ID With v3oidcpassword: OAuth 2.0 Client ID With v3oidcclientcredentials: OAuth 2.0 Client ID (Env: OS_CLIENT_ID) --os-project-domain-name With v3oidcauthcode: Domain name containing project With v3password: Domain name containing project With v3oidcaccesstoken: Domain name containing project With v3oidcpassword: Domain name containing project With token: Domain name containing project With v3oidcclientcredentials: Domain name containing project With v3tokenlessauth: Domain name containing project With v3token: Domain name containing project With v3totp: Domain name containing project With password: Domain name containing project (Env: OS_PROJECT_DOMAIN_NAME) --os-project-domain-id With v3oidcauthcode: Domain ID containing project With v3password: Domain ID containing project With v3oidcaccesstoken: Domain ID containing project With v3oidcpassword: Domain ID containing project With token: Domain ID containing project With v3oidcclientcredentials: Domain ID containing project With v3tokenlessauth: Domain ID containing project With v3token: Domain ID containing project With v3totp: Domain ID containing project With password: Domain ID containing project (Env: OS_PROJECT_DOMAIN_ID) --os-password With v2password: Password to use With v3password: User's password With v3oidcpassword: Password With password: User's password (Env: OS_PASSWORD) --os-redirect-uri With v3oidcauthcode: OpenID Connect Redirect URL (Env: OS_REDIRECT_URI) --os-endpoint With admin_token: The endpoint that will always be used (Env: OS_ENDPOINT) --os-token With v2token: Token With admin_token: The token that will always be used With token: Token to authenticate with With v3token: Token to authenticate with (Env: OS_TOKEN) --os-passcode With v3totp: User's TOTP passcode (Env: OS_PASSCODE) --os-project-id With v3oidcauthcode: Project ID to scope to With v3password: Project ID to scope to With v3oidcaccesstoken: Project ID to scope to With v3oidcpassword: Project ID to scope to With token: Project ID to scope to With v3oidcclientcredentials: Project ID to scope to With v3tokenlessauth: Project ID to scope to With v3token: Project ID to scope to With v3totp: Project ID to scope to With password: Project ID to scope to (Env: OS_PROJECT_ID) --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 Commands: alarm-count Count alarms. 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 transition history. alarm-history-list List alarms state history. alarm-list List alarms for this tenant. alarm-patch Patch the alarm state. alarm-show Describe the alarm. alarm-update Update the alarm state. complete print bash completion command dimension-name-list List names of metric dimensions. dimension-value-list List names of metric dimensions. help print detailed help for another command 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-type-list List notification types supported by monasca. notification-update Update notification. Bash Completion --------------- Basic command tab completion can be enabled by sourcing the bash completion script. :: monasca completion >> /usr/local/share/monasca.bash_completion Metrics Examples ---------------- Note: To see complete usage: 'monasca help' and 'monasca help ' 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 ' 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 ' 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. There are three possible approaches, at the moment, you can take to use the client directly. On high level, these approaches can be described as: * using **username** and **password** * using **token** * using existing _` Username & password ------------------- Following approach allows to initialize the monascaclient in a traditional way. It requires **username** and **password**. Initialization of the client can be threfore executed with:: c = mon_client.Client(api_version='2_0', username=os.environ.get('OS_USERNAME', 'mini-mon'), password=os.environ.get('OS_PASSWORD', 'password'), auth_url=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1/identity'), project_name=os.environ.get('OS_PROJECT_NAME', 'mini-mon'), endpoint='http://127.0.0.1:8070/v2.0') Token ----- In order to use the monasclient 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/. Once **token** is available, a monascaclient can be initialized with following code:: c = mon_client.Client(api_version='2_0', endpoint='http://127.0.0.1:8070/v2.0' token=token_id, auth_url=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1/identity'), project_name=os.environ.get('OS_PROJECT_NAME', 'mini-mon')) Session ------- Usage of the monasclient with existing session can be expressed with following code:: from keystoneauth1 import session from keystoneauth1 import identity auth = identity.Token(auth_url=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1/identity'), token=token_id, project_name=os.environ.get('OS_PROJECT_NAME', 'mini-mon')) sess = session.Session(auth=auth) c = client.Client(api_version='2_0', endpoint='http://127.0.0.1:8070/v2.0' session=sess) The session object construction is much broader topic. It involves picking one of the following authorization methods: * Password * Token Alternatively, if Keystone version is known, you may choose: * V2Password or V3Password * V2Token of V3Token * V3OidcClientCredentials * V3OidcPassword * V3OidcAuthorizationCode * V3OidcAccessToken * V3TOTP * V3TokenlessAuth For more details about each one of those methods, please visit `official documentation `_. License ======= (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. python-monascaclient-1.10.0/ChangeLog0000664000175100017510000002445013231417273017536 0ustar zuulzuul00000000000000CHANGES ======= 1.10.0 ------ * Updated from global requirements * Updated from global requirements * Updated from global requirements * Update usage examples * TrivialFix: remove redundant import alias * Updated from global requirements 1.9.0 ----- * Updated from global requirements * Updated from global requirements * Avoid tox\_install.sh for constraints support * Enable client documentation 1.8.0 ----- * Fix auth version detection * Updated from global requirements * Updated from global requirements * Cleanup repo and update documentation * Allow to reuse the session * Exclude tests from coverage * Update the documentation link for doc migration 1.7.0 ----- * Bringing back backward compatybility * Updated from global requirements * Integrate client with osc-lib * Updated from global requirements * Updated from global requirements * Updated from global requirements 1.6.0 ----- * Added support for os\_auth\_version when os\_auth\_url is unversiond * Added support for os\_tenant\_{name,id} after os\_project\_ * Optimize the link address * Updated from global requirements * Replacing six.iteritems() with .items() * Updated from global requirements * Migrate fully to ostestr * Updated from global requirements * Remove unused requirements * Fix notification-patch CLI fails if type not given * Fix: CLI metric-create using project-id fails * Updated from global requirements * Turn on bandit check as part of pep8 1.5.0 ----- * Typo fix: recieve => receive * Remove support for py33 * Updated from global requirements * Don't send X-Auth- headers in requests * Use requests-mock instead of custom fakes * H803 hacking have been deprecated 1.4.0 ----- * Updated from global requirements * Delete deprecated Hacking in tox.ini * Add py35 tox environment * Use the new copy of tox\_install.sh for global constraints support * Correct reraising of exception * Add \_\_ne\_\_ built-in function * Show team and repo badges on README * Add list\_next for pagination * Add CONTRIBUTING.rst 1.3.0 ----- * Fix LOG.warn to LOG.warning * move old apiclient code out of openstack/common * remove unused openstack/common/gettextutils.py * use six.moves.urllib.parse instead of py3kcompat * Use correct ENV variables for scoping * Changed author and author-email * Remove a space of Docstring * Add state-updated-timestamp filter to alarm count CLI * Sample nagios plugin and examples directory * Remove white space between print and () * Dimension value list doesn't recognize dimension name input * Change LOG.warn to LOG.warning * Add list dimension names and values in CLI * Use constraints everywhere * Sync tools/tox\_install.sh * Add support for new rest api notification-type-list * Remove discover from test-requirements * Fix dimension validation and help message for alarm count * Patch-notification failed with period=0 * Prevent potentially destructive updates on data * Fix monasca enpoint port in example and README * Fix \_\_str\_\_ not returning a String for KeystoneException * Fix monasca notification-show help message * Fixes H904: wrapping using parantheses * Add notification-patch into CLI 1.2.0 ----- * Add metric-name-list help command description * Revert 'Adding keystoneauth sessions support' * Sort by alarm\_definition\_name 1.1.0 ----- * Remove the debian folder * Oslo.utils safe\_decode * Update copyright in monascaclient * Adding keystoneauth sessions support * Graduate to oslo.utils strutils * Graduate to using oslo.utils importutils * Graduate to oslo.serialization jsonutils * [python-monascaclient] Change tox to use https instead of git * Add period field to notification methods * code compatibility with py3 * Constraint tox targets with upper-constraints.txt * Fix the homepage in setup.cfg * Add support for group\_by to measurements and statistics resources * Manually sync with global-requirements * [Trivial] Remove executable privilege of setup.py * Add --tenant-id option for some commands * Specify match\_by in alarm-definition-update help message * Alarm def update/patch failed with empty param * Change tox file * Implement monasca metric-name-list * Fix metric dimensions having only key 1.0.30 ------ * Fix argument name bug * Allow sorting notifications * Fixes typo in help messages for Monasca client * Convert to lower case before validating sort-by * Allow filtering by severity * Check Status Code in Monasca Client * Add in HPE Copyrights * Add missing spaces in help message 1.0.29 ------ * Enhanced dimension filtering * Allow sorting alarms 1.0.28 ------ * Unlocking requirements for Mitaka compatibility * Add alarm-count command * Remove MANIFEST.in * remove python 2.6 trove classifier * Return monasca specific error on conneciton refused * Deprecated tox -downloadcache option removed 1.0.27 ------ * Adding oslo.concurrency to requirements 1.0.26 ------ * Further restrictions on oslo.service 1.0.25 ------ * Adding liberty versions of oslo to requirements.txt * Fix documentation for creating metrics * Add start and end time optional parms to metric list * Delete python bytecode before every test run * Require all fields alarm definition update * use last specified value for duplicate dimension * Adding thousandths column to value output * mask X-Auth-Key for log\_curl\_request * Remove default environment variable string * Add the ability to use env variables 1.0.24 ------ * Update .gitreview for new namespace * Fix unicode output format * X-Auth-Key should not be required in the header 1.0.23 ------ * Pinning version of keystone client * Add timeout to keystone requests * Obfuscate Token in Debug Mode * Enable optional timeouts for http get or post requests 1.0.22 ------ * Add HP copyright to files that HP has changed * Force oslo.utils<2.0 * support users in domains other than Default (KSv3) 1.0.21 ------ * Make sure that we do not output token 1.0.20 ------ * Moved pbr requirements to a newer constraint * Removed output sorting in client * changed alarm-list output to match expected 1.0.19 ------ * added relative start time feature * Fixed README for Python API - about re-athenticate * replace v2.0 auth\_url with v3 * re-authenticates (once) with keystone to handle token expiration * Add lifecycle fields to CLI * The ERROR word was removed from the HttpException 2015.1 ------ * Moved CLI specific error message from ksclient to shell 1.0.18 ------ * Correctly selects endpoint based on region * added link to pypi versions * Fixed display problem with value\_meta * Add metric name list to the client library 1.0.17 ------ * Fixed readme with line feeds * Adjusted formatting functions for new measurement data * Made metric name required for measurement-list command * Expose state\_updated\_timestamp and created\_timestamp in alarm table 1.0.16 ------ * Adjusted client for influx 0.9 * Made name parameter for measurement-list optional * Fixed suppression of HTTP exceptions * Added offset and limit for list based commands 1.0.15 ------ 1.0.14 ------ * Handle API returning dict instead of list 1.0.13 ------ * Add measurement valueMeta * Conversion to milliseconds * Added development package and install instructions 1.0.12 ------ * No longer send application/json-patch+json as Content-Type * remove ChangeLog file so pbr can generate it from git * help for metric-create, and updated README * Fixed missing Pagerduty refs in docs and cli messages * Added pagerduty to the valid set of notifications 1.0.11 ------ * Remove match-by argument for alarm-definition-patch 1.0.10 ------ * Put the keystone auth in its own class * Enabling the support of Webhook notification on client * Allow service\_type to be overwritten * Pass the --os-service-type argument to keystone 1.0.8 ----- * Use relative path for monasca.bash\_completion 1.0.7 ----- * Update ChangeLog * Removing support for SMS on client * Need to pass the ca-file arg to keystone, too 1.0.6 ----- * Use keystone v3 and get a project scoped token 1.0.5 ----- * alarm formatting changes 1.0.4 ----- * Alarmed metrics API changes supported * updated README.rst for API clients 1.0.3 ----- * Added cross domain tenant param to metric POST * fixed unicode decode problem when printing exception * use keystone endpoint when api url is not input 1.0.2 ----- * Updated Changelog * help for dimensions mentions need for quoting * supports unicode 1.0.1 ----- * Fix several bashate issues * user pbr.version, update ChangeLog * Add .gitreview file * Bump hacking to 0.9.x series * removed transform dimension calls for alarm commands * quote alarm expression dimension values to allow special chars 1.0.0 ----- * renaming monclient to monascaclient, alarm-update fix * GET alarms by name, Client replace\_token, help fixes, id size * Add .gitreview file. pep8 fixes * README update for bash completion * added bash completion script to the install * pep8 changes * fixed timestamp ordering in measurement-list, alarm-history. renamed enabled to actions-enabled * Fixed enabled parms for alarm-patch, alarm-update * 1.0.3 * Add babel as a dependency * Updated version info * Updated README * Added metric-statistics command * Modified the auth token to match dev env * Added severity to alarm commands, Added alarm-list by state option * 1.0.1 changelog * new metric-create-raw command to support raw json body * Temporary fix for version problems in the egg/wheel * Added ChangeLog and .idea to the .gitignore * Modified README.rst * Improved the README.rst * alarm-list supports optional dimensions * Removed personal info from example and tests * Updated setup.cfg * Added HP copyright and Apache 2.0 license header. Added HACKING.rst and LICENSE file * Simplified exception handling by catching HTTPException * Updated client\_api\_example.py * removed runlocal args from resource commands, added example for api * support for alarm-history, fixed timestamp format measurement-list * Support for PUT,PATCH alarms, PUT notification-methods * Fixed measurement-list, alarm-list * added -j,--json output parameter, supported multi-dimensions in single parameter * Improved dict and dictlist formatting - put this in utils.py * fixed help formatting. metric-list formatting changed * added -l option, pep8 spacing * Latest changes to clean up the list commands * list and show implemented for alarms and notifications * Notification create working * Initial debian package setup * Unit tests working * metrics-create working * Initial monclient files. Help, and versioning is working python-monascaclient-1.10.0/setup.cfg0000666000175100017510000000200213231417275017576 0ustar zuulzuul00000000000000[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://docs.openstack.org/python-monascaclient/latest/ 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 [entry_points] console_scripts = monasca = monascaclient.shell:main [build_sphinx] source-dir = doc/source build-dir = doc/build all_files = 1 warning-is-error = 1 [build_releasenotes] all_files = 1 build-dir = releasenotes/build source-dir = releasenotes/source [wheel] universal = 1 [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 python-monascaclient-1.10.0/doc/0000775000175100017510000000000013231417275016526 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/doc/source/0000775000175100017510000000000013231417275020026 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/doc/source/conf.py0000666000175100017510000000742113231417032021322 0ustar zuulzuul00000000000000# -*- coding: utf-8 -*- import os import sys from monascaclient.version import version_info sys.path = [ os.path.abspath('../..'), os.path.abspath('../../bin') ] + sys.path # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. needs_sphinx = '1.6' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.coverage', 'sphinx.ext.ifconfig', 'sphinx.ext.graphviz', 'sphinx.ext.viewcode', 'openstackdocstheme' ] # geeneral information about project repository_name = u'openstack/python-monascaclient' project = u'Monasca Client Dev Docs' version = version_info.canonical_version_string() release = version_info.version_string_with_vcs() bug_project = u'880' bug_tag = u'' copyright = u'2014-present, OpenStack Foundation' author = u'OpenStack Foundation' # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. source_suffix = '.rst' # The encoding of source files. source_encoding = 'utf-8' # The master toctree document. master_doc = 'index' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [ 'common', 'doc', 'documentation', 'etc', 'java' ] # If true, '()' will be appended to :func: etc. cross-reference text. add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. show_authors = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'openstackdocs' # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%Y-%m-%d %H:%M' # If false, no index is generated. html_use_index = True # If false, no module index is generated. html_use_modindex = True # Output file base name for HTML help builder. htmlhelp_basename = 'python-monascaclientdoc' # -- Options for LaTeX output --------------------------------------------- # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'python-monascaclient.tex', u'python-monascaclient Documentation', u'Openstack Foundation \\textless{}monasca@lists.launchpad.net\\textgreater{}', 'manual'), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'python-monascaclient', u'python-monascaclient Documentation', [author], 1) ] # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'python-monascaclient', u'python-monascaclient Documentation', author, 'python-monascaclient', 'Rest-API to collect logs from your cloud.', 'Miscellaneous'), ] # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'https://doc.python.org/': None} python-monascaclient-1.10.0/doc/source/usage/0000775000175100017510000000000013231417275021132 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/doc/source/usage/index.rst0000666000175100017510000000124713231417032022770 0ustar zuulzuul00000000000000===== Usage ===== Devstack -------- python-monascaclient is bundled inside `Monasca API Devstack Plugin`_ and is available right after the devstack finished stacking up. It is always built from the **master** branch, unless specified otherwise. Docker ------ The client is also part of `monasca-docker`_, a community effort to put **monasca** into containers. The image is available as **monasca/client** and can be used as drop-in replacement for traditional way of deploying the clients. .. _Monasca API Devstack Plugin: https://github.com/openstack/monasca-api/tree/master/devstack .. _monasca-docker: https://github.com/monasca/monasca-docker/tree/master/monasca-client python-monascaclient-1.10.0/doc/source/reference/0000775000175100017510000000000013231417275021764 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/doc/source/reference/index.rst0000666000175100017510000000535013231417032023621 0ustar zuulzuul00000000000000================ Using Python API ================ Python bindings to the OpenStack Monasca API ============================================ This is a client for the OpenStack Monasca API. It includes a Python API (the :mod:`monascaclient` module) and a command-line script (installed as :program:`monasca`). Python API ========== To use python-monascaclient in a project, you need to create a client instance first. There are couple ways of doing this properly. With session ------------ A pseudo-code would be similar to this:: from keystoneauth1 import identity from keystoneauth1 import session from monascaclient import client auth = identity.Password( auth_url='http://my.keystone.com/identity', username='mini-mon', password='password', project_name='mini-mon', user_domain_id='default', project_domain_id='default' ) sess = session.Session(auth=auth) endpoint = 'http://monasca:8070/v2.0' api_version = '2_0' c = client.Client( api_version=api_version, endpoint=endpoint, session=sess ) c.alarms.list() For more information on keystoneauth API, see `Using Sessions`_. We also suggest taking closer look at `Keystone Auth Plugins`_. Each of the plugin can be used to properly instantiate new session and pass it into the client. .. note:: This is recommended way to setup a client. Other cases, described below, create sessions internally. Without session --------------- If you do not want to use a session or simply prefer client to instantiate one on its own, there are two supported ways With token ~~~~~~~~~~ A pseudo-code would be similar to this:: from monascaclient import client c = client.Client( api_version='2_0', endpoint='http://monasca:8070/v2.0', token='3bcc3d3a03f44e3d8377f9247b0ad155', project_name='mini-mon', auth_url='http://my.keystone.com/identity' ) c.alarms.list() With username & password ~~~~~~~~~~~~~~~~~~~~~~~~ A pseudo-code would be similar to this:: from monascaclient import client c = client.Client( api_version='2_0', endpoint='http://monasca:8070/v2.0', username='mini-mon', password='password', project_name='mini-mon', auth_url='http://my.keystone.com/identity' ) c.alarms.list() Examples ======== * `Monasca Agent Example`_ - with session * `Monasca UI Example`_ - with token .. _Monasca Agent Example: https://github.com/openstack/monasca-agent/blob/master/monasca_agent/forwarder/api/monasca_api.py .. _Monasca UI Example: https://github.com/openstack/monasca-ui/blob/master/monitoring/api/client.py .. _Using Sessions: https://docs.openstack.org/keystoneauth/latest/using-sessions.html .. _Keystone Auth Plugins: https://docs.openstack.org/keystoneauth/latest/authentication-plugins.html python-monascaclient-1.10.0/doc/source/index.rst0000666000175100017510000000234313231417032021662 0ustar zuulzuul00000000000000.. 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. ================================== python-monascaclient documentation ================================== This is a client for OpenStack Monitoring API. It provides :doc:`Python API bindings ` (the monascaclient module) and :doc:`command-line interface (CLI) `. User Documentation ------------------ .. toctree:: :maxdepth: 2 cli/index reference/index Usage ----- In the :doc:`Usage `, you will find information on possible ways to use python-monascaclient. .. toctree:: :maxdepth: 2 usage/index History ------- Release notes is available at http://docs.openstack.org/releasenotes/python-monascaclient/. python-monascaclient-1.10.0/doc/source/cli/0000775000175100017510000000000013231417275020575 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/doc/source/cli/monasca.rst0000666000175100017510000000551613231417032022750 0ustar zuulzuul00000000000000================= Using monasca CLI ================= The **monasca** shell utility interacts with OpenStack Monitoring API from the command-line. It supports the entire features of OpenStack Monitoring API. Basic Usage ----------- In order to use the CLI, you must provide your OpenStack username, password, project, domain information for both user and project, and auth endpoint. Use the corresponding configuration options (``--os-username``, ``--os-password``, ``--os-project-name``, ``--os-user-domain-id``, ``os-project-domain-id``, and ``--os-auth-url``), but it is easier to set them in environment variables. .. code-block:: shell export OS_USERNAME=mini-mon export OS_PASSWORD=password export OS_PROJECT_NAME=mini-mon export OS_USER_DOMAIN_ID=default export OS_PROJECT_DOMAIN_ID=default export OS_AUTH_URL=http://keystone:5000/v3 If you are using Identity v2.0 API (DEPRECATED), you don't need to pass domain information. .. code-block:: shell export OS_USERNAME=mini-mon export OS_PASSWORD=password export OS_TENANT_NAME=mini-mon export OS_AUTH_URL=http://keystone:5000/v2.0 Once you've configured your authentication parameters, you can run **monasca** commands. All commands take the form of: .. code-block:: text monasca [arguments...] Run **monasca help** to get a full list of all possible commands, and run **monasca help ** to get detailed help for that command. Using with os-client-config ~~~~~~~~~~~~~~~~~~~~~~~~~~~ `os-client-config `_ provides more convenient way to manage a collection of client configurations and you can easily switch multiple OpenStack-based configurations. To use os-client-config, you first need to prepare ``~/.config/openstack/clouds.yaml`` like the following. .. code-block:: yaml clouds: monitoring: auth: auth_url: http://keystone:5000 password: password project_domain_id: default project_name: mini-mon user_domain_id: default username: mini-mon identity_api_version: '3' region_name: RegionOne Then, you need to specify a configuration name defined in the above clouds.yaml. .. code-block:: shell export OS_CLOUD=monitoring For more detail information, see the `os-client-config `_ documentation. Using with keystone token ~~~~~~~~~~~~~~~~~~~~~~~~~ The command-line tool will attempt to re-authenticate using your provided credentials for every request. You can override this behavior by manually supplying an auth token using ``--os-url`` and ``--os-auth-token``. You can alternatively set these environment variables. .. code-block:: shell export OS_URL=http://monasca.example.org:8070/ export OS_TOKEN=3bcc3d3a03f44e3d8377f9247b0ad155 python-monascaclient-1.10.0/doc/source/cli/index.rst0000666000175100017510000000031513231417032022426 0ustar zuulzuul00000000000000========= Using CLI ========= monasca CLI ----------- .. toctree:: :maxdepth: 2 monasca CLI guide monasca CLI formatting monasca CLI debugging python-monascaclient-1.10.0/doc/source/cli/monasca-formatting.rst0000666000175100017510000000236513231417032025117 0ustar zuulzuul00000000000000=================== Changing formatting =================== Changing displayed columns -------------------------- If you want displayed columns in a list operation, ``-c`` option can be used. ``-c`` can be specified multiple times and the column order will be same as the order of ``-c`` options. Changing format --------------- If you want to change the format data is displayed in, you can use ``-f`` option for that. Format can be specified just once and it affects they way the data is printed to the ``STDOUT``. The available formats, data can be presented in, can be checked with: .. code-block:: text monasca --help Look for section **output formatters** and the flag ``--format`` or ``-f``. In most of the cases you will be able to pick one out of ``csv``, ``json``, ``table``, ``value``, ``yaml``. Affecting the width ------------------- If, for some reason, you are not happy with the width the output has taken, you can use ```--max-width {number}``` flag and set the value to match your preference. Without that output will not be constrained by the terminal width. Alternatively you may want to pass ``--fit-width`` to fit the output to display width. Remember that these flags affect the output only if ``table`` formatter is used. python-monascaclient-1.10.0/doc/source/cli/monasca-debug.rst0000666000175100017510000000075413231417032024033 0ustar zuulzuul00000000000000========= Debugging ========= ``-v`` (or ``--verbose``), as well as ``--debug``, option can be used to increase amount of low-level details regarding all the steps that client takes in order to execute the CLI command. While ``--verbose`` does not dramatically increase the output by displaying only basic information about the the execution, ``--debug`` can be used to additionally display low-level interactions **monascaclient** make with **keystone** server and/or **monasca** server. python-monascaclient-1.10.0/setup.py0000666000175100017510000000200613231417032017462 0ustar zuulzuul00000000000000# 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) python-monascaclient-1.10.0/python_monascaclient.egg-info/0000775000175100017510000000000013231417275023674 5ustar zuulzuul00000000000000python-monascaclient-1.10.0/python_monascaclient.egg-info/dependency_links.txt0000664000175100017510000000000113231417273027740 0ustar zuulzuul00000000000000 python-monascaclient-1.10.0/python_monascaclient.egg-info/pbr.json0000664000175100017510000000005613231417274025352 0ustar zuulzuul00000000000000{"git_version": "5ea9035", "is_release": true}python-monascaclient-1.10.0/python_monascaclient.egg-info/PKG-INFO0000664000175100017510000012603613231417273024777 0ustar zuulzuul00000000000000Metadata-Version: 1.1 Name: python-monascaclient Version: 1.10.0 Summary: Monasca API Client Library Home-page: https://docs.openstack.org/python-monascaclient/latest/ Author: OpenStack Author-email: openstack-dev@lists.openstack.org License: UNKNOWN Description-Content-Type: UNKNOWN Description: ======================== 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 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. Usage ===== You'll find complete documentation on the shell by running ``monasca help``:: usage: monasca [--version] [-v | -q] [--log-file LOG_FILE] [-h] [--debug] [--os-cloud ] [--os-region-name ] [--os-cacert ] [--os-cert ] [--os-key ] [--verify | --insecure] [--os-default-domain ] [--os-interface ] [--timing] [--os-beta-command] [--os-auth-type ] [--os-code ] [--os-protocol ] [--os-project-name ] [--os-trust-id ] [--os-domain-name ] [--os-user-domain-id ] [--os-access-token-type ] [--os-default-domain-name ] [--os-access-token-endpoint ] [--os-access-token ] [--os-domain-id ] [--os-user-domain-name ] [--os-openid-scope ] [--os-user-id ] [--os-identity-provider ] [--os-username ] [--os-auth-url ] [--os-client-secret ] [--os-default-domain-id ] [--os-discovery-endpoint ] [--os-client-id ] [--os-project-domain-name ] [--os-project-domain-id ] [--os-password ] [--os-redirect-uri ] [--os-endpoint ] [--os-token ] [--os-passcode ] [--os-project-id ] [--monasca-api-url MONASCA_API_URL] [--monasca-api-version MONASCA_API_VERSION] Command-line interface to the OpenStack APIs optional arguments: --version show program's version number and exit -v, --verbose Increase verbosity of output. Can be repeated. -q, --quiet Suppress output except warnings and errors. --log-file LOG_FILE Specify a file to log output. Disabled by default. -h, --help Show help message and exit. --debug Show tracebacks on errors. --os-cloud Cloud name in clouds.yaml (Env: OS_CLOUD) --os-region-name Authentication region name (Env: OS_REGION_NAME) --os-cacert CA certificate bundle file (Env: OS_CACERT) --os-cert Client certificate bundle file (Env: OS_CERT) --os-key Client certificate key file (Env: OS_KEY) --verify Verify server certificate (default) --insecure Disable server certificate verification --os-default-domain Default domain ID, default=default. (Env: OS_DEFAULT_DOMAIN) --os-interface Select an interface type. Valid interface types: [admin, public, internal]. (Env: OS_INTERFACE) --timing Print API call timing info --os-beta-command Enable beta commands which are subject to change --os-auth-type Select an authentication type. Available types: v2token, admin_token, v3oidcauthcode, v2password, v3password, v3oidcaccesstoken, v3oidcpassword, token, v3oidcclientcredentials, v3tokenlessauth, v3token, v3totp, password. Default: selected based on --os- username/--os-token (Env: OS_AUTH_TYPE) --os-code With v3oidcauthcode: OAuth 2.0 Authorization Code (Env: OS_CODE) --os-protocol With v3oidcauthcode: Protocol for federated plugin With v3oidcaccesstoken: Protocol for federated plugin With v3oidcpassword: Protocol for federated plugin With v3oidcclientcredentials: Protocol for federated plugin (Env: OS_PROTOCOL) --os-project-name With v3oidcauthcode: Project name to scope to With v3password: Project name to scope to With v3oidcaccesstoken: Project name to scope to With v3oidcpassword: Project name to scope to With token: Project name to scope to With v3oidcclientcredentials: Project name to scope to With v3tokenlessauth: Project name to scope to With v3token: Project name to scope to With v3totp: Project name to scope to With password: Project name to scope to (Env: OS_PROJECT_NAME) --os-trust-id With v2token: Trust ID With v3oidcauthcode: Trust ID With v2password: Trust ID With v3password: Trust ID With v3oidcaccesstoken: Trust ID With v3oidcpassword: Trust ID With token: Trust ID With v3oidcclientcredentials: Trust ID With v3token: Trust ID With v3totp: Trust ID With password: Trust ID (Env: OS_TRUST_ID) --os-domain-name With v3oidcauthcode: Domain name to scope to With v3password: Domain name to scope to With v3oidcaccesstoken: Domain name to scope to With v3oidcpassword: Domain name to scope to With token: Domain name to scope to With v3oidcclientcredentials: Domain name to scope to With v3tokenlessauth: Domain name to scope to With v3token: Domain name to scope to With v3totp: Domain name to scope to With password: Domain name to scope to (Env: OS_DOMAIN_NAME) --os-user-domain-id With v3password: User's domain id With v3totp: User's domain id With password: User's domain id (Env: OS_USER_DOMAIN_ID) --os-access-token-type With v3oidcauthcode: OAuth 2.0 Authorization Server Introspection token type, it is used to decide which type of token will be used when processing token introspection. Valid values are: "access_token" or "id_token" With v3oidcpassword: OAuth 2.0 Authorization Server Introspection token type, it is used to decide which type of token will be used when processing token introspection. Valid values are: "access_token" or "id_token" With v3oidcclientcredentials: OAuth 2.0 Authorization Server Introspection token type, it is used to decide which type of token will be used when processing token introspection. Valid values are: "access_token" or "id_token" (Env: OS_ACCESS_TOKEN_TYPE) --os-default-domain-name With token: Optional domain name to use with v3 API and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. With password: Optional domain name to use with v3 API and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. (Env: OS_DEFAULT_DOMAIN_NAME) --os-access-token-endpoint With v3oidcauthcode: OpenID Connect Provider Token Endpoint. Note that if a discovery document is being passed this option will override the endpoint provided by the server in the discovery document. With v3oidcpassword: OpenID Connect Provider Token Endpoint. Note that if a discovery document is being passed this option will override the endpoint provided by the server in the discovery document. With v3oidcclientcredentials: OpenID Connect Provider Token Endpoint. Note that if a discovery document is being passed this option will override the endpoint provided by the server in the discovery document. (Env: OS_ACCESS_TOKEN_ENDPOINT) --os-access-token With v3oidcaccesstoken: OAuth 2.0 Access Token (Env: OS_ACCESS_TOKEN) --os-domain-id With v3oidcauthcode: Domain ID to scope to With v3password: Domain ID to scope to With v3oidcaccesstoken: Domain ID to scope to With v3oidcpassword: Domain ID to scope to With token: Domain ID to scope to With v3oidcclientcredentials: Domain ID to scope to With v3tokenlessauth: Domain ID to scope to With v3token: Domain ID to scope to With v3totp: Domain ID to scope to With password: Domain ID to scope to (Env: OS_DOMAIN_ID) --os-user-domain-name With v3password: User's domain name With v3totp: User's domain name With password: User's domain name (Env: OS_USER_DOMAIN_NAME) --os-openid-scope With v3oidcauthcode: OpenID Connect scope that is requested from authorization server. Note that the OpenID Connect specification states that "openid" must be always specified. With v3oidcpassword: OpenID Connect scope that is requested from authorization server. Note that the OpenID Connect specification states that "openid" must be always specified. With v3oidcclientcredentials: OpenID Connect scope that is requested from authorization server. Note that the OpenID Connect specification states that "openid" must be always specified. (Env: OS_OPENID_SCOPE) --os-user-id With v2password: User ID to login with With v3password: User ID With v3totp: User ID With password: User id (Env: OS_USER_ID) --os-identity-provider With v3oidcauthcode: Identity Provider's name With v3oidcaccesstoken: Identity Provider's name With v3oidcpassword: Identity Provider's name With v3oidcclientcredentials: Identity Provider's name (Env: OS_IDENTITY_PROVIDER) --os-username With v2password: Username to login with With v3password: Username With v3oidcpassword: Username With v3totp: Username With password: Username (Env: OS_USERNAME) --os-auth-url With v2token: Authentication URL With v3oidcauthcode: Authentication URL With v2password: Authentication URL With v3password: Authentication URL With v3oidcaccesstoken: Authentication URL With v3oidcpassword: Authentication URL With token: Authentication URL With v3oidcclientcredentials: Authentication URL With v3tokenlessauth: Authentication URL With v3token: Authentication URL With v3totp: Authentication URL With password: Authentication URL (Env: OS_AUTH_URL) --os-client-secret With v3oidcauthcode: OAuth 2.0 Client Secret With v3oidcpassword: OAuth 2.0 Client Secret With v3oidcclientcredentials: OAuth 2.0 Client Secret (Env: OS_CLIENT_SECRET) --os-default-domain-id With token: Optional domain ID to use with v3 and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. With password: Optional domain ID to use with v3 and v2 parameters. It will be used for both the user and project domain in v3 and ignored in v2 authentication. (Env: OS_DEFAULT_DOMAIN_ID) --os-discovery-endpoint With v3oidcauthcode: OpenID Connect Discovery Document URL. The discovery document will be used to obtain the values of the access token endpoint and the authentication endpoint. This URL should look like https://idp.example.org/.well-known/openid- configuration With v3oidcpassword: OpenID Connect Discovery Document URL. The discovery document will be used to obtain the values of the access token endpoint and the authentication endpoint. This URL should look like https://idp.example.org/.well-known/openid- configuration With v3oidcclientcredentials: OpenID Connect Discovery Document URL. The discovery document will be used to obtain the values of the access token endpoint and the authentication endpoint. This URL should look like https://idp.example.org/.well-known /openid-configuration (Env: OS_DISCOVERY_ENDPOINT) --os-client-id With v3oidcauthcode: OAuth 2.0 Client ID With v3oidcpassword: OAuth 2.0 Client ID With v3oidcclientcredentials: OAuth 2.0 Client ID (Env: OS_CLIENT_ID) --os-project-domain-name With v3oidcauthcode: Domain name containing project With v3password: Domain name containing project With v3oidcaccesstoken: Domain name containing project With v3oidcpassword: Domain name containing project With token: Domain name containing project With v3oidcclientcredentials: Domain name containing project With v3tokenlessauth: Domain name containing project With v3token: Domain name containing project With v3totp: Domain name containing project With password: Domain name containing project (Env: OS_PROJECT_DOMAIN_NAME) --os-project-domain-id With v3oidcauthcode: Domain ID containing project With v3password: Domain ID containing project With v3oidcaccesstoken: Domain ID containing project With v3oidcpassword: Domain ID containing project With token: Domain ID containing project With v3oidcclientcredentials: Domain ID containing project With v3tokenlessauth: Domain ID containing project With v3token: Domain ID containing project With v3totp: Domain ID containing project With password: Domain ID containing project (Env: OS_PROJECT_DOMAIN_ID) --os-password With v2password: Password to use With v3password: User's password With v3oidcpassword: Password With password: User's password (Env: OS_PASSWORD) --os-redirect-uri With v3oidcauthcode: OpenID Connect Redirect URL (Env: OS_REDIRECT_URI) --os-endpoint With admin_token: The endpoint that will always be used (Env: OS_ENDPOINT) --os-token With v2token: Token With admin_token: The token that will always be used With token: Token to authenticate with With v3token: Token to authenticate with (Env: OS_TOKEN) --os-passcode With v3totp: User's TOTP passcode (Env: OS_PASSCODE) --os-project-id With v3oidcauthcode: Project ID to scope to With v3password: Project ID to scope to With v3oidcaccesstoken: Project ID to scope to With v3oidcpassword: Project ID to scope to With token: Project ID to scope to With v3oidcclientcredentials: Project ID to scope to With v3tokenlessauth: Project ID to scope to With v3token: Project ID to scope to With v3totp: Project ID to scope to With password: Project ID to scope to (Env: OS_PROJECT_ID) --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 Commands: alarm-count Count alarms. 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 transition history. alarm-history-list List alarms state history. alarm-list List alarms for this tenant. alarm-patch Patch the alarm state. alarm-show Describe the alarm. alarm-update Update the alarm state. complete print bash completion command dimension-name-list List names of metric dimensions. dimension-value-list List names of metric dimensions. help print detailed help for another command 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-type-list List notification types supported by monasca. notification-update Update notification. Bash Completion --------------- Basic command tab completion can be enabled by sourcing the bash completion script. :: monasca completion >> /usr/local/share/monasca.bash_completion Metrics Examples ---------------- Note: To see complete usage: 'monasca help' and 'monasca help ' 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 ' 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 ' 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. There are three possible approaches, at the moment, you can take to use the client directly. On high level, these approaches can be described as: * using **username** and **password** * using **token** * using existing _` Username & password ------------------- Following approach allows to initialize the monascaclient in a traditional way. It requires **username** and **password**. Initialization of the client can be threfore executed with:: c = mon_client.Client(api_version='2_0', username=os.environ.get('OS_USERNAME', 'mini-mon'), password=os.environ.get('OS_PASSWORD', 'password'), auth_url=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1/identity'), project_name=os.environ.get('OS_PROJECT_NAME', 'mini-mon'), endpoint='http://127.0.0.1:8070/v2.0') Token ----- In order to use the monasclient 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/. Once **token** is available, a monascaclient can be initialized with following code:: c = mon_client.Client(api_version='2_0', endpoint='http://127.0.0.1:8070/v2.0' token=token_id, auth_url=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1/identity'), project_name=os.environ.get('OS_PROJECT_NAME', 'mini-mon')) Session ------- Usage of the monasclient with existing session can be expressed with following code:: from keystoneauth1 import session from keystoneauth1 import identity auth = identity.Token(auth_url=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1/identity'), token=token_id, project_name=os.environ.get('OS_PROJECT_NAME', 'mini-mon')) sess = session.Session(auth=auth) c = client.Client(api_version='2_0', endpoint='http://127.0.0.1:8070/v2.0' session=sess) The session object construction is much broader topic. It involves picking one of the following authorization methods: * Password * Token Alternatively, if Keystone version is known, you may choose: * V2Password or V3Password * V2Token of V3Token * V3OidcClientCredentials * V3OidcPassword * V3OidcAuthorizationCode * V3OidcAccessToken * V3TOTP * V3TokenlessAuth For more details about each one of those methods, please visit `official documentation `_. License ======= (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. Platform: UNKNOWN Classifier: Environment :: Console Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.5 python-monascaclient-1.10.0/python_monascaclient.egg-info/entry_points.txt0000664000175100017510000000006613231417273027172 0ustar zuulzuul00000000000000[console_scripts] monasca = monascaclient.shell:main python-monascaclient-1.10.0/python_monascaclient.egg-info/not-zip-safe0000664000175100017510000000000113231417242026114 0ustar zuulzuul00000000000000 python-monascaclient-1.10.0/python_monascaclient.egg-info/requires.txt0000664000175100017510000000025713231417273026276 0ustar zuulzuul00000000000000osc-lib>=1.8.0 oslo.serialization!=2.19.1,>=2.18.0 oslo.utils>=3.33.0 Babel!=2.4.0,>=2.3.4 iso8601>=0.1.11 pbr!=2.1.0,>=2.0.0 PrettyTable<0.8,>=0.7.1 PyYAML>=3.10 six>=1.10.0 python-monascaclient-1.10.0/python_monascaclient.egg-info/SOURCES.txt0000664000175100017510000000342313231417275025562 0ustar zuulzuul00000000000000.testr.conf AUTHORS CONTRIBUTING.rst ChangeLog HACKING.rst LICENSE README.rst requirements.txt setup.cfg setup.py test-requirements.txt tox.ini doc/source/conf.py doc/source/index.rst doc/source/cli/index.rst doc/source/cli/monasca-debug.rst doc/source/cli/monasca-formatting.rst doc/source/cli/monasca.rst doc/source/reference/index.rst doc/source/usage/index.rst monascaclient/__init__.py monascaclient/client.py monascaclient/shell.py monascaclient/version.py monascaclient/common/__init__.py monascaclient/common/monasca_manager.py monascaclient/common/utils.py monascaclient/osc/__init__.py monascaclient/osc/migration.py monascaclient/tests/__init__.py monascaclient/tests/test_client.py monascaclient/tests/test_shell.py monascaclient/tests/v2_0/__init__.py monascaclient/tests/v2_0/shell/__init__.py monascaclient/tests/v2_0/shell/test_alarm_definitions.py monascaclient/tests/v2_0/shell/test_metrics.py monascaclient/tests/v2_0/shell/test_notification_types.py monascaclient/tests/v2_0/shell/test_notifications.py monascaclient/v2_0/__init__.py monascaclient/v2_0/alarm_definitions.py monascaclient/v2_0/alarms.py monascaclient/v2_0/client.py monascaclient/v2_0/metrics.py monascaclient/v2_0/notifications.py monascaclient/v2_0/notificationtypes.py monascaclient/v2_0/shell.py python_monascaclient.egg-info/PKG-INFO python_monascaclient.egg-info/SOURCES.txt python_monascaclient.egg-info/dependency_links.txt python_monascaclient.egg-info/entry_points.txt python_monascaclient.egg-info/not-zip-safe python_monascaclient.egg-info/pbr.json python_monascaclient.egg-info/requires.txt python_monascaclient.egg-info/top_level.txt releasenotes/locale/.gitkeep releasenotes/notes/openstack_docs-5cfec48411370070.yaml releasenotes/source/conf.py releasenotes/source/index.rst releasenotes/source/unreleased.rstpython-monascaclient-1.10.0/python_monascaclient.egg-info/top_level.txt0000664000175100017510000000001613231417273026421 0ustar zuulzuul00000000000000monascaclient python-monascaclient-1.10.0/HACKING.rst0000666000175100017510000000025013231417032017545 0ustar zuulzuul00000000000000python-monascaclient Style Commandments =============================================== Read the OpenStack Style Commandments http://docs.openstack.org/hacking/latest python-monascaclient-1.10.0/LICENSE0000666000175100017510000002363613231417032016771 0ustar zuulzuul00000000000000 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.