示例#1
0
    def test_archive_discard_section(self):
        '''
        Test discard a section from the archive.

        :return:
        '''
        archive = MagicMock()
        with patch('salt.cli.support.collector.tarfile.TarFile', archive):
            self.collector.open()
            self.collector.add('solar-interference')
            self.collector.link(title='Thermal anomaly', path='/path/to/another/great.config')
            self.collector.add('foo')
            self.collector.link(title='Backup Path', path='/path/to/backup.config')
            self.collector._flush_content()
            assert archive.bz2open().addfile.call_count == 2
            assert (archive.bz2open().addfile.mock_calls[0][2]['fileobj'].read()
                    == to_bytes('Thermal anomaly\n---------------\n\npath=/dev/null\n\n\n'))
            self.collector.close()

        archive = MagicMock()
        with patch('salt.cli.support.collector.tarfile.TarFile', archive):
            self.collector.open()
            self.collector.add('solar-interference')
            self.collector.link(title='Thermal anomaly', path='/path/to/another/great.config')
            self.collector.discard_current()
            self.collector.add('foo')
            self.collector.link(title='Backup Path', path='/path/to/backup.config')
            self.collector._flush_content()
            assert archive.bz2open().addfile.call_count == 2
            assert (archive.bz2open().addfile.mock_calls[0][2]['fileobj'].read()
                    == to_bytes('Backup Path\n-----------\n\npath=/dev/null\n\n\n'))
            self.collector.close()
示例#2
0
文件: aliyun.py 项目: arminsama/bos
def _compute_signature(parameters, access_key_secret):
    '''
    Generate aliyun request signature
    '''

    def percent_encode(line):
        if not isinstance(line, six.string_types):
            return line

        s = line
        if sys.stdin.encoding is None:
            s = line.decode().encode('utf8')
        else:
            s = line.decode(sys.stdin.encoding).encode('utf8')
        res = _quote(s, '')
        res = res.replace('+', '%20')
        res = res.replace('*', '%2A')
        res = res.replace('%7E', '~')
        return res

    sortedParameters = sorted(list(parameters.items()), key=lambda items: items[0])

    canonicalizedQueryString = ''
    for k, v in sortedParameters:
        canonicalizedQueryString += '&' + percent_encode(k) \
            + '=' + percent_encode(v)

    # All aliyun API only support GET method
    stringToSign = 'GET&%2F&' + percent_encode(canonicalizedQueryString[1:])

    h = hmac.new(to_bytes(access_key_secret + "&"), stringToSign, sha1)
    signature = base64.encodestring(h.digest()).strip()
    return signature
示例#3
0
def _compute_signature(parameters, access_key_secret):
    """
    Generate aliyun request signature
    """
    def percent_encode(line):
        if not isinstance(line, str):
            return line

        s = line
        if sys.stdin.encoding is None:
            s = line.decode().encode("utf8")
        else:
            s = line.decode(sys.stdin.encoding).encode("utf8")
        res = urllib.parse.quote(s, "")
        res = res.replace("+", "%20")
        res = res.replace("*", "%2A")
        res = res.replace("%7E", "~")
        return res

    sortedParameters = sorted(list(parameters.items()),
                              key=lambda items: items[0])

    canonicalizedQueryString = ""
    for k, v in sortedParameters:
        canonicalizedQueryString += "&" + percent_encode(
            k) + "=" + percent_encode(v)

    # All aliyun API only support GET method
    stringToSign = "GET&%2F&" + percent_encode(canonicalizedQueryString[1:])

    h = hmac.new(to_bytes(access_key_secret + "&"), stringToSign, sha1)
    signature = base64.encodestring(h.digest()).strip()
    return signature
