def _get_yaml_diff(new_yaml=None, old_yaml=None):
    if not new_yaml and not old_yaml:
        return None

    old_str = yaml.serialize(old_yaml, default_flow_style=False)
    new_str = yaml.serialize(new_yaml, default_flow_style=False)
    return difflib.unified_diff(old_str.split('\n'), new_str.split('\n'))
Exemple #2
0
def run():
    """
    Serializes into YAML file.

    See `template.prepare` for context arguments on loading data, and
    `template.managed` for additional arguments when rendering the output.

    Arguments:

    root (str, optional): A colon separated string to nest all data before
        serializing to YAML.

    Example:

        /etc/app/config.yaml:
          file.managed:
            - template: py
            - source: salt://_templates/yaml2.py
            - context:
                source: app:config
                root: app:production
                default:
                  cache:
                    default: value

    Output:

        # Preamble

        app:
          production:
            cache:
              pillar: value
              default: value
    """
    args = globals().get("context", {})
    data = __salt__["template.prepare"](**args)

    if "root" in args:
        for level in reversed(args["root"].split(":")):
            data = {level: data}

    # sort_keys only exists in newer pyyaml versions
    if version_cmp(_pyyaml.__version__, "5.1") >= 0:
        out = yaml.serialize(data, default_flow_style=False, sort_keys=False)
    else:
        out = yaml.serialize(data, default_flow_style=False)

    return __salt__["template.managed"](out, **args)
    def test_serialize_yaml(self):
        data = {"foo": "bar", "encrypted_data": EncryptedString("foo")}
        serialized = yaml.serialize(data)
        assert serialized == '{encrypted_data: !encrypted foo, foo: bar}', serialized

        deserialized = yaml.deserialize(serialized)
        assert deserialized == data, deserialized
Exemple #4
0
    def test_serialize_yaml(self):
        data = {"foo": "bar"}
        serialized = yaml.serialize(data)
        assert serialized == '{foo: bar}', serialized

        deserialized = yaml.deserialize(serialized)
        assert deserialized == data, deserialized
Exemple #5
0
    def test_serialize_yaml(self):
        data = {
            "foo": "bar"
        }
        serialized = yaml.serialize(data)
        assert serialized == '{foo: bar}', serialized

        deserialized = yaml.deserialize(serialized)
        assert deserialized == data, deserialized
Exemple #6
0
    def test_serialize_yaml(self):
        data = {"foo": "bar", "encrypted_data": EncryptedString("foo")}
        # The C dumper produces unquoted strings when serializing an
        # EncryptedString, while the non-C dumper produces quoted strings.
        expected = '{encrypted_data: !encrypted foo, foo: bar}' \
            if hasattr(_yaml, 'CSafeDumper') \
            else "{encrypted_data: !encrypted 'foo', foo: bar}"
        serialized = yaml.serialize(data)
        assert serialized == expected, serialized

        deserialized = yaml.deserialize(serialized)
        assert deserialized == data, deserialized
Exemple #7
0
    def test_serialize_complex_sls(self):
        data = OrderedDict([("foo", 1), ("bar", 2), ("baz", True)])
        serialized = yamlex.serialize(data)
        assert serialized == "{foo: 1, bar: 2, baz: true}", serialized

        deserialized = yamlex.deserialize(serialized)
        assert deserialized == data, deserialized

        serialized = yaml.serialize(data)
        assert serialized == "{bar: 2, baz: true, foo: 1}", serialized

        deserialized = yaml.deserialize(serialized)
        assert deserialized == data, deserialized
Exemple #8
0
    def test_serialize_sls(self):
        data = {"foo": "bar"}
        serialized = yamlex.serialize(data)
        assert serialized == "{foo: bar}", serialized

        serialized = yamlex.serialize(data, default_flow_style=False)
        assert serialized == "foo: bar", serialized

        deserialized = yamlex.deserialize(serialized)
        assert deserialized == data, deserialized

        serialized = yaml.serialize(data)
        assert serialized == "{foo: bar}", serialized

        deserialized = yaml.deserialize(serialized)
        assert deserialized == data, deserialized

        serialized = yaml.serialize(data, default_flow_style=False)
        assert serialized == "foo: bar", serialized

        deserialized = yaml.deserialize(serialized)
        assert deserialized == data, deserialized
