I recently had a problem where the Puppet environment for around 200 servers needed to be changed. It would normally be possible to make this change with Puppet by using some environment distinguishing feature, such as subnet. But this was not possible due to other environmental issues.
Puppet's documentation indicates that it is possible to use an external node classifier (ENC) to assign hosts to environments. The ENC is an application/script that accepts the node name as a sole argument, does some magic (calls the Spacewalk API in this instance), and spits out a YAML document.
The Python code below provides a very simple method of how to use Spacewalk system groups as Puppet environments via an ENC. It is not suitable for production use - it doesn't deal with issues where the Spacewalk server name is not fully qualified, duplicate servers, servers not grouped correctly etc.
#!/usr/bin/python from __future__ import print_function import xmlrpclib import sys def err(*objs): print("WARNING:", *objs, file=sys.stderr) sys.exit(1) def yaml(*objs): print("---\n environment:", *objs, file=sys.stdout) if len(sys.argv) > 2: err("too many arguments provided.") spacewalk_api = "https://spacewalk_server/rpc/api" spacewalk_user = "username" spacewalk_pass = "password" spacewalk_environments = ["env1", "env2", "env3"] api_client = xmlrpclib.Server(spacewalk_api, verbose=0) api_session_key = api_client.auth.login(spacewalk_user, spacewalk_pass) spacewalk_system = api_client.system.searchByName(api_session_key, "^" + sys.argv + "$") for puppet_environment in spacewalk_environments: environment_systems = api_client.systemgroup.listActiveSystemsInGroup(api_session_key, puppet_environment) if spacewalk_system["id"] in environment_systems: yaml(puppet_environment.lower())
The spacewalk_environments variable is set so that servers can be a member of multiple groups in Spacewalk, but only a selected few are used to determine the Puppet environment.