示例#4
0
def _toset(thing):
    """helper to convert various things to a set

    This enables flexibility in what users provide as the list of LDAP
    entry attribute values.  Note that the LDAP spec prohibits
    duplicate values in an attribute.

    RFC 2251 states that:
    "The order of attribute values within the vals set is undefined and
     implementation-dependent, and MUST NOT be relied upon."
    However, OpenLDAP have an X-ORDERED that is used in the config schema.
    Using sets would mean we can't pass ordered values and therefore can't
    manage parts of the OpenLDAP configuration, hence the use of OrderedSet.

    Sets are also good for automatically removing duplicates.

    None becomes an empty set.  Iterables except for strings have
    their elements added to a new set.  Non-None scalars (strings,
    numbers, non-iterable objects, etc.) are added as the only member
    of a new set.

    """
    if thing is None:
        return OrderedSet()
    if isinstance(thing, str):
        return OrderedSet((to_bytes(thing), ))
    if isinstance(thing, int):
        return OrderedSet((to_bytes(str(thing)), ))
    # convert numbers to strings and then bytes
    # so that equality checks work
    # (LDAP stores numbers as strings)
    try:
        return OrderedSet(
            to_bytes(str(x)) if isinstance(x, int) else to_bytes(x)
            for x in thing)
    except TypeError:
        return OrderedSet(str(thing), )
示例#5
0
    def test_archive_addwrite(self):
        '''
        Test add to the archive a section and write to it.

        :return:
        '''
        archive = MagicMock()
        with patch('salt.cli.support.collector.tarfile.TarFile', archive):
            self.collector.open()
            self.collector.add('foo')
            self.collector.write(title='title', data='data', output='null')
            self.collector._flush_content()

            assert (archive.bz2open().addfile.call_args[1]['fileobj'].read() ==
                    to_bytes('title\n-----\n\nraw-content: data\n\n\n\n'))
示例#6
0
    def test_archive_addlink(self):
        '''
        Test add to the archive a section and link an external file or directory to it.

        :return:
        '''
        archive = MagicMock()
        with patch('salt.cli.support.collector.tarfile.TarFile', archive):
            self.collector.open()
            self.collector.add('foo')
            self.collector.link(title='Backup Path', path='/path/to/backup.config')
            self.collector._flush_content()

            assert archive.bz2open().addfile.call_count == 1
            assert (archive.bz2open().addfile.call_args[1]['fileobj'].read()
                    == to_bytes('Backup Path\n-----------\n\npath=/dev/null\n\n\n'))
示例#7
0
def _update_entry(entry, status, directives):
    """Update an entry's attributes using the provided directives

    :param entry:
        A dict mapping each attribute name to a set of its values
    :param status:
        A dict holding cross-invocation status (whether delete_others
        is True or not, and the set of mentioned attributes)
    :param directives:
        A dict mapping directive types to directive-specific state
    """
    for directive, state in directives.items():
        if directive == "delete_others":
            status["delete_others"] = state
            continue
        for attr, vals in state.items():
            status["mentioned_attributes"].add(attr)
            vals = [to_bytes(val) for val in _toset(vals)]
            if directive == "default":
                if vals and (attr not in entry or not entry[attr]):
                    entry[attr] = vals
            elif directive == "add":
                vals.update(entry.get(attr, ()))
                if vals:
                    entry[attr] = vals
            elif directive == "delete":
                existing_vals = entry.pop(attr, OrderedSet())
                if vals:
                    existing_vals -= vals
                    if existing_vals:
                        entry[attr] = existing_vals
            elif directive == "replace":
                entry.pop(attr, None)
                if vals:
                    entry[attr] = vals
            else:
                raise ValueError("unknown directive: " + directive)
