Exemplo n.º 1
0
 def _execute(self) -> TaskOutcome:
     """Execute path core."""
     if not self.xlsx_helper.configure(self):
         return TaskOutcome('failure')
     # config output
     odir = self._config.get('output-dir')
     opth = pathlib.Path(odir)
     self._overwrite = self._config.getboolean('output-overwrite', True)
     # insure output dir exists
     opth.mkdir(exist_ok=True, parents=True)
     # calculate output file name & check writability
     oname = 'component-definition.json'
     ofile = opth / oname
     if not self._overwrite and pathlib.Path(ofile).exists():
         logger.error(f'output: {ofile} already exists')
         return TaskOutcome('failure')
     # initialize
     self.component_names = []
     self.defined_components = []
     self.parameters = {}
     self.parameter_helper = None
     # roles, responsible_roles, parties, responsible parties
     party_uuid_01 = str(uuid.uuid4())
     party_uuid_02 = str(uuid.uuid4())
     party_uuid_03 = str(uuid.uuid4())
     roles = self._build_roles()
     responsible_roles = self._build_responsible_roles(
         party_uuid_01, party_uuid_02, party_uuid_03)
     parties = self._build_parties(party_uuid_01, party_uuid_02,
                                   party_uuid_03)
     responsible_parties = self._build_responsible_parties(
         party_uuid_01, party_uuid_02, party_uuid_03)
     # process each row of spread sheet
     self._process_rows(responsible_roles)
     # create OSCAL ComponentDefinition
     metadata = Metadata(title='Component definition for ' +
                         self._get_catalog_title() + ' profiles',
                         last_modified=self._timestamp,
                         oscal_version=OSCAL_VERSION,
                         version=get_trestle_version(),
                         roles=roles,
                         parties=parties,
                         responsible_parties=responsible_parties)
     component_definition = ComponentDefinition(
         uuid=str(uuid.uuid4()),
         metadata=metadata,
         components=self.defined_components,
     )
     # write OSCAL ComponentDefinition to file
     if self._verbose:
         logger.info(f'output: {ofile}')
     component_definition.oscal_write(pathlib.Path(ofile))
     # issues
     self._report_issues()
     # <hack>
     # create a catalog containing the parameters,
     # since parameters are not supported in OSCAL 1.0.0 component definition
     self._write_catalog()
     # </hack>
     return TaskOutcome('success')
Exemplo n.º 2
0
    def _transform_work(self) -> TaskOutcome:
        """
        Perform the transformation work.

        Transformation work steps: read input, process, write output, display analysis.
        """
        mode = ''
        if self._simulate:
            mode = 'simulated-'
        if not self._config:
            logger.error('Config missing')
            return TaskOutcome(mode + 'failure')
        # config required input & output dirs
        try:
            idir = self._config['input-dir']
            ipth = pathlib.Path(idir)
            odir = self._config['output-dir']
            opth = pathlib.Path(odir)
        except KeyError as e:
            logger.debug(f'key {e.args[0]} missing')
            return TaskOutcome(mode + 'failure')
        # config optional overwrite & quiet
        self._overwrite = self._config.getboolean('output-overwrite', True)
        quiet = self._config.get('quiet', False)
        self._verbose = not self._simulate and not quiet
        # config optional timestamp
        timestamp = self._config.get('timestamp')
        if timestamp is not None:
            try:
                TaniumTransformer.set_timestamp(timestamp)
            except Exception:
                logger.error('config invalid "timestamp"')
                return TaskOutcome(mode + 'failure')
        # config optional performance
        modes = {
            'blocksize': self._config.getint('blocksize', 10000),
            'cpus_max': self._config.getint('cpus-max', 1),
            'cpus_min': self._config.getint('cpus-min', 1),
            'checking': self._config.getboolean('checking', False),
        }
        # insure output dir exists
        opth.mkdir(exist_ok=True, parents=True)
        # process
        for ifile in sorted(ipth.iterdir()):
            blob = self._read_file(ifile)
            tanium_transformer = TaniumTransformer()
            tanium_transformer.set_modes(modes)
            results = tanium_transformer.transform(blob)
            oname = ifile.stem + '.oscal' + '.json'
            ofile = opth / oname
            if not self._overwrite and pathlib.Path(ofile).exists():
                logger.error(f'output: {ofile} already exists')
                return TaskOutcome(mode + 'failure')
            self._write_file(results, ofile)
            self._show_analysis(tanium_transformer)
        return TaskOutcome(mode + 'success')
