# 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 logging import pprint import click from pkg_resources import iter_entry_points import yaml from spyglass.parser.engine import ProcessDataSource from spyglass.site_processors.site_processor import SiteProcessor LOG = logging.getLogger("spyglass") @click.command() @click.option("--site", "-s", help="Specify the site for which manifests to be generated") @click.option("--type", "-t", help="Specify the plugin type formation or tugboat") @click.option("--formation_url", "-f", help="Specify the formation url") @click.option("--formation_user", "-u", help="Specify the formation user id") @click.option("--formation_password", "-p", help="Specify the formation user password") @click.option( "--intermediary", "-i", type=click.Path(exists=True), help="Intermediary file path generate manifests, " "use -m also with this option", ) @click.option( "--additional_config", "-d", type=click.Path(exists=True), help="Site specific configuraton details", ) @click.option( "--generate_intermediary", "-g", is_flag=True, help="Dump intermediary file from passed excel and excel spec", ) @click.option( "--intermediary_dir", "-idir", type=click.Path(exists=True), help="The path where intermediary file needs to be generated", ) @click.option( "--generate_manifests", "-m", is_flag=True, help="Generate manifests from the generated intermediary file", ) @click.option( "--manifest_dir", "-mdir", type=click.Path(exists=True), help="The path where manifest files needs to be generated", ) @click.option( "--template_dir", "-tdir", type=click.Path(exists=True), help="The path where J2 templates are available", ) @click.option( "--excel", "-x", multiple=True, type=click.Path(exists=True), help="Path to engineering excel file, to be passed with " "generate_intermediary", ) @click.option( "--excel_spec", "-e", type=click.Path(exists=True), help="Path to excel spec, to be passed with generate_intermediary", ) @click.option( "--loglevel", "-l", default=20, multiple=False, show_default=True, help="Loglevel NOTSET:0 ,DEBUG:10, INFO:20, WARNING:30, ERROR:40, " "CRITICAL:50", ) def main(*args, **kwargs): # Extract user provided inputs generate_intermediary = kwargs["generate_intermediary"] intermediary_dir = kwargs["intermediary_dir"] generate_manifests = kwargs["generate_manifests"] manifest_dir = kwargs["manifest_dir"] intermediary = kwargs["intermediary"] site = kwargs["site"] template_dir = kwargs["template_dir"] loglevel = kwargs["loglevel"] # Set Logging format LOG.setLevel(loglevel) stream_handle = logging.StreamHandler() formatter = \ logging.Formatter("(%(name)s): %(asctime)s %(levelname)s %(message)s") stream_handle.setFormatter(formatter) LOG.addHandler(stream_handle) LOG.info("Spyglass start") LOG.info("CLI Parameters passed:\n{}".format(kwargs)) if not (generate_intermediary or generate_manifests): LOG.error("Invalid CLI parameters passed!! Spyglass exited") LOG.error("One of the options -m/-g is mandatory") LOG.info("CLI Parameters:\n{}".format(kwargs)) exit() if generate_manifests: if template_dir is None: LOG.error("Template directory not specified!! Spyglass exited") LOG.error("It is mandatory to provide it when " "generate_manifests is true") exit() # Generate Intermediary yaml and manifests extracting data # from data source specified by plugin type if intermediary is None: LOG.info("Generating Intermediary yaml") plugin_type = kwargs.get("type", None) plugin_class = None # Discover the plugin and load the plugin class LOG.info("Load the plugin class") for entry_point in iter_entry_points("data_extractor_plugins"): if entry_point.name == plugin_type: plugin_class = entry_point.load() if plugin_class is None: LOG.error( "Unsupported Plugin type. Plugin type:{}".format(plugin_type)) exit() # Extract data from plugin data source LOG.info("Extract data from plugin data source") data_extractor = plugin_class(site) plugin_conf = data_extractor.get_plugin_conf(kwargs) data_extractor.set_config_opts(plugin_conf) data_extractor.extract_data() # Apply any additional_config provided by user additional_config = kwargs.get("additional_config", None) if additional_config is not None: with open(additional_config, "r") as config: raw_data = config.read() additional_config_data = yaml.safe_load(raw_data) LOG.debug("Additional config data:\n{}".format( pprint.pformat(additional_config_data))) LOG.info("Apply additional configuration from:{}".format( additional_config)) data_extractor.apply_additional_data(additional_config_data) LOG.debug(pprint.pformat(data_extractor.site_data)) # Apply design rules to the data LOG.info("Apply design rules to the extracted data") process_input_ob = ProcessDataSource(site) process_input_ob.load_extracted_data_from_data_source( data_extractor.site_data) LOG.info("Generate intermediary yaml") intermediary_yaml = process_input_ob.generate_intermediary_yaml() else: LOG.info("Loading intermediary from user provided input") with open(intermediary, "r") as intermediary_file: raw_data = intermediary_file.read() intermediary_yaml = yaml.safe_load(raw_data) if generate_intermediary: process_input_ob.dump_intermediary_file(intermediary_dir) if generate_manifests: LOG.info("Generating site Manifests") processor_engine = SiteProcessor(intermediary_yaml, manifest_dir) processor_engine.render_template(template_dir) LOG.info("Spyglass Execution Completed") if __name__ == "__main__": main()