示例#8
0
 def _test_helper(self, init_db, expected_ret, replace, delete_others=False):
     _init_db(copy.deepcopy(init_db))
     old = _dump_db()
     new = _dump_db()
     expected_db = copy.deepcopy(init_db)
     for dn, attrs in replace.items():
         for attr, vals in attrs.items():
             vals = [to_bytes(val) for val in vals]
             if vals:
                 new.setdefault(dn, {})[attr] = list(OrderedSet(vals))
                 expected_db.setdefault(dn, {})[attr] = OrderedSet(vals)
             elif dn in expected_db:
                 new[dn].pop(attr, None)
                 expected_db[dn].pop(attr, None)
         if not expected_db.get(dn, {}):
             new.pop(dn, None)
             expected_db.pop(dn, None)
     if delete_others:
         dn_to_delete = OrderedSet()
         for dn, attrs in expected_db.items():
             if dn in replace:
                 to_delete = OrderedSet()
                 for attr, vals in attrs.items():
                     if attr not in replace[dn]:
                         to_delete.add(attr)
                 for attr in to_delete:
                     del attrs[attr]
                     del new[dn][attr]
                 if not attrs:
                     dn_to_delete.add(dn)
         for dn in dn_to_delete:
             del new[dn]
             del expected_db[dn]
     name = "ldapi:///"
     expected_ret["name"] = name
     expected_ret.setdefault("result", True)
     expected_ret.setdefault("comment", "Successfully updated LDAP entries")
     expected_ret.setdefault(
         "changes",
         {
             dn: {
                 "old": {
                     attr: vals
                     for attr, vals in old[dn].items()
                     if vals != new.get(dn, {}).get(attr, ())
                 }
                 if dn in old
                 else None,
                 "new": {
                     attr: vals
                     for attr, vals in new[dn].items()
                     if vals != old.get(dn, {}).get(attr, ())
                 }
                 if dn in new
                 else None,
             }
             for dn in replace
             if old.get(dn, {}) != new.get(dn, {})
         },
     )
     entries = [
         {dn: [{"replace": attrs}, {"delete_others": delete_others}]}
         for dn, attrs in replace.items()
     ]
     actual = salt.states.ldap.managed(name, entries)
     self.assertDictEqual(expected_ret, actual)
     self.assertDictEqual(expected_db, db)
示例#9
0
def _test_helper_add(db, expected_ret, add_items, delete_others=False):
    old = db.dump_db()
    new = db.dump_db()
    expected_db = copy.deepcopy(db.db)
    for dn, attrs in add_items.items():
        for attr, vals in attrs.items():
            vals = [to_bytes(val) for val in vals]

            vals.extend(old.get(dn, {}).get(attr, OrderedSet()))
            vals.sort()

            if vals:
                new.setdefault(dn, {})[attr] = list(OrderedSet(vals))
                expected_db.setdefault(dn, {})[attr] = OrderedSet(vals)
            elif dn in expected_db:
                new[dn].pop(attr, None)
                expected_db[dn].pop(attr, None)
        if not expected_db.get(dn, {}):
            new.pop(dn, None)
            expected_db.pop(dn, None)
    if delete_others:
        dn_to_delete = OrderedSet()
        for dn, attrs in expected_db.items():
            if dn in add_items:
                to_delete = OrderedSet()
                for attr, vals in attrs.items():
                    if attr not in add_items[dn]:
                        to_delete.add(attr)
                for attr in to_delete:
                    del attrs[attr]
                    del new[dn][attr]
                if not attrs:
                    dn_to_delete.add(dn)
        for dn in dn_to_delete:
            del new[dn]
            del expected_db[dn]
    name = "ldapi:///"
    expected_ret["name"] = name
    expected_ret.setdefault("result", True)
    expected_ret.setdefault("comment", "Successfully updated LDAP entries")
    expected_ret.setdefault(
        "changes",
        {
            dn: {
                "old": {
                    attr: vals
                    for attr, vals in old[dn].items()
                    if vals != new.get(dn, {}).get(attr, ())
                } if dn in old else None,
                "new": {
                    attr: vals
                    for attr, vals in new[dn].items()
                    if vals != old.get(dn, {}).get(attr, ())
                } if dn in new else None,
            }
            for dn in add_items if old.get(dn, {}) != new.get(dn, {})
        },
    )
    entries = [{
        dn: [{
            "add": attrs
        }, {
            "delete_others": delete_others
        }]
    } for dn, attrs in add_items.items()]
    actual = salt.states.ldap.managed(name, entries)
    assert expected_ret == actual
    assert expected_db == db.db