Exemplo n.º 3
0
 def execute(self) -> TaskOutcome:
     """Provide an executed outcome."""
     try:
         return self._execute()
     except Exception:
         logger.info(traceback.format_exc())
         return TaskOutcome('failure')
Exemplo n.º 4
0
 def _transform(self) -> TaskOutcome:
     """Perform transformation."""
     try:
         return self._transform_work()
     except Exception:
         logger.info(traceback.format_exc())
         mode = ''
         if self._simulate:
             mode = 'simulated-'
         return TaskOutcome(mode + 'failure')
 def _execute(self) -> TaskOutcome:
     """Execute path core."""
     if not self.xlsx_helper.configure(self):
         return TaskOutcome('failure')
     # config output
     odir = self._config.get('output-dir')
     opth = pathlib.Path(odir)
     self._overwrite = self._config.getboolean('output-overwrite', True)
     # insure output dir exists
     opth.mkdir(exist_ok=True, parents=True)
     # calculate output file name & check writability
     oname = 'profile.json'
     ofile = opth / oname
     if not self._overwrite and pathlib.Path(ofile).exists():
         logger.error(f'output: {ofile} already exists')
         return TaskOutcome('failure')
     # create OSCAL Profile
     metadata = Metadata(
         title='Profile for ' + self._get_profile_title(),
         last_modified=self._timestamp,
         oscal_version=OSCAL_VERSION,
         version=get_trestle_version(),
     )
     import_ = Import(
         href=self._get_spread_sheet_url(),
         include_controls=self._get_include_controls(),
     )
     imports = [import_]
     set_parameters = self._get_set_parameters()
     modify = Modify(set_parameters=set_parameters)
     profile = Profile(
         uuid=str(uuid.uuid4()),
         metadata=metadata,
         imports=imports,
         modify=modify,
     )
     # write OSCAL Profile to file
     if self._verbose:
         logger.info(f'output: {ofile}')
     profile.oscal_write(pathlib.Path(ofile))
     # issues
     self._report_issues()
     return TaskOutcome('success')
Exemplo n.º 6
0
 def _execute(self) -> TaskOutcome:
     """Perform transformation."""
     # check config
     if not self._config:
         logger.error('config missing')
         return TaskOutcome('failure')
     # input-file
     input_file = self._config.get('input-file')
     if input_file is None:
         logger.error('config missing "input-file"')
         return TaskOutcome('failure')
     logger.info(f'input-file: {input_file}')
     input_path = pathlib.Path(input_file)
     # output-dir
     output_dir = self._config.get('output-dir')
     if output_dir is None:
         logger.error('config missing "output-dir"')
         return TaskOutcome('failure')
     output_path = pathlib.Path(output_dir)
     # insure output dir exists
     output_path.mkdir(exist_ok=True, parents=True)
     # output file path
     output_name = self._config.get('output-name', 'osco-profile.yaml')
     output_filepath = pathlib.Path(output_dir, output_name)
     logger.info(f'output-file: {output_filepath}')
     # overwrite
     overwrite = self._config.getboolean('output-overwrite', True)
     if not overwrite and pathlib.Path(output_filepath).exists():
         logger.error(f'output-file: {output_filepath} already exists')
         return TaskOutcome('failure')
     # read input
     profile = Profile.oscal_read(input_path)
     # transform
     transformer = ProfileToOscoTransformer()
     ydata = json.loads(transformer.transform(profile))
     # write output
     yaml = YAML(typ='safe')
     yaml.default_flow_style = False
     with open(output_filepath, 'w') as outfile:
         yaml.dump(ydata, outfile)
     # success
     return TaskOutcome('success')
Exemplo n.º 7
0
 def simulate(self) -> TaskOutcome:
     """Provide a simulated outcome."""
     return TaskOutcome('simulated-success')
