Javascript Heat API

This patch adds the start of a Javascript Heat API similar
to the rest of the existing OpenStack ones. The app-catalog
needs this to check if a given template will work on a
specific cloud.

Change-Id: I5c245614f747ade8a91a6ac73ca39c6f99ab54bf
Partial-Bug: 1481518
This commit is contained in:
Kevin Fox 2015-08-24 15:11:26 -07:00
parent 7f69f3f2cf
commit bc9e63bafc
5 changed files with 197 additions and 0 deletions

View File

@ -25,6 +25,7 @@ in https://wiki.openstack.org/wiki/APIChangeGuidelines.
from . import cinder #flake8: noqa
from . import config #flake8: noqa
from . import glance #flake8: noqa
from . import heat #flake8: noqa
from . import keystone #flake8: noqa
from . import network #flake8: noqa
from . import neutron #flake8: noqa

View File

@ -0,0 +1,39 @@
# Licensed 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.
"""API for the heat service.
"""
from django.views import generic
from openstack_dashboard import api
from openstack_dashboard.api.rest import urls
from openstack_dashboard.api.rest import utils as rest_utils
@urls.register
class Validate(generic.View):
"""API for validating a template
"""
url_regex = r'heat/validate/$'
@rest_utils.ajax()
def post(self, request):
"""Validate a template
The following parameters may be passed in the POST
application/json object. The parameters are:
request:
:param template_url: The template to validate
"""
return api.heat.template_validate(request, **(request.DATA))

View File

@ -0,0 +1,61 @@
/*
* Licensed 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.
*/
(function () {
'use strict';
angular
.module('horizon.app.core.openstack-service-api')
.service('horizon.app.core.openstack-service-api.heat', HeatAPI);
HeatAPI.$inject = [
'horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'
];
/**
* @ngdoc service
* @name horizon.app.core.openstack-service-api.heat
* @description Provides direct pass through to Heat with NO abstraction.
*/
function HeatAPI(apiService, toastService) {
var service = {
validate: validate
};
return service;
/**
* @name horizon.app.core.openstack-service-api.heat.validate
* @description
* Validate a template.
*
* The result is an object.
*
* @param {string} params.template_url
* Specifies the template to validate.
*
* @param {boolean} suppressError
* If passed in, this will not show the default error handling
* (horizon alert).
*/
function validate(params, suppressError) {
var promise = apiService.post('/api/heat/validate/', params);
return suppressError ? promise : promise.error(function() {
toastService.add('error', gettext('Unable to validate the template.'));
});
}
}
}());

View File

@ -0,0 +1,67 @@
/*
* Licensed 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.
*/
(function() {
'use strict';
describe('Heat API', function() {
var testCall, service;
var apiService = {};
var toastService = {};
beforeEach(
module('horizon.mock.openstack-service-api',
function($provide, initServices) {
testCall = initServices($provide, apiService, toastService);
})
);
beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(inject(['horizon.app.core.openstack-service-api.heat', function(heatAPI) {
service = heatAPI;
}]));
it('defines the service', function() {
expect(service).toBeDefined();
});
var tests = [
{
'func': 'validate',
'method': 'post',
'path': '/api/heat/validate/',
'data': {
'template_url':'http://localhost/test.template'
},
'error': 'Unable to validate the template.',
'testInput': [
{
'template_url':'http://localhost/test.template'
}
]
}
];
// Iterate through the defined tests and apply as Jasmine specs.
angular.forEach(tests, function(params) {
it('defines the ' + params.func + ' call properly', function() {
var callParams = [apiService, service, toastService, params];
testCall.apply(this, callParams);
});
});
});
})();

View File

@ -0,0 +1,29 @@
# Licensed 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.
import json
import mock
from openstack_dashboard.api.rest import heat
from openstack_dashboard.test import helpers as test
class ValidateRestTestCase(test.TestCase):
@mock.patch.object(heat.api, 'heat')
def test_validate_post(self, hc):
body = '''{"template_url":"http://localhost/template.yaml"}'''
request = self.mock_rest_request(body=body)
hc.template_validate.return_value = ({'Description': 'foo'})
response = heat.Validate().post(request)
self.assertStatusCode(response, 200)
self.assertEqual(response.content, '{"Description": "foo"}')
kwargs = json.loads(body)
hc.template_validate.assert_called_once_with(request, **kwargs)