Browse Source

Merge "Fix flavor profile API handling of None updates" into stable/stein

changes/53/679753/1
Zuul 3 weeks ago
parent
commit
1126b44a8d

+ 19
- 7
octavia/api/v2/controllers/flavor_profiles.py View File

@@ -111,6 +111,24 @@ class FlavorProfileController(base.BaseController):
111 111
             db_flavor_profile, profile_types.FlavorProfileResponse)
112 112
         return profile_types.FlavorProfileRootResponse(flavorprofile=result)
113 113
 
114
+    def _validate_update_fp(self, context, id, flavorprofile):
115
+        if flavorprofile.name is None:
116
+            raise exceptions.InvalidOption(value=None, option=constants.NAME)
117
+        if flavorprofile.provider_name is None:
118
+            raise exceptions.InvalidOption(value=None,
119
+                                           option=constants.PROVIDER_NAME)
120
+        if flavorprofile.flavor_data is None:
121
+            raise exceptions.InvalidOption(value=None,
122
+                                           option=constants.FLAVOR_DATA)
123
+
124
+        # Don't allow changes to the flavor_data or provider_name if it
125
+        # is in use.
126
+        if (not isinstance(flavorprofile.flavor_data, wtypes.UnsetType) or
127
+                not isinstance(flavorprofile.provider_name, wtypes.UnsetType)):
128
+            if self.repositories.flavor.count(context.session,
129
+                                              flavor_profile_id=id) > 0:
130
+                raise exceptions.ObjectInUse(object='Flavor profile', id=id)
131
+
114 132
     @wsme_pecan.wsexpose(profile_types.FlavorProfileRootResponse,
115 133
                          wtypes.text, status_code=200,
116 134
                          body=profile_types.FlavorProfileRootPUT)
@@ -121,13 +139,7 @@ class FlavorProfileController(base.BaseController):
121 139
         self._auth_validate_action(context, context.project_id,
122 140
                                    constants.RBAC_PUT)
123 141
 
124
-        # Don't allow changes to the flavor_data or provider_name if it
125
-        # is in use.
126
-        if (not isinstance(flavorprofile.flavor_data, wtypes.UnsetType) or
127
-                not isinstance(flavorprofile.provider_name, wtypes.UnsetType)):
128
-            if self.repositories.flavor.count(context.session,
129
-                                              flavor_profile_id=id) > 0:
130
-                raise exceptions.ObjectInUse(object='Flavor profile', id=id)
142
+        self._validate_update_fp(context, id, flavorprofile)
131 143
 
132 144
         if not isinstance(flavorprofile.flavor_data, wtypes.UnsetType):
133 145
             # Do a basic JSON validation on the metadata

+ 2
- 0
octavia/common/constants.py View File

@@ -340,6 +340,8 @@ BYTES_IN = 'bytes_in'
340 340
 BYTES_OUT = 'bytes_out'
341 341
 REQUEST_ERRORS = 'request_errors'
342 342
 TOTAL_CONNECTIONS = 'total_connections'
343
+NAME = 'name'
344
+PROVIDER_NAME = 'provider_name'
343 345
 
344 346
 CERT_ROTATE_AMPHORA_FLOW = 'octavia-cert-rotate-amphora-flow'
345 347
 CREATE_AMPHORA_FLOW = 'octavia-create-amphora-flow'

+ 20
- 1
octavia/tests/functional/api/v2/test_flavor_profiles.py View File

@@ -328,7 +328,7 @@ class TestFlavorProfiles(base.BaseAPITest):
328 328
         self.assertEqual('{"hello": "world"}',
329 329
                          response.get(constants.FLAVOR_DATA))
330 330
 
331
-    def test_update_none(self):
331
+    def test_update_nothing(self):
332 332
         fp = self.create_flavor_profile('test_profile', 'noop_driver',
333 333
                                         '{"x": "y"}')
334 334
         body = self._build_body({})
@@ -340,6 +340,25 @@ class TestFlavorProfiles(base.BaseAPITest):
340 340
         self.assertEqual('{"x": "y"}',
341 341
                          response.get(constants.FLAVOR_DATA))
342 342
 
343
+    def test_update_name_none(self):
344
+        self._test_update_param_none(constants.NAME)
345
+
346
+    def test_update_provider_name_none(self):
347
+        self._test_update_param_none(constants.PROVIDER_NAME)
348
+
349
+    def test_update_flavor_data_none(self):
350
+        self._test_update_param_none(constants.FLAVOR_DATA)
351
+
352
+    def _test_update_param_none(self, param_name):
353
+        fp = self.create_flavor_profile('test_profile', 'noop_driver',
354
+                                        '{"x": "y"}')
355
+        expect_error_msg = ("None is not a valid option for %s" %
356
+                            param_name)
357
+        body = self._build_body({param_name: None})
358
+        response = self.put(self.FP_PATH.format(fp_id=fp.get('id')), body,
359
+                            status=400)
360
+        self.assertEqual(expect_error_msg, response.json['faultstring'])
361
+
343 362
     def test_update_no_flavor_data(self):
344 363
         fp = self.create_flavor_profile('test_profile', 'noop_driver',
345 364
                                         '{"x": "y"}')

+ 6
- 0
releasenotes/notes/Fix-API-update-null-None-1b400962017a3d56.yaml View File

@@ -0,0 +1,6 @@
1
+---
2
+fixes:
3
+  - |
4
+    Fixed the API handling of None (JSON null) on object update calls. The
5
+    API will now either clear the value from the field or will reset the value
6
+    of the field to the API default.

Loading…
Cancel
Save