Exemplo n.º 8
0
 def execute(self) -> TaskOutcome:
     """Provide an actual outcome."""
     if self._config:
         # initialize
         default_metadata = {}
         # process config
         idir = self._config.get('input-dir')
         if idir is None:
             logger.error(f'config missing "input-dir"')
             return TaskOutcome('failure')
         ipth = pathlib.Path(idir)
         odir = self._config.get('output-dir')
         if odir is None:
             logger.error(f'config missing "output-dir"')
             return TaskOutcome('failure')
         imeta = self._config.get('input-metadata', 'oscal-metadata.yaml')
         opth = pathlib.Path(odir)
         overwrite = self._config.getboolean('output-overwrite', True)
         quiet = self._config.getboolean('quiet', False)
         # insure output folder exists
         opth.mkdir(exist_ok=True, parents=True)
         # fetch enhancing oscal metadata
         mfile = ipth / imeta
         metadata = self._get_metadata(mfile, default_metadata)
         if len(metadata) == 0:
             logger.info(f'no metadata: {imeta}.')
         # examine each file in the input folder
         for ifile in sorted(ipth.iterdir()):
             # skip enhancing oscal metadata
             if ifile.name == imeta:
                 continue
             # assemble collection comprising output file name to unprocessed content
             collection = self._assemble(ifile)
             # formulate each output OSCAL partial results file
             for oname in collection.keys():
                 ofile = opth / pathlib.Path(oname)
                 # only allow writing output file if either:
                 # a) it does not already exist, or
                 # b) output-overwrite flag is True
                 if not overwrite:
                     if ofile.exists():
                         logger.error(f'file exists: {ofile}')
                         return TaskOutcome('failure')
                 if not quiet:
                     logger.info(f'create: {ofile}')
                 # create the OSCAL .json file from the OSCO and the optional osco-metadata files
                 observations, analysis = osco.get_observations(
                     collection[oname], metadata)
                 # write the OSCAL to the output file
                 self._write_content(ofile, observations)
                 # display analysis
                 if not quiet:
                     logger.info(f'Rules Analysis:')
                     logger.info(f'config_maps: {analysis["config_maps"]}')
                     logger.info(
                         f'dispatched rules: {analysis["dispatched_rules"]}'
                     )
                     logger.info(
                         f'result types: {analysis["result_types"]}')
         return TaskOutcome('success')
     logger.error(f'config missing')
     return TaskOutcome('failure')
Exemplo n.º 9
0
 def _execute(self) -> TaskOutcome:
     if not self._config:
         logger.error('config missing')
         return TaskOutcome('failure')
     try:
         component_name = self._config['component-name']
         org_name = self._config['org-name']
         org_remarks = self._config['org-remarks']
         self._folder_cac = self._config['folder-cac']
         profile_check_version = self._config['profile-check-version']
         profile_type = self._config['profile-type']
         profile_mnemonic = self._config['profile-mnemonic']
         profile_name = self._config['profile-name']
         profile_ns = self._config['profile-ns']
         profile_version = self._config['profile-version']
         profile_sets = {}
         profile_list = self._config['profile-list'].split()
         for profile in profile_list:
             profile_sets[profile] = {}
             profile_sets[profile]['profile-file'] = self._config[
                 f'profile-file.{profile}']
             profile_sets[profile]['profile-url'] = self._config[
                 f'profile-url.{profile}']
             profile_sets[profile]['profile-title'] = self._config[
                 f'profile-title.{profile}']
             profile_sets[profile]['profile-ns'] = profile_ns
             profile_sets[profile]['component-name'] = component_name
         odir = self._config['output-dir']
     except KeyError as e:
         logger.info(f'key {e.args[0]} missing')
         return TaskOutcome('failure')
     # selected rules
     self._selected_rules = self._get_filter_rules('selected-rules',
                                                   'selected')
     # enabled rules
     self._enabled_rules = self._get_filter_rules('enabled-rules',
                                                  'enabled')
     # verbosity
     quiet = self._config.get('quiet', False)
     verbose = not quiet
     # output
     overwrite = self._config.getboolean('output-overwrite', True)
     opth = pathlib.Path(odir)
     # insure output dir exists
     opth.mkdir(exist_ok=True, parents=True)
     # calculate output file name & check writability
     oname = 'component-definition.json'
     ofile = opth / oname
     if not overwrite and pathlib.Path(ofile).exists():
         logger.error(f'output: {ofile} already exists')
         return TaskOutcome('failure')
     # fetch rule to parameters map
     self._rule_to_parm_map = self._get_parameters_map(
         'rule-to-parameters-map')
     # roles, responsible_roles, parties, responsible parties
     party_uuid_01 = str(uuid.uuid4())
     party_uuid_02 = str(uuid.uuid4())
     party_uuid_03 = str(uuid.uuid4())
     roles = self._build_roles()
     responsible_roles = self._build_responsible_roles(
         party_uuid_01, party_uuid_02, party_uuid_03)
     parties = self._build_parties(org_name, org_remarks, party_uuid_01,
                                   party_uuid_02, party_uuid_03)
     responsible_parties = self._build_responsible_parties(
         party_uuid_01, party_uuid_02, party_uuid_03)
     # metadata
     metadata = Metadata(
         title=f'Component definition for {profile_type} profiles',
         last_modified=self._timestamp,
         oscal_version=OSCAL_VERSION,
         version=trestle.__version__,
         roles=roles,
         parties=parties,
         responsible_parties=responsible_parties)
     # defined component
     component_title = component_name
     component_description = component_name
     defined_component = DefinedComponent(
         uuid=str(uuid.uuid4()),
         description=component_description,
         title=component_title,
         type='Service',
     )
     # add control implementation per profile
     prop1 = Property(
         name='profile_name',
         value=profile_name,
         class_='scc_profile_name',
         ns=profile_ns,
     )
     prop2 = Property(
         name='profile_mnemonic',
         value=profile_mnemonic,
         class_='scc_profile_mnemonic',
         ns=profile_ns,
     )
     prop3 = Property(
         name='profile_version',
         value=profile_version,
         class_='scc_profile_version',
         ns=profile_ns,
     )
     prop4 = Property(
         name='profile_check_version',
         value=profile_check_version,
     )
     props = [prop1, prop2, prop3, prop4]
     for profile in profile_list:
         profile_set = profile_sets[profile]
         control_implementation = self._build_control_implementation(
             profile_set, responsible_roles, props)
         if control_implementation is not None:
             if defined_component.control_implementations is None:
                 defined_component.control_implementations = [
                     control_implementation
                 ]
             else:
                 defined_component.control_implementations.append(
                     control_implementation)
     # defined components
     defined_components = [defined_component]
     # component definition
     component_definition = ComponentDefinition(
         uuid=str(uuid.uuid4()),
         metadata=metadata,
         components=defined_components,
     )
     # write OSCAL ComponentDefinition to file
     if verbose:
         logger.info(f'output: {ofile}')
     component_definition.oscal_write(pathlib.Path(ofile))
     return TaskOutcome('success')
