22e6df0870
This change adds the site_type parameter in deployment_data The value will be taken from respective site-definition.yaml Change-Id: I8e65b39c73c94caf3ed4cc517520b9577160b20d
178 lines
6.9 KiB
Python
178 lines
6.9 KiB
Python
# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
|
|
#
|
|
# 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 logging
|
|
import uuid
|
|
|
|
from shipyard_client.api_client.shipyard_api_client import ShipyardClient
|
|
from shipyard_client.api_client.shipyardclient_context import \
|
|
ShipyardClientContext
|
|
import yaml
|
|
|
|
from pegleg.engine import exceptions
|
|
from pegleg.engine import site
|
|
from pegleg.engine.util import files
|
|
from pegleg.engine.util.files import add_representer_ordered_dict
|
|
from pegleg.engine.util.pegleg_secret_management import PeglegSecretManagement
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class AuthValuesError(exceptions.PeglegBaseException):
|
|
"""Shipyard authentication failed. """
|
|
def __init__(self, *, diagnostic):
|
|
self.diagnostic = diagnostic
|
|
|
|
|
|
class DocumentUploadError(exceptions.PeglegBaseException):
|
|
"""Exception occurs while uploading documents"""
|
|
def __init__(self, message):
|
|
self.message = message
|
|
|
|
|
|
class ShipyardHelper(object):
|
|
"""
|
|
A helper class for Shipyard. It performs the following operation:
|
|
1. Validates the authentication parameters required for Keystone
|
|
2. Uploads the document to Shipyard buffer
|
|
3. Commits the document
|
|
4. Formats response from Shipyard api_client
|
|
"""
|
|
def __init__(self, context, buffer_mode='replace'):
|
|
"""
|
|
Initializes params to be used by Shipyard
|
|
|
|
:param context: ShipyardHelper context object that contains
|
|
params for initializing ShipyardClient with
|
|
correct client context and the site_name.
|
|
"""
|
|
self.ctx = context
|
|
self.api_parameters = self.ctx.obj['API_PARAMETERS']
|
|
self.auth_vars = self.api_parameters.get('auth_vars')
|
|
self.context_marker = self.ctx.obj['context_marker']
|
|
if self.context_marker is None:
|
|
self.context_marker = str(uuid.uuid4())
|
|
LOG.debug("context_marker is %s", self.context_marker)
|
|
self.site_name = self.ctx.obj['site_name']
|
|
self.client_context = ShipyardClientContext(
|
|
self.auth_vars, self.context_marker)
|
|
self.api_client = ShipyardClient(self.client_context)
|
|
self.buffer_mode = buffer_mode
|
|
self.collection = self.ctx.obj.get('collection', self.site_name)
|
|
|
|
def upload_documents(self):
|
|
"""Uploads documents to Shipyard"""
|
|
|
|
collected_documents = files.collect_files_by_repo(self.site_name)
|
|
|
|
collection_data = [site.get_deployment_data_doc(self.site_name)]
|
|
LOG.info("Processing %d collection(s)", len(collected_documents))
|
|
for idx, document in enumerate(collected_documents):
|
|
# Decrypt the documents if encrypted
|
|
pegleg_secret_mgmt = PeglegSecretManagement(
|
|
docs=collected_documents[document])
|
|
decrypted_documents = pegleg_secret_mgmt.get_decrypted_secrets()
|
|
collection_data.extend(decrypted_documents)
|
|
add_representer_ordered_dict()
|
|
collection_as_yaml = yaml.dump_all(
|
|
collection_data, Dumper=yaml.SafeDumper)
|
|
|
|
# Append flag is not required for the first
|
|
# collection being uploaded to Shipyard. It
|
|
# is needed for subsequent collections.
|
|
if self.buffer_mode in ['append', 'replace']:
|
|
buffer_mode = self.buffer_mode
|
|
else:
|
|
raise exceptions.InvalidBufferModeException()
|
|
|
|
try:
|
|
self.validate_auth_vars()
|
|
resp_text = self.api_client.post_configdocs(
|
|
collection_id=self.collection,
|
|
buffer_mode=buffer_mode,
|
|
document_data=collection_as_yaml)
|
|
|
|
except AuthValuesError as ave:
|
|
resp_text = "Error: {}".format(ave.diagnostic)
|
|
raise DocumentUploadError(resp_text)
|
|
except Exception as ex:
|
|
resp_text = (
|
|
"Error: Unable to invoke action due to: {}".format(str(ex)))
|
|
LOG.debug(resp_text, exc_info=True)
|
|
raise DocumentUploadError(resp_text)
|
|
|
|
# FIXME: Standardize status_code in Deckhand to avoid this
|
|
# workaround.
|
|
code = 0
|
|
if hasattr(resp_text, 'status_code'):
|
|
code = resp_text.status_code
|
|
elif hasattr(resp_text, 'code'):
|
|
code = resp_text.code
|
|
if code >= 400:
|
|
if hasattr(resp_text, 'content'):
|
|
raise DocumentUploadError(resp_text.content)
|
|
else:
|
|
raise DocumentUploadError(resp_text)
|
|
else:
|
|
output = self.formatted_response_handler(resp_text)
|
|
LOG.info("Uploaded document in buffer %s ", output)
|
|
|
|
# Commit in the last iteration of the loop when all the documents
|
|
# have been pushed to Shipyard buffer.
|
|
return self.commit_documents()
|
|
|
|
def commit_documents(self):
|
|
"""Commit Shipyard buffer documents """
|
|
|
|
LOG.info("Commiting Shipyard buffer documents")
|
|
|
|
try:
|
|
resp_text = self.formatted_response_handler(
|
|
self.api_client.commit_configdocs())
|
|
except Exception as ex:
|
|
resp_text = (
|
|
"Error: Unable to invoke action due to: {}".format(str(ex)))
|
|
raise DocumentUploadError(resp_text)
|
|
return resp_text
|
|
|
|
def validate_auth_vars(self):
|
|
"""Checks that the required authorization varible have been entered"""
|
|
required_auth_vars = ['auth_url']
|
|
err_txt = []
|
|
for var in required_auth_vars:
|
|
if self.auth_vars[var] is None:
|
|
err_txt.append(
|
|
'Missing the required authorization variable: '
|
|
'--os-{}'.format(var.replace('_', '-')))
|
|
if err_txt:
|
|
for var in self.auth_vars:
|
|
if (self.auth_vars.get(var) is None
|
|
and var not in required_auth_vars):
|
|
err_txt.append(
|
|
'- Also not set: --os-{}'.format(
|
|
var.replace('_', '-')))
|
|
raise AuthValuesError(diagnostic='\n'.join(err_txt))
|
|
|
|
def formatted_response_handler(self, response):
|
|
"""Base format handler for either json or yaml depending on call"""
|
|
call = response.headers['Content-Type']
|
|
if 'json' in call:
|
|
try:
|
|
return json.dumps(response.json(), indent=4)
|
|
except ValueError:
|
|
return (
|
|
"This is not json and could not be printed as such. \n"
|
|
+ response.text)
|