Beispiel #1
0
def execute_docker_skillet(skillet_def: dict, args: dict) -> str:
    """
    Execute a skillet of type 'docker'. This requires the calling application have access to the
    docker socket

    :param skillet_def: the skillet as loaded from the YAML file (dict)
    :param args: context arguments required for the given skillets. These will overwrite the 'variables' in the
    skillet
    :return: JSON encoded string with dict containing the following keys: {'returncode', 'out', 'err'}
    """
    state = dict()
    full_output = ''
    err = ''
    rc = 0

    docker_helper = DockerHelper()

    if skillet_def['type'] != 'docker' and skillet_def['type'] != 'terraform':
        rc = 255
        err = f'Not a valid skillet type: {skillet_def["type"]}!'

    elif not docker_helper.check_docker_server():
        rc = 240
        err = 'Could not connect to Docker daemon, verify permissions on the docker socket! \n\n' \
              'See the documentation for details: https://panhandler.readthedocs.io/en/master/debugging.html'

    else:
        try:
            persistent_volumes = docker_helper.get_cnc_volumes()

            if 'app_data' not in skillet_def:
                skillet_def['app_data'] = dict()

            # always overwrite any volumes that may have snuck in here
            if persistent_volumes:
                skillet_def['app_data']['volumes'] = persistent_volumes

            else:
                # only this app should be setting app_data/volumes here, remove anything else
                if 'volumes' in skillet_def['app_data']:
                    skillet_def['app_data'].pop('volumes')

            sl = SkilletLoader()
            skillet = sl.create_skillet(skillet_def)

            # FIX for #181
            sanitized_args = __santize_args(args)

            output_generator = skillet.execute_async(sanitized_args)

            for out in output_generator:
                full_output += out
                current_task.update_state(state='PROGRESS', meta=full_output)

            r = skillet.get_results()

            # FIXME - docker skillets can run multiple snippets / cmds inside the container
            # should check for the output of each and determine if a single failure is considered a failure
            # for the entire skillet or only a failure for one step ?
            if isinstance(r, dict) and 'snippets' in r:
                for k, v in r['snippets'].items():
                    result = v.get('results', 'failure')

                    if result == 'success':
                        full_output = v.get('raw', '')
                    elif result == 'error' or 'fail' in result:
                        err = v.get('raw', 'error')
                        rc = 2
                    else:
                        full_output = v.get('raw', '')
                        err = f'Unknown return value type {result}'
                        rc = 3
            else:
                full_output = r
                err = 'unknown output from skillet'

        except DockerHelperException as dee:
            logger.error(dee)
            rc = 1
            err = str(dee)

        except SkilletLoaderException as sle:
            logger.error(sle)
            rc = 1
            err = str(sle)

    state['returncode'] = rc
    state['out'] = full_output
    state['err'] = err

    return json.dumps(state)
# check we actually have some diffs
if len(snippets) == 0:
    print('No Diffs found between these two configs')

    sys.exit(2)

# SkilletLoader is used to... Load Skillets
skillet_loader = SkilletLoader()

# create_skillet will return a Skillet Object from the metadata dictionary passed in.
# in this case, we create a minimal metadata dict and pass it in to create a simple 'template' skillet
# a template skillet is a nice wrapper around the jinja engine
template_skillet = skillet_loader.create_skillet(
    {'type': 'template',
     'snippets': [
         {'name': 'template', 'file': './ansible_pb_template.j2'}
     ]
     }
)

# to execute this skillet, create the context object which includes any variables found in the template file
context = dict()
context['snippets'] = snippets
context['playbook_name'] = 'Auto Generated PAN-OS Playbook'
# execute the template skillet and get the returned output
output = template_skillet.execute(context)

# template skillets add the 'template' attribute into the output which contains the rendered template
# print it out for the user
print(output['template'])
    # create the skillet definition from the 'skillet_content' dict we got from the environ
    skillet_dict_raw = oyaml.safe_load(skillet_content)

    # use skilletLoader to normalize the skillet definition and fix common config file errors
    skillet_dict = sl.normalize_skillet_dict(skillet_dict_raw)
    skillet_dict['snippet_path'] = '.'

    # create the skillet object from the skillet dict
    if 'pan_validation' in skillet_dict.get('type'):
        skillet: PanValidationSkillet = PanValidationSkillet(
            skillet_dict, device)
    elif 'pan' in skillet_dict.get('type'):
        skillet: PanosSkillet = PanosSkillet(skillet_dict, device)
    else:
        skillet: Skillet = sl.create_skillet(skillet_dict)

    # ensure all our variables from the environment / outer context is copied in and ready to go
    skillet.update_context(os.environ)
    # execute the skillet and return the results to us
    results = skillet.execute(context)

    print()
    print('=' * 137)
    print()
    print('Execution Results:')
    print()
    print('=' * 137)
    print()
    # in this case, just print them out for the user
    if skillet.type == 'pan_validation':
    sys.exit(1)

# check we actually have some diffs
if len(snippets) == 0:
    print("No Diffs found between these two configs")

    sys.exit(2)

# SkilletLoader is used to... Load Skillets
skillet_loader = SkilletLoader()

# create_skillet will return a Skillet Object from the metadata dictionary passed in.
# in this case, we create a minimal metadata dict and pass it in to create a simple 'template' skillet
# a template skillet is a nice wrapper around the jinja engine
template_skillet = skillet_loader.create_skillet(
    {"type": "template", "snippets": [{"name": "template", "file": "./ansible_pb_template.j2"}]}
)

# to execute this skillet, create the context object which includes any variables found in the template file
context = dict()
context["snippets"] = snippets
context["playbook_name"] = "Auto Generated PAN-OS Playbook"
# execute the template skillet and get the returned output
output = template_skillet.execute(context)

# template skillets add the 'template' attribute into the output which contains the rendered template
# print it out for the user
print(output["template"])

# later gator
sys.exit(0)