def build_genesis(build_path, encryption_key, validators, debug, site_name): """ Build the genesis deployment bundle, and store it in ``build_path``. Build the genesis.sh script, base65-encode, encrypt and embed the site configuration source documents in genesis.sh script. If ``validators`` flag should be True, build the bundle validator scripts as well. Store the built deployment bundle in `build_path`. :param str build_path: Directory path of the built genesis deployment bundle :param str encryption_key: Key to use to encrypt the bundled site configuration in genesis.sh script. :param bool validators: Whether to generate validator scripts :param int debug: pegleg debug level to pass to promenade engine for logging. :return: None """ # Raise an error if the build path exists. We don't want to overwrite it. if os.path.isdir(build_path): raise click.ClickException( "{} already exists, remove it or specify a new " "directory.".format(build_path)) # Get the list of config files LOG.info('=== Building bootstrap scripts ===') # Copy the site config, and site secrets to build directory os.mkdir(build_path) documents = util.definition.documents_for_site(site_name) secret_manager = PeglegSecretManagement(docs=documents) documents = secret_manager.get_decrypted_secrets() try: # Use the promenade engine to build and encrypt the genesis bundle c = Configuration(documents=documents, debug=debug, substitute=True, allow_missing_substitutions=False, leave_kubectl=False) # Both a policy and key are present, generate bundle with encryption if c.get_path('EncryptionPolicy:scripts.genesis') and encryption_key: Builder(c, validators=validators).build_all(output_dir=build_path) # A policy or key are present but not both, raise an error elif c.get_path('EncryptionPolicy:scripts.genesis') or encryption_key: raise GenesisBundleEncryptionException() # Neither policy or key are present, generate bundle without encryption else: Builder(c, validators=validators).build_all(output_dir=build_path) except exceptions.PromenadeException as e: LOG.error('Build genesis bundle failed! {}.'.format( e.display(debug=debug))) raise GenesisBundleGenerateException() LOG.info('=== Done! ===')
def on_get(self, req, resp): leave_kubectl = req.get_param_as_bool('leave_kubectl') design_ref = req.get_param('design_ref', required=True) # The required IP address to be used by Kubernetes itself ip = req.get_param('ip', required=True) # The optional IP address to configure as externally-routable external_ip = req.get_param('external_ip', default='127.0.0.1') hostname = req.get_param('hostname', required=True) # NOTE(sh8121att): Set a default here for backward compatability dns_domain = req.get_param('domain', default='local') dynamic_labels = _get_param_list(req, 'labels.dynamic') static_labels = _get_param_list(req, 'labels.static') join_ips = _get_join_ips() try: config = Configuration.from_design_ref( design_ref, allow_missing_substitutions=False, leave_kubectl=leave_kubectl) except exceptions.DeckhandException: LOG.exception('Caught Deckhand render error for configuration') raise if config.get_path('KubernetesNode:.', SENTINEL) != SENTINEL: raise exceptions.ExistingKubernetesNodeDocumentError( 'Existing KubernetesNode documents found') node_document = { 'schema': 'promenade/KubernetesNode/v1', 'metadata': { 'name': hostname, 'schema': 'metadata/Document/v1', 'layeringDefinition': { 'abstract': False, 'layer': 'site' }, }, 'data': { 'hostname': hostname, 'domain': dns_domain, 'ip': ip, 'external_ip': external_ip, 'join_ips': join_ips, 'labels': { 'dynamic': dynamic_labels, 'static': static_labels, }, }, } config.append(node_document) builder = Builder(config) script = builder.build_node_script(hostname) resp.body = script resp.content_type = 'text/x-shellscript' resp.status = falcon.HTTP_200
def on_post(self, req, resp): href = req.get_param('href', required=True) try: config = Configuration.from_design_ref(href) validation.check_design(config) msg = "Promenade validations succeeded" return self._return_msg(resp, falcon.HTTP_200, message=msg) except exceptions.ValidationException as e: msg = "Promenade validations failed: %s" % str(e) return self._return_msg( resp, falcon.HTTP_400, status="Invalid", message=msg)
def on_get(self, req, resp): leave_kubectl = req.get_param_as_bool('leave_kubectl') design_ref = req.get_param('design_ref', required=True) ip = req.get_param('ip', required=True) hostname = req.get_param('hostname', required=True) dynamic_labels = _get_param_list(req, 'labels.dynamic') static_labels = _get_param_list(req, 'labels.static') join_ip = _get_join_ip() try: config = Configuration.from_design_ref( design_ref, allow_missing_substitutions=False, leave_kubectl=leave_kubectl) except exceptions.DeckhandException: LOG.exception('Caught Deckhand render error for configuration') raise if config.get_path('KubernetesNode:.', SENTINEL) != SENTINEL: raise exceptions.ExistingKubernetesNodeDocumentError( 'Existing KubernetesNode documents found') node_document = { 'schema': 'promenade/KubernetesNode/v1', 'metadata': { 'name': hostname, 'schema': 'metadata/Document/v1', 'layeringDefinition': { 'abstract': False, 'layer': 'site' }, }, 'data': { 'hostname': hostname, 'ip': ip, 'join_ip': join_ip, 'labels': { 'dynamic': dynamic_labels, 'static': static_labels, }, }, } config.append(node_document) builder = Builder(config) script = builder.build_node_script(hostname) resp.body = script resp.content_type = 'text/x-shellscript' resp.status = falcon.HTTP_200
def on_post(self, req, resp): result = ValidationMessage() try: json_data = self.req_json(req) href = json_data.get('href', None) config = Configuration.from_design_ref( href, allow_missing_substitutions=False) result = validation.check_design(config) except exceptions.InvalidFormatError as e: msg = "Invalid JSON Format: %s" % str(e) result.add_error_message(msg, name=e.title) except Exception as e: result.add_error_message(str(e), name=e.title) result.update_response(resp)
def on_get(self, req, resp): design_ref = req.get_param('design_ref', required=True) ip = req.get_param('ip', required=True) hostname = req.get_param('hostname', required=True) dynamic_labels = _get_param_list(req, 'labels.dynamic') static_labels = _get_param_list(req, 'labels.static') join_ip = _get_join_ip() config = Configuration.from_design_ref(design_ref) node_document = { 'schema': 'promenade/KubernetesNode/v1', 'metadata': { 'name': hostname, 'schema': 'metadata/Document/v1', 'layeringDefinition': { 'abstract': False, 'layer': 'site' }, }, 'data': { 'hostname': hostname, 'ip': ip, 'join_ip': join_ip, 'labels': { 'dynamic': dynamic_labels, 'static': static_labels, }, }, } config.append(node_document) builder = Builder(config) script = builder.build_node_script(hostname) resp.body = script resp.content_type = 'text/x-shellscript' resp.status = falcon.HTTP_200