Example #1
0
def cmd_get(hname, fmt=None):
    """retrieve an smc element with its hierarchical name (hname) and
    display it.
    """
    is_xml = (fmt == "xml")
    is_yaml = (fmt == "yaml")
    is_conf = (fmt == "conf")

    #todo error
    session_file_path = get_session_file_path()
    smc_client = SMCClient(session_file_path)

    try:
        smc_element = smc_client.get(hname)
    except ResolveError as err:
        raise CommandError(err)
    except (SMCOperationFailure) as err:
        raise CommandError(u"(SMC): " + unicode(err))

    elt = smc_element.data

    if is_xml:
        xml = etree.tostring(elt, encoding='utf8', pretty_print=True)
        print_fmt(xml)

    elif is_conf:
        conf = etconfig.dumps(elt, print_root=True)
        print_fmt(conf)

    elif is_yaml:
        struct = etconfig.utils.el_to_struct(elt)
        print(yaml.dump(struct))
Example #2
0
def cmd_show_hname(hname):
    """
    convert a hierarchical name (hname) into the corresponding url
    """
    session_file_path = get_session_file_path()
    smc_client = SMCClient(session_file_path)

    try:
        url = resolve_hname(smc_client.rest_client, hname)
    except ResolveError as err:
        raise CommandError(err)
    except (SMCOperationFailure) as err:
        raise CommandError(u"(SMC): " + unicode(err))

    print_fmt(url)
Example #3
0
    def execute(self,
                target,
                operation=None,
                method="POST",
                data=None,
                params=None,
                print_only=False,
                files=None,
                **kwargs):
        """
        target is either an hname or an instance of SMCElement
        """
        hname = target.hname if isinstance(target, SMCElement) else target
        if operation:
            hname = hname + "/" + operation

        target_href = resolve_hname(self._client, hname)

        headers = {
            'Accept': 'application/xml',
        }
        if not files:
            headers['Content-Type'] = 'application/json'

        if isinstance(target, SMCElement):
            headers['If-Match'] = target.etag

        xml = None
        if data is not None:
            resolve_elt_hnames(self._client, data, ignore_errors=print_only)

            xml = etree.tostring(data, encoding='utf8', pretty_print=True)
            headers['Content-Type'] = 'application/xml'

        method = method.upper()
        if print_only:
            print_fmt("{} {} {}\n{}\n{}", method, target_href, params, xml,
                      files)
            return

        # exceptions propagated: eg SMCOperationFailure
        resp = self._client.request(method,
                                    target_href,
                                    headers=headers,
                                    params=params,
                                    data=xml,
                                    files=files)
        return resp.text
Example #4
0
def cmd_list(hname, json=False, xml=False, links=False):
    """
    list the sub-element under given hierarchical name (hname)
    """

    session_file_path = get_session_file_path()
    smc_client = SMCClient(session_file_path)

    try:
        res = smc_client.list(hname)
    except ResolveError as err:
        raise CommandError(err)
    except (SMCOperationFailure) as err:
        raise CommandError(u"(SMC): " + unicode(err))

    for name in sorted(res):
        print_fmt("{}", name)
Example #5
0
    def create(self, elt, hname=None, print_only=False):
        """send a POST request to the smc rest api to create an element

        :param etree.Element elt: represents the element data to
        create in xml e.g.  <single_fw>...</single_fw>

        :param str hname: hierarchical name that will result in the
        url endoint. It can be omitted if the hname is the same as the
        element tag. e.g. hname="#single_fw"

        :returns: None

        :raises ResolveError: fails to convert a hname to a url
        (either the target or an url in an attribute of the element)

        :raises SMCOperationFailure: if creation unsuccessful

        """
        if not hname:
            hname = elt.tag

        logger.debug("create resource hname=%s", hname)

        # ResolveError exception is propagated
        target_href = resolve_hname(self._client, hname)
        resolve_elt_hnames(self._client, elt, ignore_errors=print_only)

        xml = etree.tostring(elt, encoding='utf8', pretty_print=True)
        if print_only:
            print_fmt(CREATE_PRINT_FMT,
                      verb="POST",
                      target_href=target_href,
                      tag=elt.tag,
                      name=elt.get("name", "-"),
                      xml=xml)
            return

        headers = {
            'Content-Type': 'application/xml',
            'Accept': 'application/xml'
        }
        resp = self._client.post(target_href, headers=headers, data=xml)
        logger.debug("status_code=%d", resp.status_code)
        logger.debug("text=%s", resp.text)
Example #6
0
def delete_all_resources(smc_client, conf):
    """
    iterate over all resources in the config file and try to delete them.
    Retries till there are failed resources and some resources were deleted
    in the previous iteration, to solve dependencies.
    """
    resources = conf.xpath("resource")

    while resources:
        failed = _delete_all_resources(smc_client, resources)
        num_resources_remaining = len(failed)
        if num_resources_remaining == len(resources):
            print_fmt("{} resources could not be deleted",
                      num_resources_remaining)
            for elt in failed:
                target_hname = _get_resource_name_to_delete(elt)
                print_fmt(" - {}", target_hname)
            return
        resources = failed
