How to refresh foreman's knowledge of puppet environments from the command line?

Using Foreman 3.7 and Puppet 7.

Background:

I want to be able to make quick ad-hoc environments for testing of puppet code. However, I also want there to be a single source of truth for environment assignments; I don’t want hosts out in the infrastructure randomly switching to different environments.

Foreman is set up as an ENC (default, out of the box installation) and I am using r10k to deploy my manifests from all git branches into environments. Generally there is only production, plus whatever branch I am developing on, named according to the work I’m doing.

I can create the new environments (and delete the old) with r10k deploy environment -v -m (-m optional in most cases unless adding new modules to puppetfile). Deletion works this way also since I configured /etc/puppetlabs/r10k/r10k.yaml to contain:

deploy:
  purge_levels: [ 'deployment', 'environment', 'puppetfile' ]

I can check host environment assignments from the command line:

hammer host info --fields 'Puppet environment' --name server.example.com

And, I can sometimes set the environment on the command line as well:

hammer host update --name server.example.com --puppet-environment some_env

However, after creating a new branch in git, running r10k to create the corresponding environment, and then attempting to run the above update command, I get:

Could not update the host:
  Error: environment not found.

I can get around this by going into the Foreman UI, going to “environments” and clicking “import environments from puppetserver.example.com” (N.B.: the puppet server and foreman are the same server). However, I would like to avoid this step, and know how to do it in the command line instead.

So the question is: How can I refresh foreman’s knowledge of puppet environments from the command line?

(It’s worth mentioning, the out of date knowledge goes both ways: if I remove an environment, Foreman will still let me assign hosts to that environment until refreshed through the UI. I thought there should be something that automatically updates this, but running puppet on the foreman server didn’t do it.)

On a related note, is there an easy command-line way to show all environment-host assignments? Or all hosts in a given environment?

I couldn’t find anything in hammer to do this. I did figure out I can query it directly from postgres, with which I’m pretty familiar.

First in a root shell:

su - postgres

Then as postgres user:

PAGER=less LESS=-FRXSe PGDATABASE=foreman PSQL_EDITOR=vim psql

Then inside psql:

select h.name as hostname, e.name as environment from hosts h join host_puppet_facets hpf on (h.id = hpf.host_id) join environments e on (e.id = hpf.environment_id);

One line is nice for copy-paste but here is the formatted version:

select
  h.name as hostname,
  e.name as environment
from
  hosts h
  join host_puppet_facets hpf
    on (h.id = hpf.host_id)
  join environments e
    on (e.id = hpf.environment_id)
;

Great as it is—it would be nice not to have to go directly poking into internals like this. But maybe there is no better way at present?

(If there isn’t, I’ll probably end up writing my own wrapper script around postgres commands like the above.)

There is an API endpoint (or multiple to solve different usecases) to automatically do the import and also a hammer cli command.

The API endpoints are part of the smart_proxies namespace and so the cli command is also a subcommand of hammer proxy.

1 Like
hammer proxy import-classes --environment $environment_name --id $proxy_id --location-id $location_id

That’s what we use.

1 Like