Skip to content

Commit 8f811a8

Browse files
committed
Merge pull request #19 from clarkperkins/feature/upgrade-to-0.7
Feature/upgrade to 0.7
2 parents 03da27d + 7391b63 commit 8f811a8

File tree

15 files changed

+214
-372
lines changed

15 files changed

+214
-372
lines changed

requirements.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

setup.py

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,52 +15,43 @@
1515
# limitations under the License.
1616
#
1717

18-
import os
1918
import sys
2019

2120
from setuptools import setup, find_packages
22-
from pip.req import parse_requirements
23-
from pip.download import PipSession
2421

2522

2623
def test_python_version():
27-
if float("%d.%d" % sys.version_info[:2]) < 2.6:
28-
print('Your Python version {0}.{1}.{2} is not supported.'.format(
29-
*sys.version_info[:3]))
30-
print('stackdio requires Python 2.6 or newer.')
24+
major = sys.version_info[0]
25+
minor = sys.version_info[1]
26+
micro = sys.version_info[2]
27+
if float('%d.%d' % (major, minor)) < 2.6:
28+
err_msg = ('Your Python version {0}.{1}.{2} is not supported.\n'
29+
'stackdio-server requires Python 2.6 or newer.\n'.format(major, minor, micro))
30+
sys.stderr.write(err_msg)
3131
sys.exit(1)
3232

33-
34-
def load_pip_requirements(fp):
35-
reqs, deps = [], []
36-
for r in parse_requirements(fp, session=PipSession()):
37-
if r.url is not None:
38-
deps.append(str(r.url))
39-
reqs.append(str(r.req))
40-
return reqs, deps
41-
4233
# Set version
4334
__version__ = '0.0.0' # Explicit default
44-
execfile("stackdio/client/version.py")
35+
execfile('stackdio/client/version.py')
4536

4637

4738
SHORT_DESCRIPTION = ('A cloud deployment, automation, and orchestration '
4839
'platform for everyone.')
49-
LONG_DESCRIPTION = SHORT_DESCRIPTION
5040

51-
# If we have a README.md file, use its contents as the long description
52-
if os.path.isfile('README.md'):
53-
with open('README.md') as f:
54-
LONG_DESCRIPTION = f.read()
41+
# Use the README.md as the long description
42+
with open('README.md') as f:
43+
LONG_DESCRIPTION = f.read()
5544

45+
requirements = [
46+
'simplejson',
47+
'requests>=2.4.0,<2.6.0',
48+
]
5649

5750
if __name__ == "__main__":
58-
# build our list of requirements and dependency links based on our
59-
# requirements.txt file
60-
reqs, deps = load_pip_requirements('requirements.txt')
51+
test_python_version()
6152