Example #7
0
    def update(self, smc_element, print_only=False):
        """
        apply the change list of an smc element and send a rest call
        to update the object in the smc.

        :raises SMCOperationFailure: if update unsuccessful

        """
        # todo refresh etags if object has changed
        # todo exc

        headers = {
            'If-Match': smc_element.etag,
            'Content-Type': 'application/xml'
        }

        target_href = resolve_hname(self._client, smc_element.hname)

        # todo error
        smc_element.apply_changes()
        resolve_elt_hnames(self._client, smc_element.data)

        xml = etree.tostring(smc_element.data, pretty_print=True)

        if print_only:
            elt = smc_element.data
            print_fmt(CREATE_PRINT_FMT,
                      verb="PUT",
                      target_href=target_href,
                      tag=elt.tag,
                      name=elt.get("name", "-"),
                      xml=xml)
            return

        try:
            resp = self._client.put(target_href, headers=headers, data=xml)
        except SMCOperationFailure as exc:
            logger.error("Failed to update '%s'", unicode(exc))
            raise exc
        smc_element.change_list = []
Example #8
0
def _delete_all_resources(smc_client, resources):
    """
    iterate over a list of resources and delete them

    :param list of Element resources: list of resource to delete

    :returns: list of Element resources that could not be deleted
    :rtype: list
    """
    failed = []
    for elt in resources:
        target_hname = _get_resource_name_to_delete(elt)
        if not target_hname:
            failed.append(elt)
            continue
        # print_values(target_hname=target_hname)
        try:
            do_delete_elt(smc_client, target_hname, elt)
            print_fmt("- delete {} successful", target_hname)
        except (ResolveError, SMCOperationFailure) as exc:
            failed.append(elt)
    return failed
Example #9
0
def run_script(smc_client,
               filename,
               print_only=False,
               preprocess_only=False,
               user_variables=None,
               variable_files=None,
               ignore_errors=False,
               delete_mode=False,
               cleanup_mode=False):
    """execute a script

    :param SMCClient smc_client: client to send requests to smc
    :param str filename: name of the file containing the script
    :param bool print_only: does not execute the script. only print
    :param bool preprocess_only: show the script after the template preprocessing
    :param dict user_variables: dict of name/value used as variables for
    template preprocessing

    :returns: None

    :raises IOError: if filename could not be read
    :raises TemplateLookupException: failed to include a file
    :raises NameError: if a variable cannot be resolved
    :raises SyntaxException: syntax error during preprocessing
    :raises ElementConfError: failed to parse the filename (after processing)
    :raises InvalidSessionError: not logged in or session expired
    :raises SMCOperationFailure: is smc server responds with status_code error

    """

    api_version = smc_client.api_version
    variables = {'API_VERSION': api_version, 'SCRIPT': smc_client}

    lookup_dir = os.path.dirname(os.path.abspath(filename))
    var_config_file_name = lookup_dir + "/variables.cnf"
    logger.debug("var_config_file_name=%s", var_config_file_name)

    # default values from variables.cnf

    if os.path.isfile(var_config_file_name):
        logger.debug("opening =%s", var_config_file_name)
        var_elts = load_config_file(var_config_file_name)
        logger.debug("var_elts=%s", var_elts)
        for var_elt in var_elts:
            name = var_elt.get("name")
            value = var_elt.get("default")
            variables[name] = value
            logger.debug("VAR: %s=%s", name, value)

    # variables obtained from conf implicit file
    files = glob('*.cnfvars')
    for f in files:
        file_variables = read_variables_from_conf(f)
        variables.update(file_variables)

    # variables obtained from conf explicit file (--var-file)
    for f in variable_files:
        if not os.path.isfile(f):
            raise RunScriptError(
                "variable config file '{}' not found ".format(f))
        file_variables = read_variables_from_conf(f)
        variables.update(file_variables)

    # variables obtained from env.variables (take precedence from file)
    for name, value in os.environ.items():
        prefix = 'CNF_VAR_'
        if name.startswith(prefix):
            var_name = name[len(prefix):]
            variables[var_name] = value

    # variables obtained from command-line (take precedence from both
    # file and env.var)
    if user_variables:
        variables.update(user_variables)

    if preprocess_only:
        rendered = preprocess_config_file(filename, variables)
        print(rendered)
        return

    conf = load_config_file(filename, variables)

    if delete_mode or cleanup_mode:
        print("Cleaning up...")
        delete_all_resources(smc_client, conf)
        if delete_mode:
            return

    operations = dict(login=do_login,
                      logout=do_logout,
                      resource=do_create_elt,
                      delete=do_delete_elt,
                      update=do_update_elt,
                      command=do_execute,
                      get=do_execute)

    print("Applying config...")

    for elt in conf:
        operation = elt.tag
        target_hname = _get_target_hname(elt)

        if operation == 'resource':
            name = elt[0].attrib.get("name", "")
            op_text = "{} {}/{}...".format(operation, target_hname, name)
        else:
            op_text = "{} {}...".format(operation, target_hname)

        logging.info("script command: %s", op_text)
        print_fmt("- {}", op_text)
        if operation not in operations:
            raise RunScriptError("invalid operation: " + operation)
        fun = operations.get(operation)

        try:
            fun(smc_client, target_hname, elt, print_only)
        except (SMCOperationFailure, ResolveError) as exc:
            if ignore_errors:
                print_err(" => Ignoring error: {}", unicode(exc))
                continue
            raise SMCOperationFailure(unicode(exc))
    return