Skip to content

Commit 3e2c19e

Browse files
committed
Merge pull request #7 from clarkperkins/feature/fixes-for-cli
Fixes for the CLI
2 parents f2a7f43 + 7d69f39 commit 3e2c19e

File tree

10 files changed

+123
-47
lines changed

10 files changed

+123
-47
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,6 @@ docs/_build/
5252

5353
# PyBuilder
5454
target/
55+
56+
# PyCharm
57+
.idea/

stackdio/client/__init__.py

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

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

2424
from .blueprint import BlueprintMixin
2525
from .formula import FormulaMixin
@@ -57,12 +57,15 @@ def __init__(self, protocol="https", host="localhost", port=443,
5757

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

60+
@endpoint("")
61+
def get_root(self):
62+
"""Get the api root"""
63+
return self._get(endpoint, jsonify=True)
6064

6165
@endpoint("version/")
6266
def get_version(self):
6367
return self._get(endpoint, jsonify=True)['version']
6468

65-
6669
@use_admin_auth
6770
@endpoint("security_groups/")
6871
def create_security_group(self, name, description, cloud_provider, is_default=True):
@@ -76,6 +79,25 @@ def create_security_group(self, name, description, cloud_provider, is_default=Tr
7679
}
7780
return self._post(endpoint, data=json.dumps(data), jsonify=True)
7881

82+
@endpoint("settings/")
83+
def get_public_key(self):
84+
"""Get the public key for the logged in uesr"""
85+
return self._get(endpoint, jsonify=True)['public_key']
86+
87+
@endpoint("settings/")
88+
def set_public_key(self, public_key):
89+
"""Upload a public key for our user. public_key can be the actual key, a
90+
file handle, or a path to a key file"""
91+
92+
if isinstance(public_key, file):
93+
public_key = public_key.read()
94+
elif isinstance(public_key, str) and os.path.exists(public_key):
95+
public_key = open(public_key, "r").read()
96+
97+
data = {
98+
"public_key": public_key
99+
}
100+
return self._put(endpoint, data=json.dumps(data), jsonify=True)
79101

80102
@endpoint("instance_sizes/")
81103
def get_instance_id(self, instance_id, provider_type="ec2"):

stackdio/client/blueprint.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,42 +30,43 @@ def create_blueprint(self, blueprint, provider="ec2"):
3030

3131
# check the provided blueprint to see if we need to look up any ids
3232
for host in blueprint["hosts"]:
33-
if isinstance(host["size"], str):
33+
if isinstance(host["size"], basestring):
3434
host["size"] = self.get_instance_id(host["size"], provider)
3535

36-
if isinstance(host["zone"], str):
37-
host["zone"] = self.get_zone(host["zone"], provider)
36+
if isinstance(host["zone"], basestring):
37+
host["zone"] = self.get_zone_id(host["zone"], provider)
3838

39-
if isinstance(host["cloud_profile"], str):
40-
host["cloud_profile"] = self.get_profile_id(host["cloud_profile"])
39+
if isinstance(host["cloud_profile"], basestring):
40+
host["cloud_profile"] = self.get_profile_id(host["cloud_profile"], title=True)
4141

4242
for component in host["formula_components"]:
4343
if isinstance(component["id"], (tuple, list)):
44+
formula_id = self.get_formula_id(component["id"][0])
45+
4446
component["id"] = self.get_component_id(
45-
self.get_formula(component["id"][0]),
47+
self.get_formula(formula_id),
4648
component["id"][1])
4749

4850
return self._post(endpoint, data=json.dumps(blueprint), jsonify=True)
4951

50-
51-
5252
@endpoint("blueprints/")
5353
def list_blueprints(self):
5454
"""Return info for a specific blueprint_id"""
5555
return self._get(endpoint, jsonify=True)['results']
5656

57-
5857
@endpoint("blueprints/{blueprint_id}/")
5958
def get_blueprint(self, blueprint_id):
6059
"""Return info for a specific blueprint_id"""
6160
return self._get(endpoint, jsonify=True)
6261

63-
6462
@endpoint("blueprints/")
6563
def search_blueprints(self, **kwargs):
6664
"""Return info for a specific blueprint_id"""
6765
return self._get(endpoint, params=kwargs, jsonify=True)['results']
6866

67+
@endpoint("blueprints/{blueprint_id}")
68+
def delete_blueprint(self, blueprint_id):
69+
return self._delete(endpoint, jsonify=True)
6970

7071
@deprecated
7172
@accepted_versions("<0.7")

stackdio/client/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ class StackException(Exception):
1919
pass
2020

2121

22+
class BlueprintException(Exception):
23+
pass
24+
25+
2226
class NoAdminException(Exception):
2327
pass
2428

stackdio/client/formula.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323

2424
class FormulaMixin(HttpMixin):
25-
2625
@endpoint("formulas/")
2726
def import_formula(self, formula_uri, public=True):
2827
"""Import a formula"""
@@ -32,36 +31,40 @@ def import_formula(self, formula_uri, public=True):
3231
}
3332
return self._post(endpoint, data=json.dumps(data), jsonify=True)
3433

