Conversation
eee1717 to
f59574d
Compare
|
For "if A passed then also B needs to be passed" I thought the easiest would be to add a new metadata field And the validation is then wired up when Line 359 in 47d50e4 |
ekohl
left a comment
There was a problem hiding this comment.
Looks rather straight forward.
In Puppet we often use Integer[0] or String[1]. Have you thought about that? Would we create special types, like PositiveInteger and NonEmptyString?
obsah/data_types.py
Outdated
| Path type, accepting anything that looks like a path | ||
| """ | ||
| def validate(self, string): | ||
| return string |
There was a problem hiding this comment.
yeah, possible.
don't look too closely at the individual implementations, there are mostly there to show "it works" ;)
This is indeed something still on my in-brain todo list. Special types for these cases seem fine. I wonder if we also want to have things like |
It's rare for strings: $ rg 'String\[\d[,\d]' */manifests
puppet-foreman_proxy_content/manifests/init.pp
103: Optional[String[50]] $pulpcore_django_secret_key = undef,
puppet-foreman/manifests/settings_fragment.pp
13: String[2, 2] $order,
puppet-certs/manifests/foreman_proxy.pp
25: String[2,2] $country = $certs::country,
puppet-certs/manifests/ca.pp
7: String[2,2] $country = $certs::country,
puppet-certs/manifests/foreman.pp
11: String[2,2] $country = $certs::country,
puppet-certs/manifests/candlepin.pp
15: String[2,2] $country = $certs::country,
puppet-certs/manifests/apache.pp
57: String[2,2] $country = $certs::country,
puppet-certs/manifests/puppet.pp
11: String[2,2] $country = $certs::country,
puppet-certs/manifests/init.pp
77: String[2,2] $country = 'US',It's more common for integers, but even those are rare: $ rg 'Integer\[\d+,' */manifestspuppet-dns/manifests/logging/channel.pp
37: Integer[51, 59] $order = 51,
puppet-dns/manifests/logging/category.pp
10: Integer[51, 59] $order = 55,
puppet-foreman_proxy_content/manifests/init.pp
112: Optional[Integer[1,100]] $pulpcore_import_workers_percent = undef,
puppet-foreman_proxy/manifests/init.pp
376: Integer[0, 255] $dhcp_load_split = 255,
puppet-dhcp/manifests/failover.pp
36: Variant[Integer[0, 65535], String] $port = 519,
puppet-puppet/manifests/init.pp
606: Optional[Integer[0,23]] $run_hour = undef,
607: Variant[Integer[0,59], Array[Integer[0,59]], Undef] $run_minute = undef,
puppet-puppet/manifests/agent/service/cron.pp
5: Optional[Integer[0,23]] $hour = undef,
6: Variant[Integer[0,59], Array[Integer[0,59]], Undef] $minute = undef,
puppet-puppet/manifests/agent/service/systemd.pp
5: Optional[Integer[0,23]] $hour = undef,
6: Variant[Integer[0,59], Array[Integer[0,59]], Undef] $minute = undef,
puppet-foreman/manifests/dynflow/pool.pp
31: Integer[1, $instances].each |$n| {
puppet-foreman/manifests/repos/yum.pp
9: Variant[Integer[0, 99], Enum['absent']] $priority = 'absent',
puppet-foreman/manifests/plugin/supervisory_authority.pp
35: Integer[0,5] $log_level = 1,
puppet-pulpcore/manifests/init.pp
270: Optional[Integer[1,100]] $import_workers_percent = undef,
puppet-pulpcore/manifests/service.pp
42: Integer[1, $pulpcore::worker_count].each |$n| {Various are internal implementation details, one really should be |
yikes :) |
|
Let's not manage yum repos in this installer, shall we? ;) |
|
Yepp. From yesterdays "perforce's apt key expired" discussion in the vox channel: |
7e61977 to
dd1a46d
Compare
ba343eb to
a351b41
Compare
ekohl
left a comment
There was a problem hiding this comment.
I took the liberty to push a commit that uses a registry. Feel free to drop it if you don't like it.
|
I am not sure I like the registry -- the real one is in argparse anyway, so it seems double-registring… on the other hand, if it makes thing easier… |
I think it can make testing easier |
| on multiple lines | ||
|
|
||
| with an explicit newline | ||
| variables: |
There was a problem hiding this comment.
These are the Ansible variables being defined or the input parameters? If they are intended to be the latter, is it possible to change this nomenclature? I'm feeling the overuse of the term variables.
There was a problem hiding this comment.
the ansible vars. the parameter name is identical, unless you override it, like here:
obsah/tests/fixtures/playbooks/dummy/metadata.obsah.yaml
Lines 12 to 13 in 0d403fd
There was a problem hiding this comment.
How are you thinking about parameters that would map to multiple variables? Best example I could think of is something like --database-host where eventually it needs to map to foreman_database_host, candlepin_database_host, etc.
There was a problem hiding this comment.
ah, and it translates _ in vars to - in params, by default:
Lines 120 to 123 in 0d403fd
There was a problem hiding this comment.
How are you thinking about parameters that would map to multiple variables? Best example I could think of is something like
--database-hostwhere eventually it needs to map toforeman_database_host,candlepin_database_host, etc.
I'd thought of doing a variable/jinja layer. So the user gets --database-host that is translated to database_host and the others are defined as project_database_host: "{{ database_host }}"
(we have this aliasing in kafo too, we just don't use it)
| choices: | ||
| - journal | ||
| - file | ||
| constraints: |
There was a problem hiding this comment.
This constraint won't handle when a parameter's value determines mutually exclusive or required together.
I put this into the prototype (https://github.com/theforeman/foreman-quadlet/pull/131/files#diff-43fef5593cf5b8e6bad9b75f2bc286a354420a4d9891ff6c521d7192236c16f0R42) and that got me thinking about the database parameters. When we want to configure an external database we need to require the user specify at least database host. If we go with a parameter named --database-mode where the value of it determines the state, then we need some way to say that two parameters are required together but only if the value of that parameter is X. Similarly to be able to say if --database-mode is internal, then the user should not be able to set any of the other database parameters except maybe password.
There was a problem hiding this comment.
In Ansible (where I took the naming and the syntax from), there is required_if, that does what you want. We certainly could implement that too. Then you'd write something like
required_if:
- ['database_mode', 'external', ['database_host', 'database_port', …]]
There is no reverse of this in Ansible (as in, if database_mode is internal, you can't forbid setting host and port). But we could do something own (forbidden_if?)
There was a problem hiding this comment.
I have implemented required_if and forbidden_if.
b792c70 to
baf71e2
Compare
| for include in data.get('include', []): | ||
| include_path = os.path.join(self.application_config.playbooks_path(), include, self.application_config.metadata_name()) | ||
| include_data = self._load_metadata_file(include_path) | ||
| data['variables'] = data.get('variables', {}) | include_data.get('variables', {}) | ||
| data['constraints'] = data.get('constraints', {}) | include_data.get('constraints', {}) |
There was a problem hiding this comment.
I am abusing this PR for more experiments than just "typing", but here we are…
@ehelms wanted to have a way to have a composable CLI, that allows things like:
# mycli step1
# mycli step2
# mycli step3
but also
# mycli justdoit (runs steps 1, 2 and 3 under the hood)
today, to implement that, you'd create step1, step2 and step3 as individual playbook+metadata sets, but for justdoit you'd need to duplicate all the metadata -- especially all the variable definitions. (the same is of course true for playbooks, but these usually have a single role invocation anyway)
duplicating things sounds dangerous (what if we forget to expose a new var in one of the copies…)
the alternative is to provide "includes" for the metadata, in a similar fashion how you can include playbooks and roles, which these lines implement.
it intentionally doesn't do recursive inclusion and right now the included data wins over the original definition (if any).
is that too crazy?
There was a problem hiding this comment.
I think I would need to see an example of a command and then an includes command. Is it justdoit including the sub-commands? or the other way around?
There was a problem hiding this comment.
so assuming we deploy foreman, we have three steps: certs, foreman, proxy, you'd have something like this:
% tree
.
└── playbooks
├── certs
│ ├── certs.yaml
│ └── obsah.metadata.yaml
├── foreman
│ ├── foreman.yaml
│ └── obsah.metadata.yaml
├── install
│ ├── install.yaml
│ └── obsah.metadata.yaml
└── proxy
├── obsah.metadata.yaml
└── proxy.yaml
% for f in playbooks/*/*yaml; do echo "=== ${f} ==="; cat ${f}; done
=== playbooks/certs/certs.yaml ===
- hosts: localhost
roles:
- certs
=== playbooks/certs/obsah.metadata.yaml ===
help: certs generation
variables:
…
=== playbooks/foreman/foreman.yaml ===
- hosts: localhost
roles:
- foreman
=== playbooks/foreman/obsah.metadata.yaml ===
help: install foreman
variables:
…
=== playbooks/install/install.yaml ===
- hosts: localhost
roles:
- certs
- foreman
- proxy
=== playbooks/install/obsah.metadata.yaml ===
help: perform all installation steps
include:
- certs
- foreman
- proxy
=== playbooks/proxy/obsah.metadata.yaml ===
help: install proxy
variables:
…
=== playbooks/proxy/proxy.yaml ===
- hosts: localhost
roles:
- proxy
so, the "justdoit" (here "install") includes the others
There was a problem hiding this comment.
That reads reasonable to me. This is only composing metadata right? Would this mean everything needs to be encapsulated into roles, which means meta roles? I am thinking about how https://github.com/theforeman/foreman-quadlet/pull/119/files#diff-3413150b8dd202866a8852de783336a13f83155768b86fc4f353dcae2ae7f4df got structured where the playbook is split across the functions and has variable definitions in it.
There was a problem hiding this comment.
Building on that thought, how would you think about handling cases where the complexity of what's happening feels wrong to duplicate in two playbooks? For example, duplicating this logic for handling certificates feels error prone:
---
- name: Generate default certificates
hosts:
- quadlet
become: true
vars_files:
- "../../vars/{{ certificate_source }}_certificates.yml"
roles:
- role: certificates
when: "certificate_source == 'default'"
- role: foreman_installer_certs
when: "certificate_source == 'installer'"
- role: certificate_checks
vars:
certificate_checks_certificate: "{{ server_certificate }}"
certificate_checks_key: "{{ server_key }}"
certificate_checks_ca: "{{ ca_certificate }}"
There was a problem hiding this comment.
You don't need meta roles, no, you can still have a "hand full" in each playbook, overlapping.
Or we try import_playbook in install.yml (I didn't yet).
As for the complex example:
- I'd put the vars in a separate vars file that maps input names to role names (esp when we have multiple roles using the same input (think ext-db as my primary example)
- the
whenis more complicated -- probably import_playbook is the more correct answer here
|
Have you thought about default values? An example I was thinking through was where it the right place to define a default database password:
I feel like the Ansible level will require an "answer file" like object to exist to prevent overriding a users input. |
I have not, no. There is a task "look into this" on our todo list, but it hasn't been touched yet. |
|
Three other thoughts that came to mind:
Can we simplify the output to make the help more streamlined (this is cosmetic)? Looking at the example, I am not sure I understand the point of I would expect more of a: |
We did, but in a different context ("all of the params in the group need to be set", "one of the params in the group needs to be set"), and ended not implementing it as the "naive" constraints worked quite well.
I always hated that part of the installer cli :)
I can look whether this can be suppressed, but that's actually help/manpage convention to denote params that need a value (vs flag style things). |
d0f8fc3 to
5e6cc1f
Compare
Yes.
Fair - I just wonder about how we do not overwhelm but we can cross that bridge once we see the full extent of options.
Ahh interesting. Just poking around I see a few different styles for this: |
4399f4b to
cced844
Compare
No description provided.