Switch to python-freezerclient

Implements: blueprint switch-to-python-freezer-client
Closes-Bug: #1642921
Depends-On: Ie108d99d56ca76614cdf6927f614a44106a0a922
Change-Id: I2627a5326c8ad4acc96177605f0250925748fb67
Signed-off-by: Ruslan Aliev <raliev@mirantis.com>
This commit is contained in:
Memo García 2016-09-04 18:04:43 +01:00 committed by Ruslan Aliev
parent db19b04d7f
commit d98de1ac2b
22 changed files with 111 additions and 1987 deletions

View File

@ -1,80 +0,0 @@
"""
Copyright 2015 Hewlett-Packard
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 json
import requests
from freezer.apiclient import exceptions
class ActionManager(object):
def __init__(self, client, verify=True):
self.client = client
self.endpoint = self.client.endpoint + '/v1/actions/'
self.verify = verify
@property
def headers(self):
return {'X-Auth-Token': self.client.auth_token}
def create(self, doc, action_id=''):
action_id = action_id or doc.get('action_id', '')
endpoint = self.endpoint + action_id
r = requests.post(endpoint,
data=json.dumps(doc),
headers=self.headers,
verify=self.verify)
if r.status_code != 201:
raise exceptions.ApiClientException(r)
action_id = r.json()['action_id']
return action_id
def delete(self, action_id):
endpoint = self.endpoint + action_id
r = requests.delete(endpoint,
headers=self.headers,
verify=self.verify)
if r.status_code != 204:
raise exceptions.ApiClientException(r)
def list(self, limit=10, offset=0, search=None):
data = json.dumps(search) if search else None
query = {'limit': int(limit), 'offset': int(offset)}
r = requests.get(self.endpoint, headers=self.headers,
params=query, data=data, verify=self.verify)
if r.status_code != 200:
raise exceptions.ApiClientException(r)
return r.json()['actions']
def get(self, action_id):
endpoint = self.endpoint + action_id
r = requests.get(endpoint, headers=self.headers, verify=self.verify)
if r.status_code == 200:
return r.json()
if r.status_code == 404:
return None
raise exceptions.ApiClientException(r)
def update(self, action_id, update_doc):
endpoint = self.endpoint + action_id
r = requests.patch(endpoint,
headers=self.headers,
data=json.dumps(update_doc), verify=self.verify)
if r.status_code != 200:
raise exceptions.ApiClientException(r)
return r.json()['version']

View File

@ -1,89 +0,0 @@
"""
(c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import json
import requests
from freezer.apiclient import exceptions
class BackupsManager(object):
def __init__(self, client, verify=True):
self.client = client
self.endpoint = self.client.endpoint + '/v1/backups/'
self.verify = verify
@property
def headers(self):
return {'X-Auth-Token': self.client.auth_token}
def create(self, backup_metadata):
if not backup_metadata.get('client_id', ''):
backup_metadata['client_id'] = self.client.client_id
r = requests.post(self.endpoint,
data=json.dumps(backup_metadata),
headers=self.headers,
verify=self.verify)
if r.status_code != 201:
raise exceptions.ApiClientException(r)
backup_id = r.json()['backup_id']
return backup_id
def delete(self, backup_id):
endpoint = self.endpoint + backup_id
r = requests.delete(endpoint, headers=self.headers,
verify=self.verify)
if r.status_code != 204:
raise exceptions.ApiClientException(r)
def list_all(self, limit=10, offset=0, search=None):
"""
Retrieves a list of backups
:param limit: number of result to return (optional, default 10)
:param offset: order of first document (optional, default 0)
:param search: structured query (optional)
can contain:
* "time_before": timestamp
* "time_after": timestamp
Example:
{ "time_before": 1428529956 }
"""
data = json.dumps(search) if search else None
query = {'limit': int(limit), 'offset': int(offset)}
r = requests.get(self.endpoint, headers=self.headers,
params=query, data=data, verify=self.verify)
if r.status_code != 200:
raise exceptions.ApiClientException(r)
return r.json()['backups']
def list(self, limit=10, offset=0, search={}, client_id=None):
client_id = client_id or self.client.client_id
new_search = search.copy()
new_search['match'] = search.get('match', [])
new_search['match'].append({'client_id': client_id})
return self.list_all(limit, offset, new_search)
def get(self, backup_id):
endpoint = self.endpoint + backup_id
r = requests.get(endpoint, headers=self.headers, verify=self.verify)
if r.status_code == 200:
return r.json()
if r.status_code == 404:
return None
raise exceptions.ApiClientException(r)

View File

@ -1,275 +0,0 @@
"""
Copyright 2015 Hewlett-Packard
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.
client interface to the Freezer API
"""
import os
import socket
from keystoneauth1.identity import v2
from keystoneauth1.identity import v3
from keystoneauth1 import session as ksa_session
from oslo_config import cfg
from freezer.apiclient import actions
from freezer.apiclient import backups
from freezer.apiclient import jobs
from freezer.apiclient import registration
from freezer.apiclient import sessions
from freezer.utils import utils
FREEZER_SERVICE_TYPE = 'backup'
def env(*vars, **kwargs):
for v in vars:
value = os.environ.get(v, None)
if value:
return value
return kwargs.get('default', '')
class cached_property(object):
def __init__(self, func):
self.__doc__ = getattr(func, '__doc__')
self.func = func
def __get__(self, obj, cls):
if obj is None:
return self
value = obj.__dict__[self.func.__name__] = self.func(obj)
return value
def build_os_options():
osclient_opts = [
cfg.StrOpt('os-username',
default=env('OS_USERNAME'),
help='Name used for authentication with the OpenStack '
'Identity service. Defaults to env[OS_USERNAME].',
dest='os_username'),
cfg.StrOpt('os-password',
default=env('OS_PASSWORD'),
help='Password used for authentication with the OpenStack '
'Identity service. Defaults to env[OS_PASSWORD].',
dest='os_password'),
cfg.StrOpt('os-project-name',
default=env('OS_PROJECT_NAME'),
help='Project name to scope to. Defaults to '
'env[OS_PROJECT_NAME].',
dest='os_project_name'),
cfg.StrOpt('os-project-domain-name',
default=env('OS_PROJECT_DOMAIN_NAME'),
help='Domain name containing project. Defaults to '
'env[OS_PROJECT_DOMAIN_NAME].',
dest='os_project_domain_name'),
cfg.StrOpt('os-user-domain-name',
default=env('OS_USER_DOMAIN_NAME'),
help='User\'s domain name. Defaults to '
'env[OS_USER_DOMAIN_NAME].',
dest='os_user_domain_name'),
cfg.StrOpt('os-tenant-name',
default=env('OS_TENANT_NAME'),
help='Tenant to request authorization on. Defaults to '
'env[OS_TENANT_NAME].',
dest='os_tenant_name'),
cfg.StrOpt('os-tenant-id',
default=env('OS_TENANT_ID'),
help='Tenant to request authorization on. Defaults to '
'env[OS_TENANT_ID].',
dest='os_tenant_id'),
cfg.StrOpt('os-auth-url',
default=env('OS_AUTH_URL'),
help='Specify the Identity endpoint to use for '
'authentication. Defaults to env[OS_AUTH_URL].',
dest='os_auth_url'),
cfg.StrOpt('os-backup-url',
default=env('OS_BACKUP_URL'),
help='Specify the Freezer backup service endpoint to use. '
'Defaults to env[OS_BACKUP_URL].',
dest='os_backup_url'),
cfg.StrOpt('os-region-name',
default=env('OS_REGION_NAME'),
help='Specify the region to use. Defaults to '
'env[OS_REGION_NAME].',
dest='os_region_name'),
cfg.StrOpt('os-token',
default=env('OS_TOKEN'),
help='Specify an existing token to use instead of '
'retrieving one via authentication '
'(e.g. with username & password). Defaults '
'to env[OS_TOKEN].',
dest='os_token'),
cfg.StrOpt('os-identity-api-version',
default=env('OS_IDENTITY_API_VERSION'),
help='Identity API version: 2.0 or 3. '
'Defaults to env[OS_IDENTITY_API_VERSION]',
dest='os_identity_api_version'),
cfg.StrOpt('os-endpoint-type',
choices=['public', 'publicURL', 'internal', 'internalURL',
'admin', 'adminURL'],
default=env('OS_ENDPOINT_TYPE') or 'public',
help='Endpoint type to select. Valid endpoint types: '
'"public" or "publicURL", "internal" or "internalURL",'
' "admin" or "adminURL". Defaults to '
'env[OS_ENDPOINT_TYPE] or "public"',
dest='os_endpoint_type'),
cfg.StrOpt('os-cert',
default=env('OS_CERT'),
help='Specify a cert file to use in verifying a TLS '
'(https) server certificate',
dest='os_cert'),
cfg.StrOpt('os-cacert',
default=env('OS_CACERT'),
help='Specify a CA bundle file to use in verifying a TLS '
'(https) server certificate. Defaults to',
dest='os_cacert'),
]
return osclient_opts
def guess_auth_version(opts):
if opts.os_identity_api_version == '3':
return '3'
elif opts.os_identity_api_version == '2.0':
return '2.0'
elif opts.os_auth_url.endswith('v3'):
return '3'
elif opts.os_auth_url.endswith('v2.0'):
return '2.0'
raise Exception('Please provide valid keystone auth url with valid'
' keystone api version to use')
def get_auth_plugin(opts):
auth_version = guess_auth_version(opts)
if opts.os_username:
if auth_version == '3':
return v3.Password(auth_url=opts.os_auth_url,
username=opts.os_username,
password=opts.os_password,
project_name=opts.os_project_name,
user_domain_name=opts.os_user_domain_name,
project_domain_name=opts.os_project_domain_name)
elif auth_version == '2.0':
return v2.Password(auth_url=opts.os_auth_url,
username=opts.os_username,
password=opts.os_password,
tenant_name=opts.os_tenant_name)
elif opts.os_token:
if auth_version == '3':
return v3.Token(auth_url=opts.os_auth_url,
token=opts.os_token,
project_name=opts.os_project_name,
project_domain_name=opts.os_project_domain_name)
elif auth_version == '2.0':
return v2.Token(auth_url=opts.os_auth_url,
token=opts.os_token,
tenant_name=opts.os_tenant_name)
raise Exception('Unable to determine correct auth method, please provide'
' either username or token')
class Client(object):
def __init__(self,
version='1',
token=None,
username=None,
password=None,
tenant_name=None,
auth_url=None,
session=None,
endpoint=None,
opts=None,
project_name=None,
user_domain_name=None,
project_domain_name=None,
cert=False,
cacert=False,
insecure=False):
self.opts = opts
# this creates a namespace for self.opts when the client is
# created from other method rather than command line arguments.
if self.opts is None:
self.opts = utils.Namespace({})
if token:
self.opts.os_token = token
if username:
self.opts.os_username = username
if password:
self.opts.os_password = password
if tenant_name:
self.opts.os_tenant_name = tenant_name
if auth_url:
self.opts.os_auth_url = auth_url
if endpoint:
self.opts.os_backup_url = endpoint
if project_name:
self.opts.os_project_name = project_name
if user_domain_name:
self.opts.os_user_domain_name = user_domain_name
if project_domain_name:
self.opts.os_project_domain_name = project_domain_name
if insecure:
self.verify = False
elif cacert:
# verify arg in keystone sessions could be True/False/Path to cert
self.verify = cacert
else:
self.verify = True
if cert:
self.opts.os_cert = cert
self._session = session
self.version = version
self.backups = backups.BackupsManager(self, verify=self.verify)
self.registration = registration.RegistrationManager(
self, verify=self.verify)
self.jobs = jobs.JobManager(self, verify=self.verify)
self.actions = actions.ActionManager(self, verify=self.verify)
self.sessions = sessions.SessionManager(self, verify=self.verify)
@cached_property
def session(self):
if self._session:
return self._session
auth_plugin = get_auth_plugin(self.opts)
return ksa_session.Session(auth=auth_plugin, verify=self.verify)
@cached_property
def endpoint(self):
if self.opts.os_backup_url:
return self.opts.os_backup_url
else:
auth_ref = self.session.auth.get_auth_ref(self.session)
endpoint = auth_ref.service_catalog.url_for(
service_type=FREEZER_SERVICE_TYPE,
interface=self.opts.os_endpoint_type,
)
return endpoint
@property
def auth_token(self):
return self.session.get_token()
@cached_property
def client_id(self):
return '{0}_{1}'.format(self.session.get_project_id(),
socket.gethostname())

View File

@ -1,70 +0,0 @@
"""
(c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import json
class ApiClientException(Exception):
@staticmethod
def get_message_from_api_response(r):
"""
returns a message based on information from a api-formatted response
if available, otherwise None
api-formatted response should be:
{
title: "error title string",
description: "error description string"
}
:param r: response object
:return: string with error message or None if it fails
"""
try:
body = json.loads(r.text)
message = "Error {0}: {1}".format(
r.status_code,
body['description'])
except Exception:
message = None
return message
@staticmethod
def get_message_from_response(r):
"""
composes the error message using information eventually present
in the response (http error code and the http response body)
:param r: response object
:return: string with error message or None if it fails
"""
try:
message = "Error {0}: {1}".format(
r.status_code,
r.text)
except Exception:
message = None
return message
def __init__(self, r):
message = self.get_message_from_api_response(r) or \
self.get_message_from_response(r) or \
str(r)
try:
self.status_code = r.status_code
except Exception:
self.status_code = None
super(ApiClientException, self).__init__(message)

View File

@ -1,150 +0,0 @@
"""
Copyright 2015 Hewlett-Packard
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 json
import requests
from freezer.apiclient import exceptions
class JobManager(object):
def __init__(self, client, verify=True):
self.client = client
self.endpoint = self.client.endpoint + '/v1/jobs/'
self.verify = verify
@property
def headers(self):
return {'X-Auth-Token': self.client.auth_token}
def create(self, doc, job_id=''):
job_id = job_id or doc.get('job_id', '')
endpoint = self.endpoint + job_id
doc['client_id'] = doc.get('client_id', '') or self.client.client_id
r = requests.post(endpoint,
data=json.dumps(doc),
headers=self.headers,
verify=self.verify)
if r.status_code != 201:
raise exceptions.ApiClientException(r)
job_id = r.json()['job_id']
return job_id
def delete(self, job_id):
endpoint = self.endpoint + job_id
r = requests.delete(endpoint, headers=self.headers,
verify=self.verify)
if r.status_code != 204:
raise exceptions.ApiClientException(r)
def list_all(self, limit=10, offset=0, search=None):
data = json.dumps(search) if search else None
query = {'limit': int(limit), 'offset': int(offset)}
r = requests.get(self.endpoint, headers=self.headers,
params=query, data=data, verify=self.verify)
if r.status_code != 200:
raise exceptions.ApiClientException(r)
return r.json()['jobs']
def list(self, limit=10, offset=0, search={}, client_id=None):
client_id = client_id or self.client.client_id
new_search = search.copy()
new_search['match'] = search.get('match', [])
new_search['match'].append({'client_id': client_id})
return self.list_all(limit, offset, new_search)
def get(self, job_id):
endpoint = self.endpoint + job_id
r = requests.get(endpoint, headers=self.headers, verify=self.verify)
if r.status_code == 200:
return r.json()
if r.status_code == 404:
return None
raise exceptions.ApiClientException(r)
def update(self, job_id, update_doc):
endpoint = self.endpoint + job_id
r = requests.patch(endpoint,
headers=self.headers,
data=json.dumps(update_doc),
verify=self.verify)
if r.status_code != 200:
raise exceptions.ApiClientException(r)
return r.json()['version']
def start_job(self, job_id):
"""
Request to start a job
:param job_id: the id of the job to start
:return: the response obj:
{
result: string 'success' or 'already started'
}
"""
# endpoint /v1/jobs/{job_id}/event
endpoint = '{0}{1}/event'.format(self.endpoint, job_id)
doc = {"start": None}
r = requests.post(endpoint,
headers=self.headers,
data=json.dumps(doc),
verify=self.verify)
if r.status_code != 202:
raise exceptions.ApiClientException(r)
return r.json()
def stop_job(self, job_id):
"""
Request to stop a job
:param job_id: the id of the job to start
:return: the response obj:
{
result: string 'success' or 'already stopped'
}
"""
# endpoint /v1/jobs/{job_id}/event
endpoint = '{0}{1}/event'.format(self.endpoint, job_id)
doc = {"stop": None}
r = requests.post(endpoint,
headers=self.headers,
data=json.dumps(doc),
verify=self.verify)
if r.status_code != 202:
raise exceptions.ApiClientException(r)
return r.json()
def abort_job(self, job_id):
"""
Request to abort a job
:param job_id: the id of the job to start
:return: the response obj:
{
result: string 'success' or 'already stopped'
}
"""
# endpoint /v1/jobs/{job_id}/event
endpoint = '{0}{1}/event'.format(self.endpoint, job_id)
doc = {"abort": None}
r = requests.post(endpoint,
headers=self.headers,
data=json.dumps(doc),
verify=self.verify)
if r.status_code != 202:
raise exceptions.ApiClientException(r)
return r.json()

View File

@ -1,83 +0,0 @@
"""
(c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import json
import requests
from freezer.apiclient import exceptions
class RegistrationManager(object):
def __init__(self, client, verify=True):
self.client = client
self.endpoint = self.client.endpoint + '/v1/clients/'
self.verify = verify
@property
def headers(self):
return {'X-Auth-Token': self.client.auth_token}
def create(self, client_info):
r = requests.post(self.endpoint,
data=json.dumps(client_info),
headers=self.headers,
verify=self.verify)
if r.status_code != 201:
raise exceptions.ApiClientException(r)
client_id = r.json()['client_id']
return client_id
def delete(self, client_id):
endpoint = self.endpoint + client_id
r = requests.delete(endpoint, headers=self.headers,
verify=self.verify)
if r.status_code != 204:
raise exceptions.ApiClientException(r)
def list(self, limit=10, offset=0, search=None):
"""
Retrieves a list of client info structures
:param limit: number of result to return (optional, default 10)
:param offset: order of first document (optional, default 0)
:param search: structured query (optional)
can contain:
* "match": list of {field, value}
Example:
{ "match": [
{"description": "some search text here"},
{"client_id": "giano"},
...
],
}
"""
data = json.dumps(search) if search else None
query = {'limit': int(limit), 'offset': int(offset)}
r = requests.get(self.endpoint, headers=self.headers,
params=query, data=data, verify=self.verify)
if r.status_code != 200:
raise exceptions.ApiClientException(r)
return r.json()['clients']
def get(self, client_id):
endpoint = self.endpoint + client_id
r = requests.get(endpoint, headers=self.headers, verify=self.verify)
if r.status_code == 200:
return r.json()
if r.status_code == 404:
return None
raise exceptions.ApiClientException(r)

View File

@ -1,163 +0,0 @@
"""
Copyright 2015 Hewlett-Packard
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 json
import requests
from freezer.apiclient import exceptions
class SessionManager(object):
def __init__(self, client, verify=True):
self.client = client
self.endpoint = self.client.endpoint + '/v1/sessions/'
self.verify = verify
@property
def headers(self):
return {'X-Auth-Token': self.client.auth_token}
def create(self, doc, session_id=''):
session_id = session_id or doc.get('session_id', '')
endpoint = self.endpoint + session_id
r = requests.post(endpoint,
data=json.dumps(doc),
headers=self.headers,
verify=self.verify)
if r.status_code != 201:
raise exceptions.ApiClientException(r)
session_id = r.json()['session_id']
return session_id
def delete(self, session_id):
endpoint = self.endpoint + session_id
r = requests.delete(endpoint, headers=self.headers,
verify=self.verify)
if r.status_code != 204:
raise exceptions.ApiClientException(r)
def list_all(self, limit=10, offset=0, search=None):
data = json.dumps(search) if search else None
query = {'limit': int(limit), 'offset': int(offset)}
r = requests.get(self.endpoint, headers=self.headers,
params=query, data=data, verify=self.verify)
if r.status_code != 200:
raise exceptions.ApiClientException(r)
return r.json()['sessions']
def list(self, limit=10, offset=0, search={}):
new_search = search.copy()
new_search['match'] = search.get('match', [])
return self.list_all(limit, offset, new_search)
def get(self, session_id):
endpoint = self.endpoint + session_id
r = requests.get(endpoint, headers=self.headers, verify=self.verify)
if r.status_code == 200:
return r.json()
if r.status_code == 404:
return None
raise exceptions.ApiClientException(r)
def update(self, session_id, update_doc):
endpoint = self.endpoint + session_id
r = requests.patch(endpoint,
headers=self.headers,
data=json.dumps(update_doc),
verify=self.verify)
if r.status_code != 200:
raise exceptions.ApiClientException(r)
return r.json()['version']
def add_job(self, session_id, job_id):
# endpoint /v1/sessions/{sessions_id}/jobs/{job_id}
endpoint = '{0}{1}/jobs/{2}'.format(self.endpoint, session_id, job_id)
r = requests.put(endpoint,
headers=self.headers, verify=self.verify)
if r.status_code != 204:
raise exceptions.ApiClientException(r)
return
def remove_job(self, session_id, job_id):
# endpoint /v1/sessions/{sessions_id}/jobs/{job_id}
endpoint = '{0}{1}/jobs/{2}'.format(self.endpoint, session_id, job_id)
retry = 5
r = ''
while retry:
r = requests.delete(endpoint,
headers=self.headers, verify=self.verify)
if r.status_code == 204:
return
retry -= 1
raise exceptions.ApiClientException(r)
def start_session(self, session_id, job_id, session_tag):
"""
Informs the api that the client is starting the session
identified by the session_id and request the session_tag
to be incremented up to the requested value.
The returned session_id could be:
* current_tag + 1 if the session has started
* > current_tag + 1 if the action had already been started
by some other node and this node was out of sync
:param session_id:
:param job_id:
:param session_tag: the new session_id
:return: the response obj:
{ result: string 'running' or 'error',
'session_tag': the new session_tag )
"""
# endpoint /v1/sessions/{sessions_id}/action
endpoint = '{0}{1}/action'.format(self.endpoint, session_id)
doc = {"start": {
"job_id": job_id,
"current_tag": session_tag
}}
r = requests.post(endpoint,
headers=self.headers,
data=json.dumps(doc),
verify=self.verify)
if r.status_code != 202:
raise exceptions.ApiClientException(r)
return r.json()
def end_session(self, session_id, job_id, session_tag, result):
"""
Informs the freezer service that the job has ended.
Provides information about the job's result and the session tag
:param session_id:
:param job_id:
:param session_tag:
:param result:
:return:
"""
# endpoint /v1/sessions/{sessions_id}/action
endpoint = '{0}{1}/action'.format(self.endpoint, session_id)
doc = {"end": {
"job_id": job_id,
"current_tag": session_tag,
"result": result
}}
r = requests.post(endpoint,
headers=self.headers,
data=json.dumps(doc),
verify=self.verify)
if r.status_code != 202:
raise exceptions.ApiClientException(r)
return r.json()

View File

@ -19,7 +19,6 @@ import os
import sys
from freezer import __version__ as FREEZER_VERSION
from freezer.apiclient import client as api_client
from freezer.utils import winutils
from oslo_config import cfg
from oslo_log import log
@ -47,6 +46,14 @@ def add_filter():
addFilter(log_filter)
def env(*args, **kwargs):
for v in args:
value = os.environ.get(v, None)
if value:
return value
return kwargs.get('default', '')
def get_common_opts():
scheduler_conf_d = os.environ.get('FREEZER_SCHEDULER_CONF_D',
DEFAULT_FREEZER_SCHEDULER_CONF_D)
@ -126,10 +133,98 @@ def get_common_opts():
return _COMMON
def build_os_options():
osclient_opts = [
cfg.StrOpt('os-username',
default=env('OS_USERNAME'),
help='Name used for authentication with the OpenStack '
'Identity service. Defaults to env[OS_USERNAME].',
dest='os_username'),
cfg.StrOpt('os-password',
default=env('OS_PASSWORD'),
help='Password used for authentication with the OpenStack '
'Identity service. Defaults to env[OS_PASSWORD].',
dest='os_password'),
cfg.StrOpt('os-project-name',
default=env('OS_PROJECT_NAME'),
help='Project name to scope to. Defaults to '
'env[OS_PROJECT_NAME].',
dest='os_project_name'),
cfg.StrOpt('os-project-domain-name',
default=env('OS_PROJECT_DOMAIN_NAME'),
help='Domain name containing project. Defaults to '
'env[OS_PROJECT_DOMAIN_NAME].',
dest='os_project_domain_name'),
cfg.StrOpt('os-user-domain-name',
default=env('OS_USER_DOMAIN_NAME'),
help='User\'s domain name. Defaults to '
'env[OS_USER_DOMAIN_NAME].',
dest='os_user_domain_name'),
cfg.StrOpt('os-tenant-name',
default=env('OS_TENANT_NAME'),
help='Tenant to request authorization on. Defaults to '
'env[OS_TENANT_NAME].',
dest='os_tenant_name'),
cfg.StrOpt('os-tenant-id',
default=env('OS_TENANT_ID'),
help='Tenant to request authorization on. Defaults to '
'env[OS_TENANT_ID].',
dest='os_tenant_id'),
cfg.StrOpt('os-auth-url',
default=env('OS_AUTH_URL'),
help='Specify the Identity endpoint to use for '
'authentication. Defaults to env[OS_AUTH_URL].',
dest='os_auth_url'),
cfg.StrOpt('os-backup-url',
default=env('OS_BACKUP_URL'),
help='Specify the Freezer backup service endpoint to use. '
'Defaults to env[OS_BACKUP_URL].',
dest='os_backup_url'),
cfg.StrOpt('os-region-name',
default=env('OS_REGION_NAME'),
help='Specify the region to use. Defaults to '
'env[OS_REGION_NAME].',
dest='os_region_name'),
cfg.StrOpt('os-token',
default=env('OS_TOKEN'),
help='Specify an existing token to use instead of '
'retrieving one via authentication '
'(e.g. with username & password). Defaults '
'to env[OS_TOKEN].',
dest='os_token'),
cfg.StrOpt('os-identity-api-version',
default=env('OS_IDENTITY_API_VERSION'),
help='Identity API version: 2.0 or 3. '
'Defaults to env[OS_IDENTITY_API_VERSION]',
dest='os_identity_api_version'),
cfg.StrOpt('os-endpoint-type',
choices=['public', 'publicURL', 'internal', 'internalURL',
'admin', 'adminURL'],
default=env('OS_ENDPOINT_TYPE') or 'public',
help='Endpoint type to select. Valid endpoint types: '
'"public" or "publicURL", "internal" or "internalURL",'
' "admin" or "adminURL". Defaults to '
'env[OS_ENDPOINT_TYPE] or "public"',
dest='os_endpoint_type'),
cfg.StrOpt('os-cert',
default=env('OS_CERT'),
help='Specify a cert file to use in verifying a TLS '
'(https) server certificate',
dest='os_cert'),
cfg.StrOpt('os-cacert',
default=env('OS_CACERT'),
help='Specify a CA bundle file to use in verifying a TLS '
'(https) server certificate. Defaults to',
dest='os_cacert'),
]
return osclient_opts
def parse_args(choices):
default_conf = cfg.find_config_files('freezer', 'scheduler', '.conf')
CONF.register_cli_opts(api_client.build_os_options())
CONF.register_cli_opts(get_common_opts())
CONF.register_cli_opts(build_os_options())
log.register_options(CONF)
positional = [

View File

@ -22,11 +22,11 @@ import threading
import time
from apscheduler.schedulers import background
from freezerclient.v1 import client
from oslo_config import cfg
from oslo_log import log
import six
from freezer.apiclient import client
from freezer.scheduler import arguments
from freezer.scheduler import scheduler_job
from freezer.scheduler import shell
@ -229,13 +229,13 @@ def main():
" from python-freezerclient.\n")
apiclient = None
insecure = False
verify = True
if CONF.insecure:
insecure = True
verify = False
if CONF.no_api is False:
try:
apiclient = client.Client(opts=CONF, insecure=insecure)
apiclient = client.Client(opts=CONF, verify=verify)
if CONF.client_id:
apiclient.client_id = CONF.client_id
except Exception as e:

View File

@ -228,7 +228,7 @@ def do_job_list(client, args):
def do_client_list(client, args):
table = prettytable.PrettyTable(["client_id", "hostname", "description"])
l = client.registration.list()
l = client.clients.list()
offset = 0
while l:
offset += len(l)
@ -237,7 +237,7 @@ def do_client_list(client, args):
table.add_row([client_doc['client_id'],
client_doc.get('hostname', ''),
client_doc.get('description', '')])
l = client.registration.list(offset=offset)
l = client.clients.list(offset=offset)
print(table)

View File

@ -17,15 +17,14 @@ limitations under the License.
import json
import os
import psutil
import signal
import socket
import uuid
from freezerclient import exceptions
from oslo_log import log
import psutil
import freezer.apiclient.exceptions
LOG = log.getLogger(__name__)
@ -39,8 +38,8 @@ def do_register(client, args=None):
"hostname": socket.gethostname()
}
try:
client.registration.create(client_info)
except freezer.apiclient.exceptions.ApiClientException as e:
client.clients.create(client_info)
except exceptions.ApiClientException as e:
if e.status_code == 409:
print("Client already registered")
return 73 # os.EX_CANTCREAT

