Skip to content

Commit 7423ee3

Browse files
committed
feat(controller):add drycc resource cmd improvement
1 parent fd50adf commit 7423ee3

8 files changed

Lines changed: 41 additions & 54 deletions

File tree

charts/controller/templates/controller-clusterrole.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ rules:
6767
verbs: ["get", "list", "watch", "create", "delete", "patch", "update"]
6868
- apiGroups: ["servicecatalog.k8s.io"]
6969
resources: ["serviceinstances"]
70-
verbs: ["get", "list", "watch", "create", "delete", "update"]
70+
verbs: ["get", "list", "watch", "create", "delete", "patch", "update"]
7171
- apiGroups: ["servicecatalog.k8s.io"]
72-
resources: ["serviceinstances"]
73-
verbs: ["get", "list", "watch", "create", "delete", "update"]
72+
resources: ["servicebindings"]
73+
verbs: ["get", "list", "watch", "create", "delete", "patch", "update"]
7474
{{- end -}}
7575
{{- end -}}

rootfs/api/models/resource.py

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ def attach(self, *args, **kwargs):
5858
self._scheduler.servicecatalog.create_instance(
5959
self.app.id, self.name, **kwargs
6060
)
61-
# create/patch/put retrieve_task
6261
data = {
6362
"task_id": uuid.uuid4().hex,
6463
"resource_id": str(self.uuid),
@@ -71,7 +70,7 @@ def attach(self, *args, **kwargs):
7170

7271
@transaction.atomic
7372
def delete(self, *args, **kwargs):
74-
if self.binding and self.binding == "Ready":
73+
if self.binding == "Ready":
7574
raise DryccException("the plan is still binding")
7675
# Deatch ServiceInstance, updates k8s
7776
self.detach(*args, **kwargs)
@@ -84,7 +83,7 @@ def detach(self, *args, **kwargs):
8483
self._scheduler.servicecatalog.get_instance(self.app.id, self.name)
8584
self._scheduler.servicecatalog.delete_instance(self.app.id, self.name)
8685
except KubeException as e:
87-
raise ServiceUnavailable("Could not delete volume {} for application {}".format(name, self.app_id)) from e # noqa
86+
raise ServiceUnavailable("Could not delete resource {} for application {}".format(self.name, self.app_id)) from e # noqa
8887

8988
def log(self, message, level=logging.INFO):
9089
"""Logs a message in the context of this service.
@@ -95,7 +94,7 @@ def log(self, message, level=logging.INFO):
9594
as "belonging" to the application instead of the controller and will be handled
9695
accordingly.
9796
"""
98-
logger.log(level, "[{}]: {}".format(self.id, message))
97+
logger.log(level, "[{}]: {}".format(self.uuid, message))
9998

10099
def bind(self, *args, **kwargs):
101100
if self.status != "Ready":
@@ -112,7 +111,6 @@ def bind(self, *args, **kwargs):
112111
try:
113112
self._scheduler.servicecatalog.create_binding(
114113
self.app.id, self.name, **kwargs)
115-
# create/patch/put retrieve_task
116114
data = {
117115
"task_id": uuid.uuid4().hex,
118116
"resource_id": str(self.uuid),
@@ -124,12 +122,15 @@ def bind(self, *args, **kwargs):
124122
raise ServiceUnavailable(msg) from e
125123

126124
def unbind(self, *args, **kwargs):
127-
if self.binding != "Ready":
125+
if not self.binding:
128126
raise DryccException("the resource is not binding")
129127
try:
130128
# We raise an exception when a resource doesn't exist
131129
self._scheduler.servicecatalog.get_binding(self.app.id, self.name)
132130
self._scheduler.servicecatalog.delete_binding(self.app.id, self.name)
131+
self.binding = None
132+
self.data = {}
133+
self.save()
133134
except KubeException as e:
134135
raise ServiceUnavailable("Could not unbind resource {} for application {}".format(self.name, self.app_id)) from e # noqa
135136

@@ -138,22 +139,19 @@ def attach_update(self, *args, **kwargs):
138139
data = self._scheduler.servicecatalog.get_instance(
139140
self.app.id, self.name).json()
140141
except KubeException as e:
141-
self.log("certificate {} does not exist".format(self.app.id),
142-
level=logging.INFO)
143-
data = None
144-
logger.info(e)
142+
self.DryccException("resource {} does not exist".format(self.name))
145143
try:
146144
version = data["metadata"]["resourceVersion"]
147145
instance = self.plan.split(":")
148146
kwargs = {
149147
"instance_class": instance[0],
150148
"instance_plan": ":".join(instance[1:]),
151149
"parameters": self.options,
150+
"external_id": data["spec"]["externalID"]
152151
}
153152
self._scheduler.servicecatalog.put_instance(
154153
self.app.id, self.name, version, **kwargs
155154
)
156-
# create/patch/put retrieve_task
157155
data = {
158156
"task_id": uuid.uuid4().hex,
159157
"resource_id": str(self.uuid),
@@ -171,7 +169,8 @@ def retrieve(self, *args, **kwargs):
171169
resp_i = self._scheduler.servicecatalog.get_instance(
172170
self.app.id, self.name).json()
173171
self.status = resp_i.get('status', {}).\
174-
get('lastConditionState', '').lower()
172+
get('lastConditionState')
173+
self.options = resp_i.get('spec', {}).get('parameters', {})
175174
update_flag = True
176175
except KubeException as e:
177176
logger.info("retrieve instance info error: {}".format(e))
@@ -181,8 +180,7 @@ def retrieve(self, *args, **kwargs):
181180
resp_b = self._scheduler.servicecatalog.get_binding(
182181
self.app.id, self.name).json()
183182
self.binding = resp_b.get('status', {}).\
184-
get('lastConditionState', '').lower()
185-
self.options = resp_b.get('spec', {}).get('parameters', {})
183+
get('lastConditionState')
186184
update_flag = True
187185
secret_name = resp_b.get('spec', {}).get('secretName')
188186
if secret_name:
@@ -194,7 +192,7 @@ def retrieve(self, *args, **kwargs):
194192
logger.info("retrieve binding info error: {}".format(e))
195193
if update_flag is True:
196194
self.save()
197-
if self.status and self.binding:
195+
if self.status == "Ready" and self.binding == "Ready":
198196
return True
199197
else:
200198
return False
@@ -213,12 +211,8 @@ def detach_resource(self, *args, **kwargs):
213211
logger.info("delete binding info error: {}".format(e))
214212
self.binding = None
215213

216-
if (self.status != "Ready") or (self.binding is None):
217-
try:
218-
self._scheduler.servicecatalog.delete_instance(
219-
self.app.id, self.name)
220-
except KubeException as e:
221-
logger.info("retrieve instance info error: {}".format(e))
214+
if (self.status != "Ready") or (not self.binding):
215+
self.delete()
222216

223217

224218
@task
@@ -234,7 +228,7 @@ def retrieve_task(data):
234228
if _:
235229
return True
236230
else:
237-
t = time.time() - resource.created.timestamps()
231+
t = time.time() - resource.created.timestamp()
238232
if t < 3600:
239233
apply_async(retrieve_task, delay=30000, args=(data, ))
240234
elif t < 3600 * 12:

rootfs/api/serializers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ class ResourceSerializer(serializers.ModelSerializer):
659659
owner = serializers.ReadOnlyField(source='owner.username')
660660
name = serializers.CharField(max_length=63, required=True)
661661
plan = serializers.CharField(max_length=128, required=True)
662+
data = JSONFieldSerializer(required=False, binary=True)
662663
options = JSONFieldSerializer(required=False, binary=True)
663664

664665
class Meta:
@@ -670,8 +671,7 @@ def update(self, instance, validated_data):
670671
if instance.plan.split(':')[0] != validated_data.get('plan', '').split(':')[0]: # noqa
671672
raise DryccException("the resource cann't changed")
672673
instance.plan = validated_data.get('plan')
673-
if validated_data.get('options'):
674-
instance.options = validated_data.get('options')
674+
instance.options = validated_data.get('options')
675675
instance.attach_update()
676676
instance.save()
677677
return instance

rootfs/api/tests/test_resource.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,6 @@ def test_resource_delete(self, mock_requests):
102102
response = self.client.delete(url)
103103
self.assertEqual(response.status_code, 204)
104104

105-
def test_resource_update(self, mock_requests):
106-
"""
107-
Test that resource is delete from a app
108-
"""
109-
# create
110-
app_id = self.create_app()
111-
data = {'name': 'mysql', 'plan': 'mysql:5.6'}
112-
self.client.post('/v2/apps/{}/resources'.format(app_id), data=data)
113-
114-
# Update
115-
url = '/v2/apps/{app_id}/resources/{name}'.format(app_id=app_id,
116-
name='mysql')
117-
data = {'plan': 'mysql:5.7'}
118-
response = self.client.put(url, data=data)
119-
self.assertEqual(response.status_code, 200)
120-
121105
def test_resource_bind(self, mock_requests):
122106
# create
123107
app_id = self.create_app()

rootfs/api/views.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -792,10 +792,14 @@ def binding(self, request, *args, **kwargs):
792792
bind_action = self.request.data.get('bind_action', '').lower()
793793
if bind_action == 'bind':
794794
resource.bind()
795-
return HttpResponse(status=status.HTTP_202_ACCEPTED)
795+
serializer = self.get_serializer(resource, many=False)
796+
logger.info("resoruce bind response data: {}".format(serializer))
797+
return Response(serializer.data)
796798
elif bind_action == 'unbind':
797799
resource.unbind()
798-
return HttpResponse(status=status.HTTP_202_ACCEPTED)
800+
serializer = self.get_serializer(resource, many=False)
801+
logger.info("resoruce unbind response data: {}".format(serializer))
802+
return Response(serializer.data)
799803
else:
800804
return Http404("unknown action")
801805

rootfs/scheduler/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,11 @@ def http_patch(self, path, data=None, **kwargs):
221221
"""
222222
try:
223223
url = urljoin(self.url, path)
224+
# accepted media types include:
225+
# application/json-patch+json,
226+
# application/merge-patch+json,
227+
# application/apply-patch+yaml
228+
# self.session.headers["Content-Type"] = "application/json-patch+json"
224229
response = self.session.patch(url, data=data, **kwargs)
225230
except requests.exceptions.ConnectionError as err:
226231
# reraise as KubeException, but log stacktrace.

rootfs/scheduler/resources/servicecatalog.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import logging
12
from scheduler.resources import Resource
23
from scheduler.exceptions import KubeHTTPException
34

5+
logger = logging.getLogger(__name__)
6+
47

58
class ServiceCatalog(Resource):
69
api_version = 'servicecatalog.k8s.io/v1beta1'
@@ -22,12 +25,14 @@ def service_instance_manifest(namespace, name, version=None, **kwargs):
2225
"spec": {
2326
"clusterServiceClassExternalName": kwargs.get('instance_class'),
2427
"clusterServicePlanExternalName": kwargs.get('instance_plan'),
25-
#{"param - 1": "value - 1","param - 2": "value - 2"} # noqa
26-
"parameters": kwargs.get('parameters'),
2728
}
2829
}
2930
if version:
3031
data["metadata"]["resourceVersion"] = version
32+
if kwargs.get('parameters'):
33+
data["spec"]["parameters"] = kwargs.get('parameters')
34+
if kwargs.get('external_id'):
35+
data["spec"]["externalID"] = kwargs.get('external_id')
3136
return data
3237

3338
def get_instance(self, namespace, name=None):
@@ -52,6 +57,7 @@ def create_instance(self, namespace, name, **kwargs):
5257
"""
5358
url = self.api('/namespaces/{}/serviceinstances', namespace)
5459
data = self.service_instance_manifest(namespace, name, **kwargs)
60+
logging.info("create_instance_data:{}".format(data))
5561
response = self.http_post(url, json=data)
5662
if not response.status_code == 201:
5763
raise KubeHTTPException(
@@ -65,6 +71,7 @@ def put_instance(self, namespace, name, version, **kwargs):
6571
"""
6672
url = self.api('/namespaces/{}/serviceinstances/{}', namespace, name)
6773
data = self.service_instance_manifest(namespace, name, version, **kwargs)
74+
logger.info("put_instance data:{}".format(data))
6875
response = self.http_put(url, json=data)
6976
if not response.status_code == 200:
7077
raise KubeHTTPException(

rootfs/scheduler/tests/test_servicecatalog.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,6 @@ def test_create_binding(self):
101101
self.scheduler.ns.create("test-serviceinstance")
102102
self.create_binding(namespace="test-serviceinstance")
103103

104-
# def test_create_binding_failure(self):
105-
# with self.assertRaises(
106-
# KubeHTTPException,
107-
# msg='failed to create servicebindings doesnotexist in Namespace {}: 404 Not Found'.format(self.namespace) # noqa
108-
# ):
109-
# self.create_binding(self.namespace, 'doesnotexist')
110-
111104
def test_binding_delete(self):
112105
# test success
113106
name = self.create_binding(namespace="test-serviceinstance")

0 commit comments

Comments
 (0)