Add fake_keystone class

This class encapsulates a simple fake_keystone API to help
satisfy some internal heat Keystone requirements. The goal
is to use this alongside the new undercloud deployment commands
to help execute an all-in-one heat-all process to drive
deployment of the Undercloud with Heat.

Change-Id: I291ffb13e0ba1709d48c64a5ccd5277853984f16
This commit is contained in:
Dan Prince 2017-01-31 21:30:59 -05:00
parent b999d83100
commit 7a8cad1e56

View File

@ -0,0 +1,224 @@
# Copyright 2016 Red Hat, Inc.
#
# 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 BaseHTTPServer
import datetime
import json
import logging
import os
from oslo_utils import timeutils
TOMORROW = timeutils.isotime(at=(timeutils.utcnow()
+ datetime.timedelta(days=1)))
VERSION_RESPONSE_GET = {
"version": {
"status": "stable",
"updated": timeutils.isotime(),
"media-types": [{
"base": "application/json",
"type": "application/vnd.openstack.identity-v3+json"
}],
"id": "v3.6",
"links": [{
"href": "http://127.0.0.1:%(api_port)s/v3/",
"rel": "self"
}]
}
}
TOKEN_RESPONSE_POST = {
"token": {
"is_domain": False,
"methods": ["password"],
"roles": [{
"id": "4c8de39b96794ab28bf37a0b842b8bc8",
"name": "admin"
}],
"expires_at": TOMORROW,
"project": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "admin",
"name": "admin"
},
"catalog": [{
"endpoints": [{
"url": "http://127.0.0.1:%(heat_port)s/v1/admin",
"interface": "public",
"region": "regionOne",
"region_id": "regionOne",
"id": "2809305628004fb391b3d0254fb5b4f7"
}, {
"url": "http://127.0.0.1:%(heat_port)s/v1/admin",
"interface": "internal",
"region": "regionOne",
"region_id": "regionOne",
"id": "2809305628004fb391b3d0254fb5b4f7"
}, {
"url": "http://127.0.0.1:%(heat_port)s/v1/admin",
"interface": "admin",
"region": "regionOne",
"region_id": "regionOne",
"id": "2809305628004fb391b3d0254fb5b4f7"
}],
"type": "orchestration",
"id": "96a549e3961d45cabe883dd17c5835be",
"name": "heat"
}, {
"endpoints": [{
"url": "http://127.0.0.1:%(api_port)s/v3",
"interface": "public",
"region": "regionOne",
"region_id": "regionOne",
"id": "eca215878e404a2d9dcbcc7f6a027165"
}, {
"url": "http://127.0.0.1:%(api_port)s/v3",
"interface": "internal",
"region": "regionOne",
"region_id": "regionOne",
"id": "eca215878e404a2d9dcbcc7f6a027165"
}, {
"url": "http://127.0.0.1:%(api_port)s/v3",
"interface": "admin",
"region": "regionOne",
"region_id": "regionOne",
"id": "eca215878e404a2d9dcbcc7f6a027165"
}],
"type": "identity",
"id": "a785f0b7603042d1bf59237c71af2f15",
"name": "keystone"
}],
"user": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "8b7b4c094f934e8c83aa7fe12591dc6c",
"name": "admin"
},
"audit_ids": ["F6ONJ8fCT6i_CFTbmC0vBA"],
"issued_at": timeutils.isotime()
}
}
STACK_USER_ROLE_GET = {
"links": {
"self": "http://127.0.0.1:%(api_port)s/v3/roles",
"previous": None,
"next": None
},
"roles": [{
"domain_id": None,
"id": "b123456",
"links": {
"self": "http://127.0.0.1:%(api_port)s/v3/roles/b123456"
},
"name": "heat_stack_user"
}]
}
STACK_USER_POST = {
"user": {
"name": "heat_stack_user",
"links": {
"self": "http://127.0.0.1:%(api_port)s/v3/users/c123456"
},
"domain_id": "default",
"enabled": True,
"email": "heat@localhost",
"id": "c123456"
}
}
AUTH_TOKEN_GET = {
"token": {
"issued_at": timeutils.isotime(),
"audit_ids": ["PUrztDYYRBeq-C8CKr-kEw"],
"methods": ["password"],
"expires_at": TOMORROW,
"user": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "8b7b4c094f934e8c83aa7fe12591dc6c",
"name": "admin"
}
}
}
class FakeKeystone(BaseHTTPServer.BaseHTTPRequestHandler):
log = logging.getLogger(__name__ + ".FakeKeystone")
def _get_port_from_env(self):
return os.environ.get('FAKE_KEYSTONE_PORT', '35358')
def _get_heat_port_from_env(self):
return os.environ.get('HEAT_API_PORT', '8006')
def _format(self, my_json):
return (json.dumps(my_json) % {'api_port': self._get_port_from_env(),
'heat_port': self._get_heat_port_from_env()})
def _send_headers(self, code=200):
self.send_response(code)
self.send_header('Content-type', 'application/json')
self.send_header('X-Auth-User', 'admin')
self.send_header('X-Subject-Token', '123456789')
self.end_headers()
def do_GET(self):
if self.path in ['/', '/v3', '/v3/']:
self._send_headers(300)
self.wfile.write(self._format(VERSION_RESPONSE_GET))
elif self.path == '/v3/auth/tokens':
self._send_headers(200)
self.wfile.write(self._format(AUTH_TOKEN_GET))
elif self.path.startswith('/v3/roles?name=heat_stack_user'):
self._send_headers()
self.wfile.write(self._format(STACK_USER_ROLE_GET))
else:
raise Exception('Not Implemented: %s' % self.path)
def do_POST(self):
if self.path == '/v3/auth/tokens':
self._send_headers(201)
self.wfile.write(self._format(TOKEN_RESPONSE_POST))
elif self.path == '/v3/users':
self._send_headers()
self.wfile.write(self._format(STACK_USER_POST))
else:
raise Exception('Not Implemented: %s' % self.path)
def do_PUT(self):
if self.path.startswith('/v3/projects/admin/users/'):
self._send_headers()
pass # NOTE: 200 response is good enough here
else:
raise Exception('Not Implemented: %s' % self.path)
def log_message(self, format, *args):
return
def launch():
port = os.environ.get('FAKE_KEYSTONE_PORT', '35358')
httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', int(port)), FakeKeystone)
httpd.serve_forever()