View File

@ -57,8 +57,8 @@ class PySvc(win32serviceutil.ServiceFramework):
win32event.SetEvent(self.hWaitStop)
def main(self):
import freezer.apiclient.client
from freezer.scheduler.freezer_scheduler import FreezerScheduler
from freezerclient.v1.client import Client
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
@ -95,7 +95,7 @@ class PySvc(win32serviceutil.ServiceFramework):
'insecure': self.insecure
}
client = freezer.apiclient.client.Client(**credentials)
client = Client(**credentials)
scheduler = FreezerScheduler(
apiclient=client, interval=int(os.environ['SERVICE_INTERVAL']),

View File

@ -1,128 +0,0 @@
"""
Copyright 2015 Hewlett-Packard
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 unittest
from mock import Mock, patch
from freezer.apiclient import exceptions
from freezer.apiclient import actions
class TestActionManager(unittest.TestCase):
def setUp(self):
self.mock_client = Mock()
self.mock_response = Mock()
self.mock_client.endpoint = 'http://testendpoint:9999'
self.mock_client.auth_token = 'testtoken'
self.mock_client.client_id = 'test_client_id_78900987'
self.action_manager = actions.ActionManager(self.mock_client)
@patch('freezer.apiclient.actions.requests')
def test_create(self, mock_requests):
self.assertEqual('http://testendpoint:9999/v1/actions/', self.action_manager.endpoint)
self.assertEqual({'X-Auth-Token': 'testtoken'}, self.action_manager.headers)
@patch('freezer.apiclient.actions.requests')
def test_create_ok(self, mock_requests):
self.mock_response.status_code = 201
self.mock_response.json.return_value = {'action_id': 'qwerqwer'}
mock_requests.post.return_value = self.mock_response
retval = self.action_manager.create({'action': 'metadata'})
self.assertEqual('qwerqwer', retval)
@patch('freezer.apiclient.actions.requests')
def test_create_fail_when_api_return_error_code(self, mock_requests):
self.mock_response.status_code = 500
mock_requests.post.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.action_manager.create, {'action': 'metadata'})
@patch('freezer.apiclient.actions.requests')
def test_delete_ok(self, mock_requests):
self.mock_response.status_code = 204
mock_requests.delete.return_value = self.mock_response
retval = self.action_manager.delete('test_action_id')
self.assertIsNone(retval)
@patch('freezer.apiclient.actions.requests')
def test_delete_fail(self, mock_requests):
self.mock_response.status_code = 500
mock_requests.delete.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.action_manager.delete, 'test_action_id')
@patch('freezer.apiclient.actions.requests')
def test_get_ok(self, mock_requests):
self.mock_response.status_code = 200
self.mock_response.json.return_value = {'action_id': 'qwerqwer'}
mock_requests.get.return_value = self.mock_response
retval = self.action_manager.get('test_action_id')
self.assertEqual({'action_id': 'qwerqwer'}, retval)
@patch('freezer.apiclient.actions.requests')
def test_get_fails_on_error_different_from_404(self, mock_requests):
self.mock_response.status_code = 500
mock_requests.get.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.action_manager.get, 'test_action_id')
@patch('freezer.apiclient.actions.requests')
def test_get_none(self, mock_requests):
self.mock_response.status_code = 404
mock_requests.get.return_value = self.mock_response
retval = self.action_manager.get('test_action_id')
self.assertIsNone(retval)
@patch('freezer.apiclient.actions.requests')
def test_list_ok(self, mock_requests):
self.mock_response.status_code = 200
action_list = [{'action_id_0': 'bomboloid'}, {'action_id_1': 'asdfasdf'}]
self.mock_response.json.return_value = {'actions': action_list}
mock_requests.get.return_value = self.mock_response
retval = self.action_manager.list()
self.assertEqual(action_list, retval)
@patch('freezer.apiclient.actions.requests')
def test_list_error(self, mock_requests):
self.mock_response.status_code = 404
action_list = [{'action_id_0': 'bomboloid'}, {'action_id_1': 'asdfasdf'}]
self.mock_response.json.return_value = {'clients': action_list}
mock_requests.get.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.action_manager.list)
@patch('freezer.apiclient.actions.requests')
def test_update_ok(self, mock_requests):
self.mock_response.status_code = 200
self.mock_response.json.return_value = {
"patch": {"status": "bamboozled"},
"version": 12,
"action_id": "d454beec-1f3c-4d11-aa1a-404116a40502"
}
mock_requests.patch.return_value = self.mock_response
retval = self.action_manager.update('d454beec-1f3c-4d11-aa1a-404116a40502', {'status': 'bamboozled'})
self.assertEqual(12, retval)
@patch('freezer.apiclient.actions.requests')
def test_update_raise_MetadataUpdateFailure_when_api_return_error_code(self, mock_requests):
self.mock_response.json.return_value = {
"patch": {"status": "bamboozled"},
"version": 12,
"action_id": "d454beec-1f3c-4d11-aa1a-404116a40502"
}
self.mock_response.status_code = 404
self.mock_response.text = '{"title": "Not Found","description":"No document found with ID d454beec-1f3c-4d11-aa1a-404116a40502x"}'
mock_requests.patch.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.action_manager.update,
'd454beec-1f3c-4d11-aa1a-404116a40502', {'status': 'bamboozled'})

View File

@ -1,169 +0,0 @@
"""
Copyright 2015 Hewlett-Packard
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 json
import unittest
from mock import Mock, patch
from freezer.apiclient import exceptions
from freezer.apiclient import backups
class CallArgs(object):
def __init__(self, mock_obj=Mock()):
self.args = mock_obj.call_args[0]
self.kwargs = mock_obj.call_args[1]
def _check_arg(self, arg, value, load_json):
if load_json:
arg = json.loads(arg)
if (arg != value):
raise Exception("Argument doesn't match: {0} != {1}".format(arg, value))
return
def check_arg(self, pos, value, load_json=False):
if isinstance(pos, int):
return self._check_arg(self.args[pos], value, load_json)
return self._check_arg(self.kwargs[pos], value, load_json)
class TestBackupManager(unittest.TestCase):
def setUp(self):
self.mock_client = Mock()
self.mock_client.client_id = "jumpingjack"
self.mock_client.endpoint = 'http://testendpoint:9999'
self.mock_client.auth_token = 'testtoken'
self.b = backups.BackupsManager(self.mock_client)
@patch('freezer.apiclient.backups.requests')
def test_create(self, mock_requests):
self.assertEqual('http://testendpoint:9999/v1/backups/', self.b.endpoint)
self.assertEqual({'X-Auth-Token': 'testtoken'}, self.b.headers)
@patch('freezer.apiclient.backups.requests')
def test_create_ok(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 201
mock_response.json.return_value = {'backup_id': 'qwerqwer'}
mock_requests.post.return_value = mock_response
retval = self.b.create(backup_metadata={'backup': 'metadata'})
ca = CallArgs(mock_requests.post)
ca.check_arg(0, 'http://testendpoint:9999/v1/backups/')
ca.check_arg('data', {"backup": "metadata", "client_id": "jumpingjack"}, load_json=True)
ca.check_arg('headers', {'X-Auth-Token': 'testtoken'})
ca.check_arg('verify', True)
self.assertEqual('qwerqwer', retval)
@patch('freezer.apiclient.backups.requests')
def test_create_ok_with_client_id(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 201
mock_response.json.return_value = {'backup_id': 'qwerqwer'}
mock_requests.post.return_value = mock_response
retval = self.b.create(backup_metadata={'backup': 'metadata', 'client_id': 'wahwah'})
ca = CallArgs(mock_requests.post)
ca.check_arg(0, 'http://testendpoint:9999/v1/backups/')
ca.check_arg('data', {"backup": "metadata", "client_id": "wahwah"}, load_json=True)
ca.check_arg('headers', {'X-Auth-Token': 'testtoken'})
ca.check_arg('verify', True)
self.assertEqual('qwerqwer', retval)
@patch('freezer.apiclient.backups.requests')
def test_create_fail_when_api_return_error_code(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 500
mock_requests.post.return_value = mock_response
self.assertRaises(exceptions.ApiClientException, self.b.create, {'backup': 'metadata'})
@patch('freezer.apiclient.backups.requests')
def test_delete_ok(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 204
mock_requests.delete.return_value = mock_response
retval = self.b.delete('test_backup_id')
self.assertIsNone(retval)
@patch('freezer.apiclient.backups.requests')
def test_delete_fail(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 500
mock_requests.delete.return_value = mock_response
self.assertRaises(exceptions.ApiClientException, self.b.delete, 'test_backup_id')
@patch('freezer.apiclient.backups.requests')
def test_get_ok(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 200
mock_response.json.return_value = {'backup_id': 'qwerqwer'}
mock_requests.get.return_value = mock_response
retval = self.b.get('test_backup_id')
self.assertEqual({'backup_id': 'qwerqwer'}, retval)
@patch('freezer.apiclient.backups.requests')
def test_get_none(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 404
mock_requests.get.return_value = mock_response
retval = self.b.get('test_backup_id')
self.assertIsNone(retval)
@patch('freezer.apiclient.backups.requests')
def test_get_error(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 403
mock_requests.get.return_value = mock_response
self.assertRaises(exceptions.ApiClientException,
self.b.get, 'test_backup_id')
@patch('freezer.apiclient.backups.requests')
def test_list_ok(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 200
backup_list = [{'backup_id_0': 'qwerqwer'}, {'backup_id_1': 'asdfasdf'}]
mock_response.json.return_value = {'backups': backup_list}
mock_requests.get.return_value = mock_response
retval = self.b.list()
self.assertEqual(backup_list, retval)
@patch('freezer.apiclient.backups.requests')
def test_list_parameters(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 200
backup_list = [{'backup_id_0': 'qwerqwer'}, {'backup_id_1': 'asdfasdf'}]
mock_response.json.return_value = {'backups': backup_list}
mock_requests.get.return_value = mock_response
retval = self.b.list(limit=5,
offset=5,
search={"time_before": 1428529956})
ca = CallArgs(mock_requests.get)
ca.check_arg(0, 'http://testendpoint:9999/v1/backups/')
ca.check_arg('data', {"time_before": 1428529956, "match": [{"client_id": "jumpingjack"}]}, load_json=True)
ca.check_arg('headers', {'X-Auth-Token': 'testtoken'})
ca.check_arg('verify', True)
self.assertEqual(backup_list, retval)
@patch('freezer.apiclient.backups.requests')
def test_list_error(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 404
backup_list = [{'backup_id_0': 'qwerqwer'}, {'backup_id_1': 'asdfasdf'}]
mock_response.json.return_value = {'backups': backup_list}
mock_requests.get.return_value = mock_response
self.assertRaises(exceptions.ApiClientException, self.b.list)

View File

@ -1,166 +0,0 @@
"""
Copyright 2015 Hewlett-Packard
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 unittest
from mock import Mock, patch
from freezer.apiclient import client
class TestSupportFunctions(unittest.TestCase):
@patch('freezer.apiclient.client.os')
def test_env_return_env_var(self, mock_os):
mock_os.environ = {'TEST_ENV_VAR': 'qwerty'}
var = client.env('TEST_ENV_VAR')
self.assertEqual('qwerty', var)
@patch('freezer.apiclient.client.os')
def test_env_return_default(self, mock_os):
mock_os.environ = {}
var = client.env('TEST_ENV_VAR')
self.assertEqual('', var)
def test_guess_auth_version_returns_none(self):
mock_opts = Mock()
mock_opts.os_identity_api_version = ''
mock_opts.os_auth_url = ''
self.assertRaises(Exception, client.guess_auth_version, mock_opts)
def test_guess_auth_version_explicit_3(self):
mock_opts = Mock()
mock_opts.os_identity_api_version = '3'
self.assertEqual('3', client.guess_auth_version(mock_opts))
def test_guess_auth_version_explicit_2(self):
mock_opts = Mock()
mock_opts.os_identity_api_version = '2.0'
self.assertEqual('2.0', client.guess_auth_version(mock_opts))
def test_guess_auth_version_implicit_3(self):
mock_opts = Mock()
mock_opts.os_auth_url = 'http://whatever/v3'
self.assertEqual('3', client.guess_auth_version(mock_opts))
def test_guess_auth_version_implicit_2(self):
mock_opts = Mock()
mock_opts.os_auth_url = 'http://whatever/v2.0'
self.assertEqual('2.0', client.guess_auth_version(mock_opts))
@patch('freezer.apiclient.client.v3')
@patch('freezer.apiclient.client.v2')
def test_get_auth_plugin_v3_Password(self, mock_v2, mock_v3):
mock_opts = Mock()
mock_opts.os_identity_api_version = '3'
mock_opts.os_user_name = 'myuser'
mock_opts.os_token = ''
client.get_auth_plugin(mock_opts)
self.assertTrue(mock_v3.Password.called)
@patch('freezer.apiclient.client.v3')
@patch('freezer.apiclient.client.v2')
def test_get_auth_plugin_v3_Token(self, mock_v2, mock_v3):
mock_opts = Mock()
mock_opts.os_identity_api_version = '3'
mock_opts.os_username = ''
mock_opts.os_token = 'mytoken'
client.get_auth_plugin(mock_opts)
self.assertTrue(mock_v3.Token.called)
@patch('freezer.apiclient.client.v3')
@patch('freezer.apiclient.client.v2')
def test_get_auth_plugin_v2_Password(self, mock_v2, mock_v3):
mock_opts = Mock()
mock_opts.os_identity_api_version = '2.0'
mock_opts.os_user_name = 'myuser'
mock_opts.os_token = ''
client.get_auth_plugin(mock_opts)
self.assertTrue(mock_v2.Password.called)
@patch('freezer.apiclient.client.v3')
@patch('freezer.apiclient.client.v2')
def test_get_auth_plugin_v2_Token(self, mock_v2, mock_v3):
mock_opts = Mock()
mock_opts.os_identity_api_version = '2.0'
mock_opts.os_username = ''
mock_opts.os_token = 'mytoken'
client.get_auth_plugin(mock_opts)
self.assertTrue(mock_v2.Token.called)
@patch('freezer.apiclient.client.v3')
@patch('freezer.apiclient.client.v2')
def test_get_auth_plugin_raises_when_no_username_token(self, mock_v2, mock_v3):
mock_opts = Mock()
mock_opts.os_identity_api_version = '2.0'
mock_opts.os_username = ''
mock_opts.os_token = ''
self.assertRaises(Exception, client.get_auth_plugin, mock_opts)
class TestClientMock(unittest.TestCase):
@patch('freezer.apiclient.client.ksa_session')
@patch('freezer.apiclient.client.get_auth_plugin')
def test_client_new(self, mock_get_auth_plugin, mock_ksa_session):
c = client.Client(opts=Mock(), endpoint='blabla')
self.assertIsInstance(c, client.Client)
@patch('freezer.apiclient.client.ksa_session')
@patch('freezer.apiclient.client.get_auth_plugin')
def test_client_new_with_kwargs(self, mock_get_auth_plugin, mock_ksa_session):
kwargs = {'token': 'alpha',
'username': 'bravo',
'password': 'charlie',
'tenant_name': 'delta',
'auth_url': 'echo',
'session': 'foxtrot',
'endpoint': 'golf',
'version': 'hotel',
'cert': 'india',
'insecure': 'juliet',
'opts': Mock()}
c = client.Client(**kwargs)
self.assertIsInstance(c, client.Client)
self.assertEqual('alpha', c.opts.os_token)
self.assertEqual('bravo', c.opts.os_username)
self.assertEqual('charlie', c.opts.os_password)
self.assertEqual('delta', c.opts.os_tenant_name)
self.assertEqual('echo', c.opts.os_auth_url)
self.assertEqual('foxtrot', c._session)
self.assertEqual('foxtrot', c.session)
self.assertEqual('golf', c.endpoint)
self.assertEqual('hotel', c.version)
@patch('freezer.apiclient.client.ksa_session')
@patch('freezer.apiclient.client.get_auth_plugin')
def test_get_token(self, mock_get_auth_plugin, mock_ksa_session):
mock_session = Mock()
mock_session.get_token.return_value = 'antaniX2'
c = client.Client(session=mock_session, endpoint='justtest', opts=Mock())
self.assertIsInstance(c, client.Client)
self.assertEqual('antaniX2', c.auth_token)
@patch('freezer.apiclient.client.socket')
@patch('freezer.apiclient.client.ksa_session')
@patch('freezer.apiclient.client.get_auth_plugin')
def test_get_client_id(self, mock_get_auth_plugin, mock_ksa_session, mock_socket):
mock_socket.gethostname.return_value = 'parmenide'
mock_session = Mock()
mock_session.get_project_id.return_value = 'H2O'
c = client.Client(session=mock_session, endpoint='justtest', opts=Mock())
self.assertIsInstance(c, client.Client)
self.assertEqual('H2O_parmenide', c.client_id)

View File

@ -1,25 +0,0 @@
# (c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from freezer.apiclient import exceptions
class TestApiClientException(unittest.TestCase):
def test_get_message_from_response_string(self):
e = exceptions.ApiClientException('some error message')
self.assertEqual(str(e), 'some error message')

View File

@ -1,240 +0,0 @@
"""
Copyright 2015 Hewlett-Packard
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 json
import unittest
from mock import Mock, patch
from freezer.apiclient import exceptions
from freezer.apiclient import jobs
class TestJobManager(unittest.TestCase):
def setUp(self):
self.mock_client = Mock()
self.mock_response = Mock()
self.mock_client.endpoint = 'http://testendpoint:9999'
self.mock_client.auth_token = 'testtoken'
self.headers = {'X-Auth-Token': 'testtoken'}
self.mock_client.client_id = 'test_client_id_78900987'
self.job_manager = jobs.JobManager(self.mock_client)
@patch('freezer.apiclient.jobs.requests')
def test_create(self, mock_requests):
self.assertEqual('http://testendpoint:9999/v1/jobs/', self.job_manager.endpoint)
self.assertEqual({'X-Auth-Token': 'testtoken'}, self.job_manager.headers)
@patch('freezer.apiclient.jobs.requests')
def test_create_ok(self, mock_requests):
self.mock_response.status_code = 201
self.mock_response.json.return_value = {'job_id': 'qwerqwer'}
mock_requests.post.return_value = self.mock_response
retval = self.job_manager.create({'job': 'metadata'})
self.assertEqual('qwerqwer', retval)
@patch('freezer.apiclient.jobs.json')
@patch('freezer.apiclient.jobs.requests')
def test_create_adds_client_id_if_not_provided(self, mock_requests, mock_json):
self.mock_response.status_code = 201
self.mock_response.json.return_value = {'job_id': 'qwerqwer'}
mock_json.dumps.return_value = {'job': 'mocked'}
mock_requests.post.return_value = self.mock_response
retval = self.job_manager.create({'job': 'metadata'})
mock_json.dumps.assert_called_with({'job': 'metadata',
'client_id': 'test_client_id_78900987'})
self.assertEqual('qwerqwer', retval)
@patch('freezer.apiclient.jobs.json')
@patch('freezer.apiclient.jobs.requests')
def test_create_leaves_provided_client_id(self, mock_requests, mock_json):
self.mock_response.status_code = 201
self.mock_response.json.return_value = {'job_id': 'qwerqwer'}
mock_json.dumps.return_value = {'job': 'mocked'}
mock_requests.post.return_value = self.mock_response
retval = self.job_manager.create({'job': 'metadata', 'client_id': 'parmenide'})
mock_json.dumps.assert_called_with({'job': 'metadata',
'client_id': 'parmenide'})
self.assertEqual('qwerqwer', retval)
@patch('freezer.apiclient.jobs.requests')
def test_create_fail_when_api_return_error_code(self, mock_requests):
self.mock_response.status_code = 500
mock_requests.post.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.job_manager.create, {'job': 'metadata'})
@patch('freezer.apiclient.jobs.requests')
def test_delete_ok(self, mock_requests):
self.mock_response.status_code = 204
mock_requests.delete.return_value = self.mock_response
retval = self.job_manager.delete('test_job_id')
self.assertIsNone(retval)
@patch('freezer.apiclient.jobs.requests')
def test_delete_fail(self, mock_requests):
self.mock_response.status_code = 500
mock_requests.delete.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.job_manager.delete, 'test_job_id')
@patch('freezer.apiclient.jobs.requests')
def test_get_ok(self, mock_requests):
self.mock_response.status_code = 200
self.mock_response.json.return_value = {'job_id': 'qwerqwer'}
mock_requests.get.return_value = self.mock_response
retval = self.job_manager.get('test_job_id')
self.assertEqual({'job_id': 'qwerqwer'}, retval)
@patch('freezer.apiclient.jobs.requests')
def test_get_fails_on_error_different_from_404(self, mock_requests):
self.mock_response.status_code = 500
mock_requests.get.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.job_manager.get, 'test_job_id')
@patch('freezer.apiclient.jobs.requests')
def test_get_none(self, mock_requests):
self.mock_response.status_code = 404
mock_requests.get.return_value = self.mock_response
retval = self.job_manager.get('test_job_id')
self.assertIsNone(retval)
@patch('freezer.apiclient.jobs.requests')
def test_list_ok(self, mock_requests):
self.mock_response.status_code = 200
job_list = [{'job_id_0': 'bomboloid'}, {'job_id_1': 'asdfasdf'}]
self.mock_response.json.return_value = {'jobs': job_list}
mock_requests.get.return_value = self.mock_response
retval = self.job_manager.list()
self.assertEqual(job_list, retval)
@patch('freezer.apiclient.jobs.requests')
def test_list_error(self, mock_requests):
self.mock_response.status_code = 404
job_list = [{'job_id_0': 'bomboloid'}, {'job_id_1': 'asdfasdf'}]
self.mock_response.json.return_value = {'clients': job_list}
mock_requests.get.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.job_manager.list)
@patch('freezer.apiclient.jobs.requests')
def test_update_ok(self, mock_requests):
self.mock_response.status_code = 200
self.mock_response.json.return_value = {
"patch": {"status": "bamboozled"},
"version": 12,
"job_id": "d454beec-1f3c-4d11-aa1a-404116a40502"
}
mock_requests.patch.return_value = self.mock_response
retval = self.job_manager.update('d454beec-1f3c-4d11-aa1a-404116a40502', {'status': 'bamboozled'})
self.assertEqual(12, retval)
@patch('freezer.apiclient.jobs.requests')
def test_update_raise_MetadataUpdateFailure_when_api_return_error_code(self, mock_requests):
self.mock_response.json.return_value = {
"patch": {"status": "bamboozled"},
"version": 12,
"job_id": "d454beec-1f3c-4d11-aa1a-404116a40502"
}
self.mock_response.status_code = 404
self.mock_response.text = '{"title": "Not Found","description":"No document found with ID d454beec-1f3c-4d11-aa1a-404116a40502x"}'
mock_requests.patch.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.job_manager.update,
'd454beec-1f3c-4d11-aa1a-404116a40502', {'status': 'bamboozled'})
@patch('freezer.apiclient.jobs.requests')
def test_start_job_posts_proper_data(self, mock_requests):
job_id = 'jobdfsfnqwerty1234'
self.mock_response.status_code = 202
self.mock_response.json.return_value = {'result': 'success'}
mock_requests.post.return_value = self.mock_response
# /v1/jobs/{job_id}/event
endpoint = '{0}/v1/jobs/{1}/event'.format(self.mock_client.endpoint, job_id)
data = {"start": None}
retval = self.job_manager.start_job(job_id)
self.assertEqual({'result': 'success'}, retval)
args = mock_requests.post.call_args[0]
kwargs = mock_requests.post.call_args[1]
self.assertEqual(endpoint, args[0])
self.assertEqual(data, json.loads(kwargs['data']))
self.assertEqual(self.headers, kwargs['headers'])
@patch('freezer.apiclient.jobs.requests')
def test_start_job_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
job_id = 'jobdfsfnqwerty1234'
self.mock_response.status_code = 500
self.mock_response.json.return_value = {'result': 'success'}
mock_requests.post.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.job_manager.start_job, job_id)
@patch('freezer.apiclient.jobs.requests')
def test_stop_job_posts_proper_data(self, mock_requests):
job_id = 'jobdfsfnqwerty1234'
self.mock_response.status_code = 202
self.mock_response.json.return_value = {'result': 'success'}
mock_requests.post.return_value = self.mock_response
# /v1/jobs/{job_id}/event
endpoint = '{0}/v1/jobs/{1}/event'.format(self.mock_client.endpoint, job_id)
data = {"stop": None}
retval = self.job_manager.stop_job(job_id)
self.assertEqual({'result': 'success'}, retval)
args = mock_requests.post.call_args[0]
kwargs = mock_requests.post.call_args[1]
self.assertEqual(endpoint, args[0])
self.assertEqual(data, json.loads(kwargs['data']))
self.assertEqual(self.headers, kwargs['headers'])
@patch('freezer.apiclient.jobs.requests')
def test_stop_job_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
job_id = 'jobdfsfnqwerty1234'
self.mock_response.status_code = 500
self.mock_response.json.return_value = {'result': 'success'}
mock_requests.post.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.job_manager.start_job, job_id)
@patch('freezer.apiclient.jobs.requests')
def test_abort_job_posts_proper_data(self, mock_requests):
job_id = 'jobdfsfnqwerty1234'
self.mock_response.status_code = 202
self.mock_response.json.return_value = {'result': 'success'}
mock_requests.post.return_value = self.mock_response
# /v1/jobs/{job_id}/event
endpoint = '{0}/v1/jobs/{1}/event'.format(self.mock_client.endpoint, job_id)
data = {"abort": None}
retval = self.job_manager.abort_job(job_id)
self.assertEqual({'result': 'success'}, retval)
args = mock_requests.post.call_args[0]
kwargs = mock_requests.post.call_args[1]
self.assertEqual(endpoint, args[0])
self.assertEqual(data, json.loads(kwargs['data']))
self.assertEqual(self.headers, kwargs['headers'])
@patch('freezer.apiclient.jobs.requests')
def test_abort_job_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
job_id = 'jobdfsfnqwerty1234'
self.mock_response.status_code = 500
self.mock_response.json.return_value = {'result': 'success'}
mock_requests.post.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.job_manager.abort_job, job_id)

View File

@ -1,111 +0,0 @@
"""
Copyright 2015 Hewlett-Packard
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 unittest
from mock import Mock, patch
from freezer.apiclient import exceptions
from freezer.apiclient import registration
class TestRegistrationManager(unittest.TestCase):
def setUp(self):
self.mock_client = Mock()
self.mock_client.endpoint = 'http://testendpoint:9999'
self.mock_client.auth_token = 'testtoken'
self.r = registration.RegistrationManager(self.mock_client)
@patch('freezer.apiclient.registration.requests')
def test_create(self, mock_requests):
self.assertEqual('http://testendpoint:9999/v1/clients/', self.r.endpoint)
self.assertEqual({'X-Auth-Token': 'testtoken'}, self.r.headers)
@patch('freezer.apiclient.registration.requests')
def test_create_ok(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 201
mock_response.json.return_value = {'client_id': 'qwerqwer'}
mock_requests.post.return_value = mock_response
retval = self.r.create(client_info={'client': 'metadata'})
self.assertEqual('qwerqwer', retval)
@patch('freezer.apiclient.registration.requests')
def test_create_fail_when_api_return_error_code(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 500
mock_requests.post.return_value = mock_response
self.assertRaises(exceptions.ApiClientException, self.r.create, {'client': 'metadata'})
@patch('freezer.apiclient.registration.requests')
def test_delete_ok(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 204
mock_requests.delete.return_value = mock_response
retval = self.r.delete('test_client_id')
self.assertIsNone(retval)
@patch('freezer.apiclient.registration.requests')
def test_delete_fail(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 500
mock_requests.delete.return_value = mock_response
self.assertRaises(exceptions.ApiClientException, self.r.delete, 'test_client_id')
@patch('freezer.apiclient.registration.requests')
def test_get_ok(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 200
mock_response.json.return_value = {'client_id': 'qwerqwer'}
mock_requests.get.return_value = mock_response
retval = self.r.get('test_client_id')
self.assertEqual({'client_id': 'qwerqwer'}, retval)
@patch('freezer.apiclient.registration.requests')
def test_get_none(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 404
mock_requests.get.return_value = mock_response
retval = self.r.get('test_client_id')
self.assertIsNone(retval)
@patch('freezer.apiclient.registration.requests')
def test_get_raises_ApiClientException_on_error_not_404(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 500
mock_requests.get.return_value = mock_response
self.assertRaises(exceptions.ApiClientException, self.r.get, 'test_client_id')
@patch('freezer.apiclient.registration.requests')
def test_list_ok(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 200
client_list = [{'client_id_0': 'qwerqwer'}, {'client_id_1': 'asdfasdf'}]
mock_response.json.return_value = {'clients': client_list}
mock_requests.get.return_value = mock_response
retval = self.r.list()
self.assertEqual(client_list, retval)
@patch('freezer.apiclient.registration.requests')
def test_list_error(self, mock_requests):
mock_response = Mock()
mock_response.status_code = 404
client_list = [{'client_id_0': 'qwerqwer'}, {'client_id_1': 'asdfasdf'}]
mock_response.json.return_value = {'clients': client_list}
mock_requests.get.return_value = mock_response
self.assertRaises(exceptions.ApiClientException, self.r.list)

View File

@ -1,223 +0,0 @@
"""
Copyright 2015 Hewlett-Packard
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 json
import unittest
from mock import Mock, patch
from freezer.apiclient import exceptions
from freezer.apiclient import sessions
class TestSessionManager(unittest.TestCase):
def setUp(self):
self.mock_client = Mock()
self.mock_response = Mock()
self.mock_client.endpoint = 'http://testendpoint:9999'
self.mock_client.auth_token = 'testtoken'
self.mock_client.client_id = 'test_client_id_78900987'
self.session_manager = sessions.SessionManager(self.mock_client)
self.endpoint = 'http://testendpoint:9999/v1/sessions/'
self.headers = {'X-Auth-Token': 'testtoken'}
@patch('freezer.apiclient.sessions.requests')
def test_create(self, mock_requests):
self.assertEqual(self.endpoint, self.session_manager.endpoint)
self.assertEqual(self.headers, self.session_manager.headers)
@patch('freezer.apiclient.sessions.requests')
def test_create_ok(self, mock_requests):
self.mock_response.status_code = 201
self.mock_response.json.return_value = {'session_id': 'qwerqwer'}
mock_requests.post.return_value = self.mock_response
retval = self.session_manager.create({'session': 'metadata'})
self.assertEqual('qwerqwer', retval)
@patch('freezer.apiclient.sessions.requests')
def test_create_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
self.mock_response.status_code = 500
mock_requests.post.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.session_manager.create, {'session': 'metadata'})
@patch('freezer.apiclient.sessions.requests')
def test_delete_ok(self, mock_requests):
self.mock_response.status_code = 204
mock_requests.delete.return_value = self.mock_response
retval = self.session_manager.delete('test_session_id')
self.assertIsNone(retval)
@patch('freezer.apiclient.sessions.requests')
def test_delete_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
self.mock_response.status_code = 500
mock_requests.delete.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.session_manager.delete, 'test_session_id')
@patch('freezer.apiclient.sessions.requests')
def test_get_ok(self, mock_requests):
self.mock_response.status_code = 200
self.mock_response.json.return_value = {'session_id': 'qwerqwer'}
mock_requests.get.return_value = self.mock_response
retval = self.session_manager.get('test_session_id')
self.assertEqual({'session_id': 'qwerqwer'}, retval)
@patch('freezer.apiclient.sessions.requests')
def test_get_raise_ApiClientException_when_api_return_error_different_from_404(self, mock_requests):
self.mock_response.status_code = 500
mock_requests.get.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.session_manager.get, 'test_session_id')
@patch('freezer.apiclient.sessions.requests')
def test_get_none(self, mock_requests):
self.mock_response.status_code = 404
mock_requests.get.return_value = self.mock_response
retval = self.session_manager.get('test_session_id')
self.assertIsNone(retval)
@patch('freezer.apiclient.sessions.requests')
def test_list_ok(self, mock_requests):
self.mock_response.status_code = 200
session_list = [{'session_id_0': 'bomboloid'}, {'session_id_1': 'asdfasdf'}]
self.mock_response.json.return_value = {'sessions': session_list}
mock_requests.get.return_value = self.mock_response
retval = self.session_manager.list()
self.assertEqual(session_list, retval)
@patch('freezer.apiclient.sessions.requests')
def test_list_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
self.mock_response.status_code = 404
session_list = [{'session_id_0': 'bomboloid'}, {'session_id_1': 'asdfasdf'}]
self.mock_response.json.return_value = {'clients': session_list}
mock_requests.get.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.session_manager.list)
@patch('freezer.apiclient.sessions.requests')
def test_update_ok(self, mock_requests):
self.mock_response.status_code = 200
self.mock_response.json.return_value = {
"patch": {"status": "bamboozled"},
"version": 12,
"session_id": "d454beec-1f3c-4d11-aa1a-404116a40502"
}
mock_requests.patch.return_value = self.mock_response
retval = self.session_manager.update('d454beec-1f3c-4d11-aa1a-404116a40502', {'status': 'bamboozled'})
self.assertEqual(12, retval)
@patch('freezer.apiclient.sessions.requests')
def test_update_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
self.mock_response.json.return_value = {
"patch": {"status": "bamboozled"},
"version": 12,
"session_id": "d454beec-1f3c-4d11-aa1a-404116a40502"
}
self.mock_response.status_code = 404
self.mock_response.text = '{"title": "Not Found","description":"No document found with ID d454beec-1f3c-4d11-aa1a-404116a40502x"}'
mock_requests.patch.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.session_manager.update,
'd454beec-1f3c-4d11-aa1a-404116a40502', {'status': 'bamboozled'})
@patch('freezer.apiclient.sessions.requests')
def test_add_job_uses_proper_endpoint(self, mock_requests):
session_id, job_id = 'sessionqwerty1234', 'jobqwerty1234'
self.mock_response.status_code = 204
mock_requests.put.return_value = self.mock_response
endpoint = '{0}{1}/jobs/{2}'.format(self.endpoint, session_id, job_id)
retval = self.session_manager.add_job(session_id, job_id)
self.assertIsNone(retval)
mock_requests.put.assert_called_with(endpoint, headers=self.headers, verify=True)
@patch('freezer.apiclient.sessions.requests')
def test_add_job_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
session_id, job_id = 'sessionqwerty1234', 'jobqwerty1234'
self.mock_response.status_code = 500
mock_requests.put.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.session_manager.add_job, session_id, job_id)
@patch('freezer.apiclient.sessions.requests')
def test_remove_job_uses_proper_endpoint(self, mock_requests):
session_id, job_id = 'sessionqwerty1234', 'jobqwerty1234'
self.mock_response.status_code = 204
mock_requests.delete.return_value = self.mock_response
endpoint = '{0}{1}/jobs/{2}'.format(self.endpoint, session_id, job_id)
retval = self.session_manager.remove_job(session_id, job_id)
self.assertIsNone(retval)
mock_requests.delete.assert_called_with(endpoint, headers=self.headers, verify=True)
@patch('freezer.apiclient.sessions.requests')
def test_remove_job_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
session_id, job_id = 'sessionqwerty1234', 'jobqwerty1234'
self.mock_response.status_code = 500
mock_requests.delete.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.session_manager.remove_job, session_id, job_id)
@patch('freezer.apiclient.sessions.requests')
def test_start_session_posts_proper_data(self, mock_requests):
session_id, job_id, tag = 'sessionqwerty1234', 'jobqwerty1234', 23
self.mock_response.status_code = 202
self.mock_response.json.return_value = {'result': 'success', 'session_tag': 24}
mock_requests.post.return_value = self.mock_response
# /v1/sessions/{sessions_id}/action
endpoint = '{0}{1}/action'.format(self.endpoint, session_id)
data = {"start": {"current_tag": 23, "job_id": "jobqwerty1234"}}
retval = self.session_manager.start_session(session_id, job_id, tag)
self.assertEqual({'result': 'success', 'session_tag': 24}, retval)
args = mock_requests.post.call_args[0]
kwargs = mock_requests.post.call_args[1]
self.assertEqual(endpoint, args[0])
self.assertEqual(data, json.loads(kwargs['data']))
self.assertEqual(self.headers, kwargs['headers'])
@patch('freezer.apiclient.sessions.requests')
def test_start_session_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
session_id, job_id, tag = 'sessionqwerty1234', 'jobqwerty1234', 23
self.mock_response.status_code = 500
self.mock_response.json.return_value = {'result': 'success', 'session_tag': 24}
mock_requests.post.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.session_manager.start_session,
session_id, job_id, tag)
@patch('freezer.apiclient.sessions.requests')
def test_end_session_posts_proper_data(self, mock_requests):
session_id, job_id, tag = 'sessionqwerty1234', 'jobqwerty1234', 23
self.mock_response.status_code = 202
self.mock_response.json.return_value = {'result': 'success', 'session_tag': 24}
mock_requests.post.return_value = self.mock_response
# /v1/sessions/{sessions_id}/action
endpoint = '{0}{1}/action'.format(self.endpoint, session_id)
data = {"end": {"current_tag": 23, "job_id": "jobqwerty1234", "result": "fail"}}
retval = self.session_manager.end_session(session_id, job_id, tag, 'fail')
self.assertEqual({'result': 'success', 'session_tag': 24}, retval)
args = mock_requests.post.call_args[0]
kwargs = mock_requests.post.call_args[1]
self.assertEqual(endpoint, args[0])
self.assertEqual(data, json.loads(kwargs['data']))
self.assertEqual(self.headers, kwargs['headers'])
@patch('freezer.apiclient.sessions.requests')
def test_end_session_raise_ApiClientException_when_api_return_error_code(self, mock_requests):
session_id, job_id, tag = 'sessionqwerty1234', 'jobqwerty1234', 23
self.mock_response.status_code = 500
self.mock_response.json.return_value = {'result': 'success', 'session_tag': 24}
mock_requests.post.return_value = self.mock_response
self.assertRaises(exceptions.ApiClientException, self.session_manager.end_session,
session_id, job_id, tag, 'fail')

View File

@ -9,6 +9,7 @@ python-cinderclient!=1.7.0,!=1.7.1,>=1.6.0 # Apache-2.0
python-glanceclient>=2.5.0 # Apache-2.0
python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0
python-openstackclient>=3.3.0 # Apache-2.0
python-freezerclient>=1.0.0 # Apache-2.0
oslo.utils>=3.18.0 # Apache-2.0
oslo.i18n>=2.1.0 # Apache-2.0
oslo.log>=3.11.0 # Apache-2.0
@ -24,3 +25,4 @@ six>=1.9.0 # MIT
apscheduler # MIT License
psutil<2.0.0,>=1.1.1 # BSD