static void test_set_names(void) { EvalContext *ctx = EvalContextNew(); DetectDomainName(ctx, "laptop.intra"); assert_true(!EvalContextClassGet(ctx, NULL, "laptop_intra_cfengine_com")->is_soft); assert_true(!EvalContextClassGet(ctx, NULL, "intra_cfengine_com")->is_soft); assert_true(!EvalContextClassGet(ctx, NULL, "cfengine_com")->is_soft); assert_true(!EvalContextClassGet(ctx, NULL, "com")->is_soft); assert_true(!EvalContextClassGet(ctx, NULL, "laptop_intra")->is_soft); TestSysVar(ctx, "host", "laptop.intra"); TestSysVar(ctx, "fqhost", "laptop.intra.cfengine.com"); TestSysVar(ctx, "uqhost", "laptop.intra"); TestSysVar(ctx, "domain", "cfengine.com"); EvalContextDestroy(ctx); }
void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config) { GenericAgentSetDefaultDigest(&CF_DEFAULT_DIGEST, &CF_DEFAULT_DIGEST_LEN); GenericAgentInitialize(ctx, config); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); SanitizeEnvironment(); THIS_AGENT_TYPE = config->agent_type; EvalContextClassPutHard(ctx, CF_AGENTTYPES[config->agent_type], "cfe_internal,source=agent"); DetectEnvironment(ctx); EvalContextHeapPersistentLoadAll(ctx); LoadSystemConstants(ctx); if (config->agent_type == AGENT_TYPE_AGENT && config->agent_specific.agent.bootstrap_policy_server) { if (!RemoveAllExistingPolicyInInputs(GetInputDir())) { Log(LOG_LEVEL_ERR, "Error removing existing input files prior to bootstrap"); exit(EXIT_FAILURE); } if (!WriteBuiltinFailsafePolicy(GetInputDir())) { Log(LOG_LEVEL_ERR, "Error writing builtin failsafe to inputs prior to bootstrap"); exit(EXIT_FAILURE); } bool am_policy_server = false; { const char *canonified_bootstrap_policy_server = CanonifyName(config->agent_specific.agent.bootstrap_policy_server); am_policy_server = NULL != EvalContextClassGet(ctx, NULL, canonified_bootstrap_policy_server); { char policy_server_ipv4_class[CF_BUFSIZE]; snprintf(policy_server_ipv4_class, CF_MAXVARSIZE, "ipv4_%s", canonified_bootstrap_policy_server); am_policy_server |= NULL != EvalContextClassGet(ctx, NULL, policy_server_ipv4_class); } if (am_policy_server) { Log(LOG_LEVEL_INFO, "Assuming role as policy server, with policy distribution point at %s", GetMasterDir()); EvalContextClassPutHard(ctx, "am_policy_hub", "source=bootstrap"); if (!MasterfileExists(GetMasterDir())) { Log(LOG_LEVEL_ERR, "In order to bootstrap as a policy server, the file '%s/promises.cf' must exist.", GetMasterDir()); exit(EXIT_FAILURE); } } else { Log(LOG_LEVEL_INFO, "Not assuming role as policy server"); } WriteAmPolicyHubFile(CFWORKDIR, am_policy_server); } WritePolicyServerFile(GetWorkDir(), config->agent_specific.agent.bootstrap_policy_server); SetPolicyServer(ctx, config->agent_specific.agent.bootstrap_policy_server); /* FIXME: Why it is called here? Can't we move both invocations to before if? */ UpdateLastPolicyUpdateTime(ctx); Log(LOG_LEVEL_INFO, "Bootstrapping to '%s'", POLICY_SERVER); } else { char *existing_policy_server = ReadPolicyServerFile(GetWorkDir()); if (existing_policy_server) { Log(LOG_LEVEL_VERBOSE, "This agent is bootstrapped to '%s'", existing_policy_server); SetPolicyServer(ctx, existing_policy_server); free(existing_policy_server); UpdateLastPolicyUpdateTime(ctx); } else { Log(LOG_LEVEL_VERBOSE, "This agent is not bootstrapped"); return; } if (GetAmPolicyHub(GetWorkDir())) { EvalContextClassPutHard(ctx, "am_policy_hub", "source=bootstrap,deprecated,alias=policy_server"); Log(LOG_LEVEL_VERBOSE, "Additional class defined: am_policy_hub"); EvalContextClassPutHard(ctx, "policy_server", "inventory,attribute_name=CFEngine roles,source=bootstrap"); Log(LOG_LEVEL_VERBOSE, "Additional class defined: policy_server"); } } }
static PromiseResult VerifyEnvironments(EvalContext *ctx, Attributes a, const Promise *pp) { char hyper_uri[CF_MAXVARSIZE]; enum cfhypervisors envtype = cfv_none; switch (Str2Hypervisors(a.env.type)) { case cfv_virt_xen: case cfv_virt_xen_net: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "xen:///"); envtype = cfv_virt_xen; break; case cfv_virt_kvm: case cfv_virt_kvm_net: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "qemu:///session"); envtype = cfv_virt_kvm; break; case cfv_virt_esx: case cfv_virt_esx_net: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "esx://127.0.0.1"); envtype = cfv_virt_esx; break; case cfv_virt_test: case cfv_virt_test_net: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "test:///default"); envtype = cfv_virt_test; break; case cfv_virt_vbox: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "vbox:///session"); envtype = cfv_virt_vbox; break; case cfv_zone: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "solaris_zone"); envtype = cfv_zone; break; default: Log(LOG_LEVEL_ERR, "Environment type '%s' not currently supported", a.env.type); return PROMISE_RESULT_NOOP; break; } Log(LOG_LEVEL_VERBOSE, "Selecting environment type '%s' '%s'", a.env.type, hyper_uri); ClassRef environment_host_ref = ClassRefParse(a.env.host); if (!EvalContextClassGet(ctx, environment_host_ref.ns, environment_host_ref.name)) { switch (a.env.state) { case ENVIRONMENT_STATE_CREATE: case ENVIRONMENT_STATE_RUNNING: Log(LOG_LEVEL_VERBOSE, "This host ''%s' is not the promised host for the environment '%s', so setting its intended state to 'down'", VFQNAME, a.env.host); a.env.state = ENVIRONMENT_STATE_DOWN; break; default: Log(LOG_LEVEL_VERBOSE, "This is not the promised host for the environment, but it does not promise a run state, so take promise as valid"); } } ClassRefDestroy(environment_host_ref); virInitialize(); PromiseResult result = PROMISE_RESULT_NOOP; #if defined(__linux__) switch (Str2Hypervisors(a.env.type)) { case cfv_virt_xen: case cfv_virt_kvm: case cfv_virt_esx: case cfv_virt_vbox: case cfv_virt_test: result = PromiseResultUpdate(result, VerifyVirtDomain(ctx, hyper_uri, envtype, a, pp)); break; case cfv_virt_xen_net: case cfv_virt_kvm_net: case cfv_virt_esx_net: case cfv_virt_test_net: result = PromiseResultUpdate(result, VerifyVirtNetwork(ctx, hyper_uri, envtype, a, pp)); break; case cfv_ec2: break; case cfv_eucalyptus: break; default: break; } #elif defined(__APPLE__) switch (Str2Hypervisors(a.env.type)) { case cfv_virt_vbox: case cfv_virt_test: result = PromiseResultUpdate(result, VerifyVirtDomain(ctx, hyper_uri, envtype, a, pp)); break; case cfv_virt_xen_net: case cfv_virt_kvm_net: case cfv_virt_esx_net: case cfv_virt_test_net: result = PromiseResultUpdate(result, VerifyVirtNetwork(ctx, hyper_uri, envtype, a, pp)); break; default: break; } #elif defined(__sun) switch (Str2Hypervisors(a.env.type)) { case cfv_zone: result = PromiseResultUpdate(result, VerifyZone(a, pp)); break; default: break; } #else Log(LOG_LEVEL_VERBOSE, "Unable to resolve an environment supervisor/monitor for this platform, aborting"); #endif return result; }
void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config) { strcpy(VPREFIX, ""); Log(LOG_LEVEL_VERBOSE, " %s", NameVersion()); Banner("Initialization preamble"); GenericAgentSetDefaultDigest(&CF_DEFAULT_DIGEST, &CF_DEFAULT_DIGEST_LEN); GenericAgentInitialize(ctx, config); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); SanitizeEnvironment(); THIS_AGENT_TYPE = config->agent_type; LoggingSetAgentType(CF_AGENTTYPES[config->agent_type]); EvalContextClassPutHard(ctx, CF_AGENTTYPES[config->agent_type], "cfe_internal,source=agent"); DetectEnvironment(ctx); EvalContextHeapPersistentLoadAll(ctx); LoadSystemConstants(ctx); const char *bootstrap_arg = config->agent_specific.agent.bootstrap_policy_server; /* Are we bootstrapping the agent? */ if (config->agent_type == AGENT_TYPE_AGENT && bootstrap_arg != NULL) { EvalContextClassPutHard(ctx, "bootstrap_mode", "source=environment"); if (!RemoveAllExistingPolicyInInputs(GetInputDir())) { Log(LOG_LEVEL_ERR, "Error removing existing input files prior to bootstrap"); exit(EXIT_FAILURE); } if (!WriteBuiltinFailsafePolicy(GetInputDir())) { Log(LOG_LEVEL_ERR, "Error writing builtin failsafe to inputs prior to bootstrap"); exit(EXIT_FAILURE); } char canonified_ipaddr[strlen(bootstrap_arg) + 1]; StringCanonify(canonified_ipaddr, bootstrap_arg); bool am_policy_server = EvalContextClassGet(ctx, NULL, canonified_ipaddr) != NULL; if (am_policy_server) { Log(LOG_LEVEL_INFO, "Assuming role as policy server," " with policy distribution point at: %s", GetMasterDir()); MarkAsPolicyServer(ctx); if (!MasterfileExists(GetMasterDir())) { Log(LOG_LEVEL_ERR, "In order to bootstrap as a policy server," " the file '%s/promises.cf' must exist.", GetMasterDir()); exit(EXIT_FAILURE); } CheckAndSetHAState(GetWorkDir(), ctx); } else { Log(LOG_LEVEL_INFO, "Assuming role as regular client," " bootstrapping to policy server: %s", bootstrap_arg); if (config->agent_specific.agent.bootstrap_trust_server) { EvalContextClassPutHard(ctx, "trust_server", "source=agent"); Log(LOG_LEVEL_NOTICE, "Bootstrap mode: implicitly trusting server, " "use --trust-server=no if server trust is already established"); } } WriteAmPolicyHubFile(am_policy_server); WritePolicyServerFile(GetWorkDir(), bootstrap_arg); SetPolicyServer(ctx, bootstrap_arg); /* FIXME: Why it is called here? Can't we move both invocations to before if? */ UpdateLastPolicyUpdateTime(ctx); } else { char *existing_policy_server = ReadPolicyServerFile(GetWorkDir()); if (existing_policy_server) { Log(LOG_LEVEL_VERBOSE, "This agent is bootstrapped to: %s", existing_policy_server); SetPolicyServer(ctx, existing_policy_server); free(existing_policy_server); UpdateLastPolicyUpdateTime(ctx); } else { Log(LOG_LEVEL_VERBOSE, "This agent is not bootstrapped -" " can't find policy_server.dat in: %s", GetWorkDir()); return; } if (GetAmPolicyHub()) { MarkAsPolicyServer(ctx); /* Should this go in MarkAsPolicyServer() ? */ CheckAndSetHAState(GetWorkDir(), ctx); } } }
static void test_class_persistence(void) { EvalContext *ctx = EvalContextNew(); // simulate old version { CF_DB *dbp; PersistentClassInfo i; assert_true(OpenDB(&dbp, dbid_state)); i.expires = UINT_MAX; i.policy = CONTEXT_STATE_POLICY_RESET; WriteDB(dbp, "old", &i, sizeof(PersistentClassInfo)); CloseDB(dbp); } // e.g. by monitoring EvalContextHeapPersistentSave(ctx, "class1", 3, CONTEXT_STATE_POLICY_PRESERVE, "a,b"); // e.g. by a class promise in a bundle with a namespace { Policy *p = PolicyNew(); Bundle *bp = PolicyAppendBundle(p, "ns1", "bundle1", "agent", NULL, NULL); EvalContextStackPushBundleFrame(ctx, bp, NULL, false); EvalContextHeapPersistentSave(ctx, "class2", 5, CONTEXT_STATE_POLICY_PRESERVE, "x"); EvalContextStackPopFrame(ctx); PolicyDestroy(p); } EvalContextHeapPersistentLoadAll(ctx); { const Class *cls = EvalContextClassGet(ctx, "default", "old"); assert_true(cls != NULL); assert_string_equal("old", cls->name); assert_true(cls->tags != NULL); assert_int_equal(1, StringSetSize(cls->tags)); assert_true(StringSetContains(cls->tags, "source=persistent")); } { const Class *cls = EvalContextClassGet(ctx, "default", "class1"); assert_true(cls != NULL); assert_string_equal("class1", cls->name); assert_true(cls->tags != NULL); assert_int_equal(3, StringSetSize(cls->tags)); assert_true(StringSetContains(cls->tags, "source=persistent")); assert_true(StringSetContains(cls->tags, "a")); assert_true(StringSetContains(cls->tags, "b")); } { const Class *cls = EvalContextClassGet(ctx, "ns1", "class2"); assert_true(cls != NULL); assert_string_equal("ns1", cls->ns); assert_string_equal("class2", cls->name); assert_true(cls->tags != NULL); assert_int_equal(2, StringSetSize(cls->tags)); assert_true(StringSetContains(cls->tags, "source=persistent")); assert_true(StringSetContains(cls->tags, "x")); } EvalContextDestroy(ctx); }