Exemplo n.º 10
0
 def _execute(self) -> TaskOutcome:
     """Wrap the execute for exception handling."""
     if not self._config:
         logger.error('config missing')
         return TaskOutcome('failure')
     try:
         idir = self._config['input-dir']
         odir = self._config['output-dir']
     except KeyError as e:
         logger.info(f'key {e.args[0]} missing')
         return TaskOutcome('failure')
     # verbosity
     quiet = self._config.get('quiet', False)
     verbose = not quiet
     # output
     overwrite = self._config.getboolean('output-overwrite', True)
     opth = pathlib.Path(odir)
     # insure output dir exists
     opth.mkdir(exist_ok=True, parents=True)
     # calculate output file name & check writability
     oname = 'catalog.json'
     ofile = opth / oname
     if not overwrite and pathlib.Path(ofile).exists():
         logger.error(f'output: {ofile} already exists')
         return TaskOutcome('failure')
     # metadata links (optional)
     metadata_links = self._config.get('metadata-links')
     # get list or <name>.profile files
     filelist = self._get_filelist(idir)
     if len(filelist) < 1:
         logger.error(f'input: {idir} no .profile file found')
         return TaskOutcome('failure')
     # initialize node list
     self._node_map = {}
     # process files
     for fp in filelist:
         lines = self._get_content(fp)
         self._parse(lines)
     # get root nodes
     root_nodes = self._get_root_nodes()
     # groups and controls
     root = Group(title='root', groups=[])
     for node in root_nodes:
         group = Group(title=f'{node.name} {node.description}')
         root.groups.append(group)
         depth = self._depth(node.name)
         if depth == 3:
             self._add_groups(group, node.name, depth)
         if depth == 2:
             self._add_controls(group, node.name, depth)
     # metadata
     metadata = Metadata(
         title=self._title, last_modified=self._timestamp, oscal_version=OSCAL_VERSION, version=trestle.__version__
     )
     # metadata links
     if metadata_links is not None:
         metadata.links = []
         for item in metadata_links.split():
             link = Link(href=item)
             metadata.links.append(link)
     # catalog
     catalog = Catalog(uuid=_uuid(), metadata=metadata, groups=root.groups)
     # write OSCAL ComponentDefinition to file
     if verbose:
         logger.info(f'output: {ofile}')
     catalog.oscal_write(pathlib.Path(ofile))
     return TaskOutcome('success')