Exemple #9
0
    def test_compare_sls_vs_yaml_with_jinja(self):
        tpl = '{{ data }}'
        env = jinja2.Environment()
        src = '{foo: 1, bar: 2, baz: {qux: true}}'

        sls_src = env.from_string(tpl).render(data=yamlex.deserialize(src))
        yml_src = env.from_string(tpl).render(data=yaml.deserialize(src))

        sls_data = yamlex.deserialize(sls_src)
        yml_data = yaml.deserialize(yml_src)

        # ensure that sls & yaml have the same base
        assert isinstance(sls_data, dict)
        assert isinstance(yml_data, dict)
        # The below has been commented out because something the loader test
        # is modifying the yaml renderer to render things to unicode. Without
        # running the loader test, the below passes. Even reloading the module
        # from disk does not reset its internal state (per the Python docs).
        ##
        #assert sls_data == yml_data

        # ensure that sls is ordered, while yaml not
        assert isinstance(sls_data, OrderedDict)
        assert not isinstance(yml_data, OrderedDict)

        # prove that yaml does not handle well with OrderedDict
        # while sls is jinja friendly.
        obj = OrderedDict([
            ('foo', 1),
            ('bar', 2),
            ('baz', {'qux': True})
        ])

        sls_obj = yamlex.deserialize(yamlex.serialize(obj))
        try:
            yml_obj = yaml.deserialize(yaml.serialize(obj))
        except SerializationError:
            # BLAAM! yaml was unable to serialize OrderedDict,
            # but it's not the purpose of the current test.
            yml_obj = obj.copy()

        sls_src = env.from_string(tpl).render(data=sls_obj)
        yml_src = env.from_string(tpl).render(data=yml_obj)

        final_obj = yaml.deserialize(sls_src)
        assert obj == final_obj

        # BLAAM! yml_src is not valid !
        final_obj = OrderedDict(yaml.deserialize(yml_src))
        assert obj != final_obj
Exemple #10
0
    def test_compare_sls_vs_yaml_with_jinja(self):
        tpl = '{{ data }}'
        env = jinja2.Environment()
        src = '{foo: 1, bar: 2, baz: {qux: true}}'

        sls_src = env.from_string(tpl).render(data=yamlex.deserialize(src))
        yml_src = env.from_string(tpl).render(data=yaml.deserialize(src))

        sls_data = yamlex.deserialize(sls_src)
        yml_data = yaml.deserialize(yml_src)

        # ensure that sls & yaml have the same base
        assert isinstance(sls_data, dict)
        assert isinstance(yml_data, dict)
        # The below has been commented out because something the loader test
        # is modifying the yaml renderer to render things to unicode. Without
        # running the loader test, the below passes. Even reloading the module
        # from disk does not reset its internal state (per the Python docs).
        ##
        #assert sls_data == yml_data

        # ensure that sls is ordered, while yaml not
        assert isinstance(sls_data, OrderedDict)
        assert not isinstance(yml_data, OrderedDict)

        # prove that yaml does not handle well with OrderedDict
        # while sls is jinja friendly.
        obj = OrderedDict([
            ('foo', 1),
            ('bar', 2),
            ('baz', {'qux': True})
        ])

        sls_obj = yamlex.deserialize(yamlex.serialize(obj))
        try:
            yml_obj = yaml.deserialize(yaml.serialize(obj))
        except SerializationError:
            # BLAAM! yaml was unable to serialize OrderedDict,
            # but it's not the purpose of the current test.
            yml_obj = obj.copy()

        sls_src = env.from_string(tpl).render(data=sls_obj)
        yml_src = env.from_string(tpl).render(data=yml_obj)

        final_obj = yaml.deserialize(sls_src)
        assert obj == final_obj

        # BLAAM! yml_src is not valid !
        final_obj = OrderedDict(yaml.deserialize(yml_src))
        assert obj != final_obj
    def test_compare_sls_vs_yaml_with_jinja(self):
        tpl = '{{ data }}'
        env = jinja2.Environment()
        src = '{foo: 1, bar: 2, baz: {qux: true}}'

        sls_src = env.from_string(tpl).render(data=yamlex.deserialize(src))
        yml_src = env.from_string(tpl).render(data=yaml.deserialize(src))

        sls_data = yamlex.deserialize(sls_src)
        yml_data = yaml.deserialize(yml_src)

        # ensure that sls & yaml have the same base
        assert isinstance(sls_data, dict)
        assert isinstance(yml_data, dict)
        assert sls_data == yml_data

        # ensure that sls is ordered, while yaml not
        assert isinstance(sls_data, OrderedDict)
        assert not isinstance(yml_data, OrderedDict)

        # prove that yaml does not handle well with OrderedDict
        # while sls is jinja friendly.
        obj = OrderedDict([
            ('foo', 1),
            ('bar', 2),
            ('baz', {'qux': True})
        ])

        sls_obj = yamlex.deserialize(yamlex.serialize(obj))
        try:
            yml_obj = yaml.deserialize(yaml.serialize(obj))
        except SerializationError:
            # BLAAM! yaml was unable to serialize OrderedDict,
            # but it's not the purpose of the current test.
            yml_obj = obj.copy()

        sls_src = env.from_string(tpl).render(data=sls_obj)
        yml_src = env.from_string(tpl).render(data=yml_obj)

        final_obj = yaml.deserialize(sls_src)
        assert obj == final_obj

        # BLAAM! yml_src is not valid !
        final_obj = OrderedDict(yaml.deserialize(yml_src))
        assert obj != final_obj