35-
3634
@endpoint("formulas/")
3735
def list_formulas(self):
3836
"""Return all formulas"""
3937
return self._get(endpoint, jsonify=True)['results']
4038

41-
4239
@endpoint("formulas/{formula_id}/")
4340
def get_formula(self, formula_id):
4441
"""Get a formula with matching id"""
4542
return self._get(endpoint, jsonify=True)
4643

47-
4844
@endpoint("formulas/")
4945
def search_formulas(self, **kwargs):
5046
"""Get a formula with matching id"""
5147
return self._get(endpoint, params=kwargs, jsonify=True)['results']
5248

53-
5449
@endpoint("formulas/{formula_id}/")
5550
def delete_formula(self, formula_id):
5651
"""Delete formula with matching id"""
5752
return self._delete(endpoint, jsonify=True)
5853

59-
6054
@endpoint("formulas/{formula_id}/action/")
6155
def update_formula(self, formula_id):
6256
"""Delete formula with matching id"""
6357
return self._post(endpoint, json.dumps({"action": "update"}), jsonify=True)
6458

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)
6568

6669
def get_component_id(self, formula, component_title):
6770
"""Get the id for a component from formula_id that matches title"""

stackdio/client/http.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ class HttpMixin(object):
100100
}
101101

102102
def __init__(self, auth=None, verify=True):
103-
self._http_options = {}
104-
self._http_options['auth'] = auth
105-
self._http_options['verify'] = verify
103+
self._http_options = {
104+
'auth': auth,
105+
'verify': verify,
106+
}
106107
self._http_log = logging.getLogger(__name__)
107108

108-
109109
def _request(self, verb, url, quiet=False,
110110
none_on_404=False, jsonify=False, raise_for_status=True,
111111
*args, **kwargs):
@@ -114,17 +114,20 @@ def _request(self, verb, url, quiet=False,
114114
self._http_log.info("{0}: {1}".format(verb, url))
115115

116116
headers = kwargs.get('headers', HttpMixin.HEADERS['json'])
117+
117118
result = requests.request(verb, url,
118119
auth=self._http_options['auth'],
119120
headers=headers,
120121
verify=self._http_options['verify'],
121122
*args, **kwargs)
122123

123-
124124
# Handle special conditions
125125
if none_on_404 and result.status_code == 404:
126126
return None
127127

128+
elif result.status_code == 204:
129+
return None
130+
128131
elif raise_for_status:
129132
try:
130133
result.raise_for_status()
@@ -138,26 +141,20 @@ def _request(self, verb, url, quiet=False,
138141
else:
139142
return result
140143

141-
142144
def _head(self, url, *args, **kwargs):
143145
return self._request("HEAD", url, *args, **kwargs)
144146

145-
146147
def _get(self, url, *args, **kwargs):
147148
return self._request("GET", url, *args, **kwargs)
148149

149-
150150
def _delete(self, url, *args, **kwargs):
151151
return self._request("DELETE", url, *args, **kwargs)
152152

153-
154153
def _post(self, url, data=None, *args, **kwargs):
155154
return self._request("POST", url, data=data, *args, **kwargs)
156155

157-
158156
def _put(self, url, data=None, *args, **kwargs):
159157
return self._request("PUT", url, data=data, *args, **kwargs)
160158

161-
162159
def _patch(self, url, data=None, *args, **kwargs):
163160
return self._request("PATCH", url, data=data, *args, **kwargs)

stackdio/client/profile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,4 @@ def get_profile_id(self, slug, title=False):
7575
if profile.get("slug" if not title else "title") == slug:
7676
return profile.get("id")
7777

78-
return StackException("Provider %s not found" % slug)
78+
return StackException("Profile %s not found" % slug)

stackdio/client/provider.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def create_provider(self, **kwargs):
7676

7777

7878
@endpoint("providers/")
79-
def list_providers(self, provider_id):
79+
def list_providers(self):
8080
"""List all providers"""
8181
return self._get(endpoint, jsonify=True)['results']
8282

stackdio/client/region.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,12 @@ def get_zone_id(self, title, type_name="ec2"):
7272
"""Get a zone id for title"""
7373

7474
result = self._get(endpoint, jsonify=True)
75+
76+
type_id = self.get_provider_type_id(type_name)
7577
for zone in result['results']:
76-
if zone.get("title") == title and \
77-
zone.get("provider_type") == type_name:
78-
return zone.get("id")
78+
if zone.get("title") == title:
79+
region = self._get(zone.get("region"), jsonify=True)
80+
if region.get("provider_type") == type_id:
81+
return zone.get("id")
7982

8083
raise StackException("Zone %s not found for %s" % (title, type_name))

0 commit comments

Comments
 (0)