6253
# Call the setup method from setuptools that does all the heavy lifting
63-
# of packaging stackdio
54+
# of packaging stackdio-client
6455
setup(
6556
name='stackdio',
6657
version=__version__,
@@ -73,17 +64,18 @@ def load_pip_requirements(fp):
7364
include_package_data=True,
7465
packages=find_packages(),
7566
zip_safe=False,
76-
install_requires=reqs,
77-
dependency_links=deps,
67+
install_requires=requirements,
68+
dependency_links=[],
7869
classifiers=[
79-
'Development Status :: 3 - Alpha',
70+
'Development Status :: 4 - Beta',
8071
'Environment :: Web Environment',
8172
'Framework :: Django',
8273
'Intended Audience :: Developers',
8374
'Intended Audience :: Information Technology',
8475
'Intended Audience :: System Administrators',
8576
'License :: OSI Approved :: Apache Software License',
8677
'Programming Language :: Python',
78+
'Programming Language :: Python :: 2',
8779
'Programming Language :: Python :: 2.6',
8880
'Programming Language :: Python :: 2.7',
8981
'Topic :: System :: Clustering',

stackdio/client/__init__.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919
import logging
2020

2121
from .http import use_admin_auth, endpoint
22-
from .exceptions import BlueprintException, StackException
22+
from .exceptions import BlueprintException, StackException, IncompatibleVersionException
2323

2424
from .blueprint import BlueprintMixin
2525
from .formula import FormulaMixin
26-
from .profile import ProfileMixin
27-
from .provider import ProviderMixin
26+
from .account import AccountMixin
27+
from .image import ImageMixin
2828
from .region import RegionMixin
2929
from .settings import SettingsMixin
3030
from .stack import StackMixin
@@ -34,8 +34,8 @@
3434
logger = logging.getLogger(__name__)
3535

3636

37-
class StackdIO(BlueprintMixin, FormulaMixin, ProfileMixin,
38-
ProviderMixin, RegionMixin, StackMixin, SettingsMixin):
37+
class StackdIO(BlueprintMixin, FormulaMixin, AccountMixin,
38+
ImageMixin, RegionMixin, StackMixin, SettingsMixin):
3939

4040
def __init__(self, protocol="https", host="localhost", port=443,
4141
base_url=None, auth=None, auth_admin=None,
@@ -57,6 +57,10 @@ def __init__(self, protocol="https", host="localhost", port=443,
5757

5858
_, self.version = _parse_version_string(self.get_version())
5959

60+
if self.version[0] != 0 or self.version[1] != 7:
61+
raise IncompatibleVersionException('Server version {0}.{1}.{2} not '
62+
'supported.'.format(**self.version))
63+
6064
@endpoint("")
6165
def get_root(self):
6266
"""Get the api root"""
@@ -79,10 +83,10 @@ def create_security_group(self, name, description, cloud_provider, is_default=Tr
7983
}
8084
return self._post(endpoint, data=json.dumps(data), jsonify=True)
8185

82-
@endpoint("settings/")
86+
@endpoint("user/")
8387
def get_public_key(self):
84-
"""Get the public key for the logged in uesr"""
85-
return self._get(endpoint, jsonify=True)['public_key']
88+
"""Get the public key for the logged in user"""
89+
return self._get(endpoint, jsonify=True)['settings']['public_key']
8690

8791
@endpoint("settings/")
8892
def set_public_key(self, public_key):

stackdio/client/account.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Copyright 2014, Digital Reasoning
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
import json
19+
20+
from .http import HttpMixin, endpoint
21+
22+
23+
class AccountMixin(HttpMixin):
24+
25+
@endpoint("cloud/providers/")
26+
def list_providers(self):
27+
"""List all providers"""
28+
return self._get(endpoint, jsonify=True)['results']
29+
30+
@endpoint("cloud/providers/")
31+
def search_providers(self, provider_id):
32+
"""List all providers"""
33+
return self._get(endpoint, jsonify=True)['results']
34+
35+
@endpoint("cloud/accounts/")
36+
def create_account(self, **kwargs):
37+
"""Create an account"""
38+
39+
form_data = {
40+
"title": None,
41+
"account_id": None,
42+
"provider": None,
43+
"access_key_id": None,
44+
"secret_access_key": None,
45+
"keypair": None,
46+
"security_groups": None,
47+
"route53_domain": None,
48+
"default_availability_zone": None,
49+
"private_key": None
50+
}
51+
52+
for key in form_data.keys():
53+
form_data[key] = kwargs.get(key)
54+
55+
return self._post(endpoint, data=json.dumps(form_data), jsonify=True)
56+
57+
@endpoint("accounts/")
58+
def list_accounts(self):
59+
"""List all account"""
60+
return self._get(endpoint, jsonify=True)['results']
61+
62+
@endpoint("accounts/{account_id}/")
63+
def get_account(self, account_id, none_on_404=False):
64+
"""Return the account that matches the given id"""
65+
return self._get(endpoint, jsonify=True, none_on_404=none_on_404)
66+
67+
@endpoint("accounts/")
68+
def search_accounts(self, account_id):
69+
"""List all accounts"""
70+
return self._get(endpoint, jsonify=True)['results']
71+
72+
@endpoint("accounts/{account_id}/")
73+
def delete_account(self, account_id):
74+
"""List all accounts"""
75+
return self._delete(endpoint, jsonify=True)['results']

stackdio/client/blueprint.py

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717

1818
import json
1919

20-
from .exceptions import StackException
2120
from .http import HttpMixin, endpoint
22-
from .version import accepted_versions, deprecated
2321

2422

2523
class BlueprintMixin(HttpMixin):
@@ -28,25 +26,33 @@ class BlueprintMixin(HttpMixin):
2826
def create_blueprint(self, blueprint, provider="ec2"):
2927
"""Create a blueprint"""
3028

31-
# check the provided blueprint to see if we need to look up any ids
32-
for host in blueprint["hosts"]:
33-
if isinstance(host["size"], basestring):
34-
host["size"] = self.get_instance_id(host["size"], provider)
29+
formula_map = {}
30+
31+
if 'formula_versions' in blueprint:
32+
all_formulas = self.list_formulas()
3533

36-
# zone isn't required if you provide a subnet_id
37-
if 'zone' in host and isinstance(host["zone"], basestring):
38-
host["zone"] = self.get_zone_id(host["zone"], provider)
34+
used_formulas = []
3935

40-
if isinstance(host["cloud_profile"], basestring):
41-
host["cloud_profile"] = self.get_profile_id(host["cloud_profile"]) # noqa
36+
for formula_version in blueprint['formula_versions']:
37+
for formula in all_formulas:
38+
if formula['uri'] == formula_version['formula']:
39+
formula['version'] = formula_version['version']
40+
used_formulas.append(formula)
41+
break
4242

43-
for component in host["formula_components"]:
44-
if not component.get("sls_path") and isinstance(component["id"], (tuple, list)):
45-
formula_id = self.get_formula_id(component["id"][0])
43+
for formula in used_formulas:
44+
components = self._get(
45+
'{0}?version={1}'.format(formula['components'], formula['version']),
46+
jsonify=True,
47+
)['results']
48+
for component in components:
49+
formula_map[component['sls_path']] = formula['uri']
4650

47-
component["id"] = self.get_component_id(
48-
self.get_formula(formula_id),
49-
component["id"][1])
51+
# check the provided blueprint to see if we need to look up any ids
52+
for host in blueprint['host_definitions']:
53+
for component in host['formula_components']:
54+
if component['sls_path'] in formula_map:
55+
component['formula'] = formula_map[component['sls_path']]
5056

5157
return self._post(endpoint, data=json.dumps(blueprint), jsonify=True, raise_for_status=False)
5258

@@ -68,15 +74,3 @@ def search_blueprints(self, **kwargs):
6874
@endpoint("blueprints/{blueprint_id}")
6975
def delete_blueprint(self, blueprint_id):
7076
return self._delete(endpoint, jsonify=True)
71-
72-
@deprecated
73-
@accepted_versions("<0.7")
74-
def get_blueprint_id(self, title):
75-
"""Get the id for a blueprint that matches title"""
76-
77-
blueprints = self.search_blueprints(title=title)
78-
79-
if not len(blueprints):
80-
raise StackException("Blueprint %s not found" % title)
81-
82-
return blueprints[0]['id']

stackdio/client/exceptions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# limitations under the License.
1616
#
1717

18+
1819
class StackException(Exception):
1920
pass
2021

stackdio/client/formula.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import json
1919

20-
from .exceptions import StackException
2120
from .http import HttpMixin, endpoint
2221

2322

@@ -55,23 +54,3 @@ def delete_formula(self, formula_id):
5554
def update_formula(self, formula_id):
5655
"""Delete formula with matching id"""
5756
return self._post(endpoint, json.dumps({"action": "update"}), jsonify=True)
58-
59-
def get_formula_id(self, title):
60-
"""Find a stack id"""
61-
62-
formulas = self.list_formulas()
63-
for formula in formulas:
64-
if formula.get("title") == title:
65-
return formula.get("id")
66-
67-
raise StackException("Formula %s not found" % title)
68-
69-
def get_component_id(self, formula, component_title):
70-
"""Get the id for a component from formula_id that matches title"""
71-
72-
for component in formula.get("components"):
73-
if component.get("title") == component_title:
74-
return component.get("id")
75-
76-
raise StackException("Component %s not found for formula %s" %
77-
(component_title, formula.get("title")))

stackdio/client/http.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,6 @@ def __init__(self, auth=None, verify=True):
122122
from requests.packages.urllib3 import disable_warnings
123123
disable_warnings()
124124

125-
126-
127125
def _request(self, verb, url, quiet=False,
128126
none_on_404=False, jsonify=False, raise_for_status=True,
129127
*args, **kwargs):

0 commit comments

Comments
 (0)