def __init__( self, template_path: str, parent_dir: str, uploaders: Uploaders, code_signer: CodeSigner, resources_to_export=frozenset( RESOURCES_EXPORT_LIST + [CloudFormationStackResource, ServerlessApplicationResource]), metadata_to_export=frozenset(METADATA_EXPORT_LIST), ): """ Reads the template and makes it ready for export """ if not (is_local_folder(parent_dir) and os.path.isabs(parent_dir)): raise ValueError( "parent_dir parameter must be " "an absolute path to a folder {0}".format(parent_dir)) abs_template_path = make_abs_path(parent_dir, template_path) template_dir = os.path.dirname(abs_template_path) with open(abs_template_path, "r") as handle: template_str = handle.read() self.template_dict = yaml_parse(template_str) self.template_dir = template_dir self.resources_to_export = resources_to_export self.metadata_to_export = metadata_to_export self.uploaders = uploaders self.code_signer = code_signer
def do_export(self, resource_id, resource_dict, parent_dir): """ If the nested stack template is valid, this method will export on the nested template, upload the exported template to S3 and set property to URL of the uploaded S3 template """ template_path = resource_dict.get(self.PROPERTY_NAME, None) if (template_path is None or is_s3_url(template_path) or template_path.startswith(self.uploader.s3.meta.endpoint_url) or template_path.startswith("https://s3.amazonaws.com/")): # Nothing to do return abs_template_path = make_abs_path(parent_dir, template_path) if not is_local_file(abs_template_path): raise exceptions.InvalidTemplateUrlParameterError( property_name=self.PROPERTY_NAME, resource_id=resource_id, template_path=abs_template_path) exported_template_dict = Template(template_path, parent_dir, self.uploaders, self.code_signer).export() exported_template_str = yaml_dump(exported_template_dict) with mktempfile() as temporary_file: temporary_file.write(exported_template_str) temporary_file.flush() url = self.uploader.upload_with_dedup(temporary_file.name, "template") # TemplateUrl property requires S3 URL to be in path-style format parts = S3Uploader.parse_s3_url(url, version_property="Version") s3_path_url = self.uploader.to_path_style_s3_url( parts["Key"], parts.get("Version", None)) set_value_from_jmespath(resource_dict, self.PROPERTY_NAME, s3_path_url)