############################################################
#
# The self-healing tower: Anti-Dominoes
#
#  This method works with Enterprise
#
#  If you want to test this on localhost, just edit /etc/hosts
#  to add host1 host2 host3 host4 as aliases to localhost
#
############################################################
body common control
{
  bundlesequence => { "weak_dependency_symphony" };
  inputs => { "$(sys.libdir)/stdlib.cf" };
}

body server control
{
  allowconnects => { "127.0.0.1", "::1", @(def.acl) };
  allowallconnects => { "127.0.0.1", "::1", @(def.acl) };
}

############################################################
bundle agent weak_dependency_symphony
{
  methods:
    # We have to seed the beginning by creating the tower
    # /tmp/tower_localhost
    host1::
      "tower"
        usebundle => tier1,
        classes => publish_ok("ok_O");

    host2::
      "tower"
        usebundle => tier2,
        classes => publish_ok("ok_1");

    host3::
      "tower"
        usebundle => tier3,
        classes => publish_ok("ok_2");

    host4::
      "tower"
        usebundle => tier4,
        classes => publish_ok("ok_f");

  classes:
    ok_O::
      # Wait for the methods, report on host1 only
      "check1" expression => remoteclassesmatching("ok.*", "host2", "yes", "a");
      "check2" expression => remoteclassesmatching("ok.*", "host3", "yes", "a");
      "check3" expression => remoteclassesmatching("ok.*", "host4", "yes", "a");

  reports:
    ok_O::
      "tier 1 is ok";

    a_ok_1::
      "tier 2 is ok";

    a_ok_2::
      "tier 3 is ok";

    a_ok_f::
      "tier 4 is ok";

    ok_O&a_ok_1&a_ok_2&a_ok_f::
      "The Tower is standing";

    !(ok_O&a_ok_1&a_ok_2&a_ok_f)::
      "The Tower is down";
}

############################################################
bundle agent tier1
{
  files:
    "/tmp/something_to_do_1" create => "true";
}

bundle agent tier2
{
  files:
    "/tmp/something_to_do_2" create => "true";
}

bundle agent tier3
{
  files:
    "/tmp/something_to_do_3" create => "true";
}

bundle agent tier4
{
  files:
    "/tmp/something_to_do_4" create => "true";
}

############################################################
bundle server access_rules()
{
  access:
    "ok.*"
      resource_type => "context",
      admit => { "127.0.0.1" };
}

############################################################
body classes publish_ok(x)
{
  promise_repaired => { "$(x)" };
  promise_kept => { "$(x)" };
  cancel_notkept => { "$(x)" };
  persist_time => "2";
}