Exemple #12
0
def add(princ,
        minion_id,
        tmp_keytab_dir='/root', 
        # CONFIGURE THESE!
        pillarstack_dir='/srv/pillar/keytabs/id/',
        keytab_prov_user='******', 
        keytab_prov_creds='/root/ktprov.keytab',
        kdc_type = 'mit',
        ad_dir = 'OU=Comps,OU=SomeOrg'):

  tmp_keytab = re.sub('[/@]', '_', princ) + '.keytab'
  fqdn = princ.split('/')[1].split('@')[0]
  # AD computer account name can only be 16 chars, select the last 14 of the principal
  ad_comp_name = "h-" + fqdn.split('.')[0][-14:]
  princ_type = princ.split('/')[0]
  krbDict = {'keytabs' : {tmp_keytab : ''}}
  id_yml = '{0}.yml'.format(minion_id)
  

  # Provision the principal
  if kdc_type == 'ad':
    subprocess.call('k5start {2} -f {3} -k /tmp/krbcc_keytab_state -- msktutil -b "{4}" -k {0}/{1} -h {5} -s {6} --computer-name {7}'.format(tmp_keytab_dir, tmp_keytab, keytab_prov_user, keytab_prov_creds, ad_dir, fqdn, princ_type, ad_comp_name), shell=True)
  else:
    subprocess.call('echo -e "ank -randkey {4}\nktadd -k {0}/{1} {4}" | kadmin -p {2} -k -t {3}'.format(tmp_keytab_dir, tmp_keytab, keytab_prov_user, keytab_prov_creds, princ), shell=True)

  # Add the principal to the minion's pillar
  with open('{0}/{1}'.format(tmp_keytab_dir, tmp_keytab), 'rb') as krbFile:
    krbDict['keytabs'][tmp_keytab] = base64.b64encode(krbFile.read())
  fh = open('{0}/{1}'.format(pillarstack_dir, id_yml), 'wb')
  fh.write(yaml.serialize(krbDict))
  fh.close()
  
  # Clean up temp keytab file
  os.remove('{0}/{1}'.format(tmp_keytab_dir, tmp_keytab))
  
  # Wait for the minion to grab the keytab, then remove it from pillar
  time.sleep(20)
  os.remove('{0}/{1}'.format(pillarstack_dir, id_yml))
