Problem: How to determine machine role from the hostname using Cfengine? Data: My server hostnames contain location code, department code, type (web/db/etc.) and environment (stage/prod/dev).
For example: "lax-it-web01-prod01". Location: Los Angeles Department: IT Primary role: Web (first server) Environment: Production (first production environment) This model falls short when roles move from host to host, or additional roles are added to to an existing server. I don't have a host inventory database in my current environment. How to document which machine does what? Preferably in a way native to Cfengine. Solution 0. Setting classes based on hostnames is elementary functionality of Cfengine. So let's set a role class based on the hostname: # set a "webserver" class if hostname is lax-it-web01-prod01 classes: lax-it-web01-prod01:: "webserver"; Error! "Irreconcilable constraints in classes for webserver (broken promise)". I don't know what irreconcilable constraints are, in fact, there are no constraints here besides the class. Mark, is there something semantically wrong with the shorter version? It embodies my intention with nothing extra added. So then I added: # set a "webserver" class if hostname is lax-it-web01-prod01 classes: lax-it-web01-prod01:: "webserver" expression => "any"; and that worked, but now I've got "noise" in my config due to the added text. Is it possible to do without the mandatory explicit constraint, please? Let's continue with this example: Let me put my "who does what" config data in the Cfengine config: classes: lax-it-web01-prod01:: "webserver" expression => "any"; classes: lax-it-web01-prod01:: "nagios" expression => "any"; classes: lax-it-web02-prod01:: "webserver" expression => "any"; classes: lax-it-db01-prod01:: "postgres" expression => "any"; classes: lax-it-db01-prod01:: "zenoss" expression => "any"; If I want to do something on all nagios servers, I use the nagios:: class. If I want to identify all the roles on lax-it-web01-prod01 (for knowledge management), I would run a shell command like: grep '^classes: lax-it-web01-prod01::' who_does_what.cf | awk '{print $3}' Comments? Alternatives - store the config data OUTSIDE Cfengine: 1. My current method, with Cfengine 2, is to seed the role name into the hostname line in /etc/hosts -- this way it'll be set as a hard class when cfengine starts. For example, let's say the name is "lax-it-web01-prod01". /etc/hosts would read: xxx.xxx.xxx.xxx lax-it-web01-prod01 webserver nagios "webserver" and "nagios" are the roles. When I bring up a new instance, I have to edit /etc/hosts to add the role, and then Cfengine takes care of the rest of the configuration (based on the role). 2. Make a text file with hostnames and roles in them, and set up cfengine classes by running grep and parsing the output with regex. 3. Set up a database: make a table of hostnames and whether each host has (yes or no) each of all the possible roles. Read it from inside cfengine with a command-line database client and set up classes based on regex parsing of the output. 4. Put an /etc/roles file on each machine, and put roles into that file, one role per line, plain text, when roles are added to the server. Or make an /etc/roles/ directory, and touch /etc/roles/webserver, /etc/roles/nagios, etc. I am inclined to go with option 0, native to Cfengine, I just don't like the noise of 'expression => "any";' Could we please get rid of it? Best, -at _______________________________________________ Help-cfengine mailing list Help-cfengine@cfengine.org https://cfengine.org/mailman/listinfo/help-cfengine