Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions libcloud/compute/drivers/cloudwatt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing first line of the license header - # Licensed to the Apache Software Foundation (ASF) under one or more

# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

"""
Cloudwatt driver.
"""
import sys
try:
import simplejson as json
except ImportError:
import json
from libcloud.utils.py3 import httplib
from libcloud.compute.types import Provider
from libcloud.compute.drivers.openstack import OpenStack_1_1_Connection
from libcloud.compute.drivers.openstack import OpenStack_1_1_NodeDriver
from libcloud.common.openstack import OpenStackAuthConnection
from libcloud.utils.iso8601 import parse_date

from libcloud.compute.types import InvalidCredsError, MalformedResponseError


__all__ = [
'CloudwattNodeDriver'
]

BASE_URL = 'https://identity.fr1.cloudwatt.com/v2.0'
AUTH_URL = BASE_URL + '/tokens'


class CloudwattAuthConnection(OpenStackAuthConnection):
"""
AuthConnection class for the Cloudwatt driver.
"""
name = 'Cloudwatt Auth'

def __init__(self, *args, **kwargs):
self._ex_tenant_id = kwargs.pop('ex_tenant_id')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, could we maybe use an existing ex_tenant_name argument here?

super(CloudwattAuthConnection, self).__init__(*args, **kwargs)

def authenticate(self, force=False):
reqbody = json.dumps({'auth': {
'passwordCredentials': {
'username': self.user_id,
'password': self.key
},
'tenantId': self._ex_tenant_id
}})
resp = self.request('/tokens', data=reqbody, headers={},
method='POST')

if resp.status == httplib.UNAUTHORIZED:
# HTTP UNAUTHORIZED (401): auth failed
raise InvalidCredsError()
elif resp.status != httplib.OK:
body = 'code: %s body:%s' % (resp.status, resp.body)
raise MalformedResponseError('Malformed response', body=body,
driver=self.driver)
else:
try:
body = json.loads(resp.body)
except Exception:
e = sys.exc_info()[1]
raise MalformedResponseError('Failed to parse JSON', e)

try:
expires = body['access']['token']['expires']

self.auth_token = body['access']['token']['id']
self.auth_token_expires = parse_date(expires)
self.urls = body['access']['serviceCatalog']
self.auth_user_info = None
except KeyError:
e = sys.exc_info()[1]
raise MalformedResponseError('Auth JSON response is \
missing required elements', e)

return self


class CloudwattConnection(OpenStack_1_1_Connection):
"""
Connection class for the Cloudwatt driver.
"""
auth_url = BASE_URL
service_region = 'fr1'
service_type = 'compute'

def __init__(self, *args, **kwargs):
self.ex_tenant_id = kwargs.pop('ex_tenant_id')
super(CloudwattConnection, self).__init__(*args, **kwargs)
osa = CloudwattAuthConnection(
self,
AUTH_URL,
self._auth_version,
self.user_id,
self.key,
tenant_name=self._ex_tenant_name,
timeout=self.timeout,
ex_tenant_id=self.ex_tenant_id
)
self._osa = osa
self._auth_version = '2.0'


class CloudwattNodeDriver(OpenStack_1_1_NodeDriver):
"""
Implements the :class:`NodeDriver`'s for Cloudwatt.
"""
name = 'Cloudwatt'
website = 'https://www.cloudwatt.com/'
connectionCls = CloudwattConnection
type = Provider.CLOUDWATT

def __init__(self, key, secret, tenant_id, secure=True, tenant_name=None,
host=None, port=None, **kwargs):
"""
@inherits: :class:`NodeDriver.__init__`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inherits CloudwattNodeDriver ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind, my bad


:param tenant_id: ID of tenant required for Cloudwatt auth
:type tenant_id: ``str``
"""
self.ex_tenant_id = tenant_id
self.extra = {}
super(CloudwattNodeDriver, self).__init__(
key=key,
secret=secret,
secure=secure,
host=host,
port=port,
**kwargs
)

def _ex_connection_class_kwargs(self):
"""
Includes ``tenant_id`` in Connection.
"""
return {
'ex_tenant_id': self.ex_tenant_id
}
2 changes: 2 additions & 0 deletions libcloud/compute/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@
('libcloud.compute.drivers.ec2', 'OutscaleSASNodeDriver'),
Provider.OUTSCALE_INC:
('libcloud.compute.drivers.ec2', 'OutscaleINCNodeDriver'),
Provider.CLOUDWATT:
('libcloud.compute.drivers.cloudwatt', 'CloudwattNodeDriver'),

# Deprecated
Provider.CLOUDSIGMA_US:
Expand Down
1 change: 1 addition & 0 deletions libcloud/compute/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ class Provider(object):

# OpenStack based providers
HPCLOUD = 'hpcloud'
CLOUDWATT = 'cloudwatt'
KILI = 'kili'

# Deprecated constants which are still supported
Expand Down