<p>I am trying to create my Role YAML file for Kubernetes and I am getting stuck with this specific section of the needed YAML:</p>

<pre><code>rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
</code></pre>

<p>I have tried to add it as a dictionary and then a list with a dictionary inside that for the -apiGroups line, but that then causes issues with the rest of the arguments for rules. I also am having issues with the [] showing up just like that when I am using yaml.dump even though I specify <code>default_flow_style=False</code></p>

<pre><code>def create_role_yml(role_filename, team_name, group_user):
    """
    https://kubernetes.io/docs/reference/
    access-authn-authz/rbac/#role-and-clusterrole
    """

    yml_file_kubernetes_data = dict(

        apiVersion='rbac.authorization.k8s.io/v1',
        kind='Role',
        metadata=dict(
            namespace=team_name,
            name=group_user,
            ),
        rules={
            [{'apiGroups':""}],
            'resourses': '[pods]',
            'verbs':'[get, watch, list]'}

        )

    with open(role_filename, 'w') as outfile:
        yaml.dump(yml_file_kubernetes_data, outfile, 
                  default_flow_style=False)
</code></pre>

<p>I would like to open the YAML and it to look exactly like the Kubernetes reference YAML: </p>

<pre><code>kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
</code></pre>

<p>but I am getting the [ ] seperated, and no - for apiGroup. This is my result:</p>

<pre><code>kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
apiGroups:
- "" # "" indicates the core API group
resources: 
- "pods"
verbs: 
-"get"
-"watch"
-"list"
</code></pre>

<p>What you try to do is not possible with the normal parameters you can hand to PyYAML's <code>dump()</code>,
which gives you only very course control using <code>default_flow_style</code></p>

<ul>
<li><code>True</code>: everything is flow style (JSON like)</li>
<li><code>False</code>: everything is block style</li>
<li><code>None</code>: leaf collections are flow style, and the rest block style</li>
</ul>

<p>You reference YAML has both block style leaf collections: the value
for the key <code>metadata</code>, as well as flow style leaf collections: the
value for the key <code>verbs</code>. Without hacking the representer you cannot
achieve this in PyYAML.</p>

<p>The way more easy way to generate YAML in your particular form is by
read-modify-write your expected YAML with a parser that knows how to
keep the formatting. You can do that with <code>ruamel.yaml</code>, which is
specifically developed to preserve these kind of things (disclaimer: I
am the author of that package).</p>

<p>If your input file is <code>input.yaml</code>:</p>

<pre><code>kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace:
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", 'list']
</code></pre>

<p>(the single entry under <code>metadata</code> is on purpose, but you could specify both, or none if
you assign instead of update)</p>

<p>And the following program:</p>

<pre><code>import sys
from pathlib import Path
import ruamel.yaml

yaml_str = """\
"""

in_file = Path("input.yaml")
out_file = Path("output.yaml")

team_name = "default"
group_user = "pod-reader"


yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
data = yaml.load(in_file)
data["metadata"].update(dict(namespace=team_name, name=group_user))
yaml.dump(data, out_file)
</code></pre>

<p>gives <code>output.yaml</code>:</p>

<pre><code>kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", 'list']
</code></pre>

<p>Please note that apart from the block/flow style, also the single/double quotes
from the original and the comment are preserved. Your indentation
already matches the default, so that is not explicity set (<code>yaml.indent(mapping=2, sequence=2, offset=0)</code>).</p>
