spyglass/spyglass/spyglass.py

224 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 logging
import pkg_resources
import pprint
import click
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
intermediary_yaml = {}
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 pkg_resources.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()