Exemple #13
0
def test_reactor_is_leader(
    event_listener,
    salt_master,
    salt_run_cli,
    master_event_bus,
    reactor_event,
    salt_minion,
    event_listerner_timeout,
):
    """
    If reactor system is unavailable, an exception is thrown.
    When leader is true (the default), the reacion event should return.
    When leader is set to false reactor should timeout/not do anything.
    """
    ret = salt_run_cli.run("reactor.is_leader")
    assert ret.exitcode == 0
    assert (
        "salt.exceptions.CommandExecutionError: Reactor system is not running."
        in ret.stdout
    )

    ret = salt_run_cli.run("reactor.set_leader", value=True)
    assert ret.exitcode == 0
    assert (
        "salt.exceptions.CommandExecutionError: Reactor system is not running."
        in ret.stdout
    )

    ret = salt_run_cli.run("reactor.is_leader")
    assert ret.exitcode == 0
    assert (
        "salt.exceptions.CommandExecutionError: Reactor system is not running."
        in ret.stdout
    )

    # make reactor not the leader; ensure reactor engine is available
    engines_config = salt_master.config.get("engines").copy()
    for idx, engine in enumerate(list(engines_config)):
        if "reactor" in engine:
            engines_config.pop(idx)

    engines_config.append(
        {
            "reactor": {
                "refresh_interval": 60,
                "worker_threads": 10,
                "worker_hwm": 10000,
            }
        }
    )
    config_overrides = yaml.serialize({"engines": engines_config})
    confd_dir = (
        pathlib.Path(salt_master.config_dir)
        / pathlib.Path(salt_master.config["default_include"]).parent
    )
    confd_dir.mkdir(exist_ok=True)

    # Now, with the temp config in place, ensure the reactor engine is running
    with pytest.helpers.temp_file("reactor-test.conf", config_overrides, confd_dir):
        ret = salt_run_cli.run("reactor.set_leader", value=True)
        assert ret.exitcode == 0
        assert (
            "CommandExecutionError" not in ret.stdout
        ), "reactor engine is not running"

        ret = salt_run_cli.run("reactor.is_leader")
        assert ret.exitcode == 0
        assert ret.stdout.rstrip().splitlines()[-1] == "true"

        ret = salt_run_cli.run("reactor.set_leader", value=False)
        assert ret.exitcode == 0

        ret = salt_run_cli.run("reactor.is_leader")
        assert ret.exitcode == 0
        assert ret.stdout.rstrip().splitlines()[-1] == "false"

        start_time = time.time()
        master_event_bus.fire_event({"id": salt_minion.id}, reactor_event.tag)

        # Since leader is false, let's try and get the fire event to ensure it was triggered
        event_pattern = (salt_master.id, reactor_event.tag)
        matched_events = event_listener.wait_for_events(
            [event_pattern],
            after_time=start_time,
            timeout=event_listerner_timeout.catch,
        )
        assert matched_events.found_all_events
        # Now that we matched the trigger event, let's confirm we don't get the reaction event
        event_pattern = (salt_master.id, reactor_event.event_tag)
        matched_events = event_listener.wait_for_events(
            [event_pattern], after_time=start_time, timeout=event_listerner_timeout.miss
        )
        assert matched_events.found_all_events is not True

        # make reactor the leader again; ensure reactor engine is available
        ret = salt_run_cli.run("reactor.set_leader", value=True)
        assert ret.exitcode == 0
        ret = salt_run_cli.run("reactor.is_leader")
        assert ret.exitcode == 0
        assert ret.stdout.rstrip().splitlines()[-1] == "true"

        # trigger a reaction
        start_time = time.time()
        master_event_bus.fire_event({"id": salt_minion.id}, reactor_event.tag)
        event_pattern = (salt_master.id, reactor_event.event_tag)
        matched_events = event_listener.wait_for_events(
            [event_pattern],
            after_time=start_time,
            timeout=event_listerner_timeout.catch,
        )
        assert matched_events.found_all_events
        for event in matched_events:
            assert event.data["test_reaction"] is True

    # Let's just confirm the engine is not running once again(because the config file is deleted by now)
    ret = salt_run_cli.run("reactor.is_leader")
    assert ret.exitcode == 0
    assert (
        "salt.exceptions.CommandExecutionError: Reactor system is not running."
        in ret.stdout
    )