<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Operator SDK – Operator SDK Documentation</title>
    <link>/docs/</link>
    <description>Recent content in Operator SDK Documentation on Operator SDK</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    
	  <atom:link href="/docs/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Docs: Operator Best Practices</title>
      <link>/docs/best-practices/best-practices/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/best-practices/</guid>
      <description>
        
        
        &lt;h2 id=&#34;development&#34;&gt;Development&lt;/h2&gt;
&lt;p&gt;Considerations for Operator developers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An Operator should manage a single type of application, essentially following the UNIX principle: do one thing and do it well.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If an application consists of multiple tiers or components, multiple Operators should be written one for each of them. For example, if the application consists of Redis, AMQ, and MySQL, there should be 3 Operators, not one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If there is significant orchestration and sequencing involved, an Operator should be written that represents the entire stack, in turn delegating to other Operators for orchestrating their part of it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators should own a CRD and only one Operator should control a CRD on a cluster. Two Operators managing the same CRD is not a recommended best practice. An API that exists with multiple implementations is a typical example of a no-op Operator. The no-op Operator doesn&amp;rsquo;t have any deployment or reconciliation loop to define the shared API and other Operators depend on this Operator to provide one implementation of the API, e.g. similar to PVCs or Ingress.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Inside an Operator, multiple controllers should be used if multiple CRDs are managed. This helps in separation of concerns and code readability. Note that this doesn&amp;rsquo;t necessarily mean that we need to have one container image per controller, but rather one reconciliation loop (which could be running as part of the same Operator binary) per CRD.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An Operator shouldn&amp;rsquo;t deploy or manage other operators (such patterns are known as meta or super operators or include CRDs in its Operands). It&amp;rsquo;s the Operator Lifecycle Manager&amp;rsquo;s job to manage the deployment and lifecycle of operators. For further information check &lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/olm-architecture/dependency-resolution/&#34;&gt;Dependency Resolution&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If multiple operators are packaged and shipped as a single entity by the same CSV for example, then it is recommended to add all owned and required CRDs, as well as all deployments for operators that manage the owned CRDs, to the same CSV.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Writing an Operator involves using the Kubernetes API, which in most scenarios will be built using same boilerplate code. Use a framework like the Operator SDK to save yourself time with this and to also get a suite of tooling to ease development and testing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators shouldn’t make any assumptions about the namespace they are deployed in and they should not use hard-coded names of resources that they expect to already exist.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators shouldn’t hard code the namespaces they are watching. This should be configurable - having no namespace supplied is interpreted as watching all namespaces&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Semantic versioning (aka semver) should be used to version an Operator. Operators are long-running workloads on the cluster and its APIs are potentially in need of support over a longer period of time. Use the &lt;a href=&#34;https://semver.org&#34;&gt;semver.org guidelines&lt;/a&gt; to help determine when and how to bump versions when there are breaking or non-breaking changes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes API versioning guidelines should be used to version Operator CRDs. Use the &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md#so-you-want-to-change-the-api&#34;&gt;Kubernetes sig-architecture guidelines&lt;/a&gt; to get best practices on when to bump versions and when breaking changes are acceptable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When defining CRDs, you should use OpenAPI spec to create a structural schema for your CRDs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators are instrumented to provide useful, actionable metrics to external systems (e.g. monitoring/alerting platforms).  Minimally, metrics should represent the software&amp;rsquo;s health and key performance indicators, as well as support the creation of &lt;a href=&#34;https://en.wikipedia.org/wiki/Service_level_indicator&#34;&gt;service levels indicators&lt;/a&gt; such as throughput, latency, availability, errors, capacity, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators may create objects as part of their operational duty. Object accumulation can consume unnecessary resources, slow down the API and clutter the user interface. As such it is important for operators to keep good hygiene and to clean up resources when they are not needed. Here are instructions on &lt;a href=&#34;/docs/building-operators/golang/advanced-topics#handle-cleanup-on-deletion&#34;&gt;how to handle cleanup on deletion&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;One Operator per managed application&lt;/li&gt;
&lt;li&gt;Multiple operators should be used for complex, multi-tier application stacks&lt;/li&gt;
&lt;li&gt;CRD can only be owned by a single Operator, shared CRDs should be owned by a separate Operator&lt;/li&gt;
&lt;li&gt;One controller per custom resource definition&lt;/li&gt;
&lt;li&gt;Use a tool like Operator SDK&lt;/li&gt;
&lt;li&gt;Do not hard-code namespaces or resources names&lt;/li&gt;
&lt;li&gt;Make watch namespace configurable&lt;/li&gt;
&lt;li&gt;Use semver / observe Kubernetes guidelines on versioning APIs&lt;/li&gt;
&lt;li&gt;Use OpenAPI spec with structural schema on CRDs&lt;/li&gt;
&lt;li&gt;Operators expose metrics to external systems&lt;/li&gt;
&lt;li&gt;Operators cleanup resources on deletion&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;running-on-cluster&#34;&gt;Running On-Cluster&lt;/h2&gt;
&lt;p&gt;Considerations for on-cluster behavior&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Like all containers on Kubernetes, Operators need not run as root unless absolutely necessary. Operators should come with their own ServiceAccount and not rely on the &lt;code&gt;default&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators should not self-register their CRDs. These are global resources and careful consideration needs to be taken when setting those up. Also this requires the Operator to have global privileges which is potentially dangerous compared to that little extra convenience.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators use CRs as the primary interface to the cluster user. As such, at all times, meaningful status information should be written to those objects unless they are solely used to store data in a structured schema.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators should be updated frequently according to server versioning.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators need to support updating managed applications (Operands) that were set up by an older version of the Operator. There are multiple models for this:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Operator fan-out&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;where the Operator allows the user to specify the version in the custom resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;single version&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;where the Operator is tied to the version of the operand.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;hybrid approach&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;where the Operator is tied to a range of versions, and the user can select some level of the version.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An Operator should not deploy another Operator - an additional component on cluster should take care of this (OLM).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When Operators change their APIs, CRD conversion (webhooks) should be used to deal with potentially older instances of them using the previous API version.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators should make it easy for users to use their APIs - validating and rejecting malformed requests via extensive Open API validation schema on CRDs or via an admission webhook is good practice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Operator itself should be really modest in its requirements - it should always be able to deploy by deploying its controllers, no user input should be required to start up the Operator.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If user input is required to change the configuration of the Operator itself, a Configuration CRD should be used. Init-containers as part of the Operator deployments can be used to create a default instance of those CRs and then the Operator manages their lifecycle.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;summary-1&#34;&gt;Summary:&lt;/h3&gt;
&lt;p&gt;On the cluster, an Operator&amp;hellip;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does not run as root&lt;/li&gt;
&lt;li&gt;Does not self-register CRDs&lt;/li&gt;
&lt;li&gt;Does not install other Operators&lt;/li&gt;
&lt;li&gt;Does rely on dependencies via package manager (OLM)&lt;/li&gt;
&lt;li&gt;Writes meaningful status information on Custom Resources objects unless pure data structure&lt;/li&gt;
&lt;li&gt;Should be capable of updating from a previous version of the Operator&lt;/li&gt;
&lt;li&gt;Should be capable of managing an Operand from an older Operator version&lt;/li&gt;
&lt;li&gt;Uses CRD conversion (webhooks) if API/CRDs change&lt;/li&gt;
&lt;li&gt;Uses OpenAPI validation / Admission Webhooks to reject invalid CRs&lt;/li&gt;
&lt;li&gt;Should always be able to deploy and come up without user input&lt;/li&gt;
&lt;li&gt;Offers (pre)configuration via a &lt;code&gt;“Configuration CR”&lt;/code&gt; instantiated by InitContainers&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: OLM Integration Bundle Quickstart</title>
      <link>/docs/olm-integration/quickstart-bundle/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/quickstart-bundle/</guid>
      <description>
        
        
        &lt;p&gt;The &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/&#34;&gt;Operator Lifecycle Manager (OLM)&lt;/a&gt; is a set of cluster resources that manage the lifecycle of an Operator.
The Operator SDK supports both creating manifests for OLM deployment, and testing your Operator on an OLM-enabled
Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;This document is intended to quickly walk through the steps to generate an OLM bundle. For further explanation,
or if you&amp;rsquo;re using package manifests, see the &lt;a href=&#34;/docs/olm-integration/tutorial-bundle&#34;&gt;Bundle Tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; this guide assumes your project was scaffolded with &lt;code&gt;operator-sdk init --project-version=3&lt;/code&gt;.
These features are unavailable to projects of version &lt;code&gt;2&lt;/code&gt; or less; this information can be found by inspecting
your &lt;code&gt;PROJECT&lt;/code&gt; file&amp;rsquo;s &lt;code&gt;version&lt;/code&gt; value.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Have a working operator that you have uploaded to a container registry. This guide assumes the simple Golang Memcached operator from &lt;a href=&#34;/docs/building-operators/golang/quickstart&#34;&gt;the building operators section&lt;/a&gt; at version &lt;code&gt;0.0.1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Make sure your user is authorized with &lt;code&gt;cluster-admin&lt;/code&gt; permissions.&lt;/li&gt;
&lt;li&gt;Have OLM installed on your cluster. The command &lt;code&gt;operator-sdk olm install&lt;/code&gt; will attempt to install a basic OLM deployment on your cluster.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;steps&#34;&gt;Steps&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Export environment variables&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ &lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;USERNAME&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&amp;lt;container-registry-username&amp;gt;
$ &lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;VERSION&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;0.0.1
$ &lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;docker.io/&lt;span style=&#34;color:#000&#34;&gt;$USERNAME&lt;/span&gt;/memcached-operator:v&lt;span style=&#34;color:#000&#34;&gt;$VERSION&lt;/span&gt; // location where your operator image is hosted
$ &lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;BUNDLE_IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;docker.io/&lt;span style=&#34;color:#000&#34;&gt;$USERNAME&lt;/span&gt;/memcached-operator-bundle:v&lt;span style=&#34;color:#000&#34;&gt;$VERSION&lt;/span&gt; // location where your bundle will be hosted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Create a bundle from the root directory of your project&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ make bundle
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will prompt you to enter basic information about your operator.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Build and push the bundle image&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ make bundle-build bundle-push
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Validate the bundle&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ operator-sdk bundle validate &lt;span style=&#34;color:#000&#34;&gt;$BUNDLE_IMG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Install the bundle with OLM&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ operator-sdk run bundle &lt;span style=&#34;color:#000&#34;&gt;$BUNDLE_IMG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Read the &lt;a href=&#34;/docs/olm-integration/tutorial-bundle&#34;&gt;full tutorial&lt;/a&gt; for a more in-depth look at creating and using a bundle.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: OLM Integration Bundle Tutorial</title>
      <link>/docs/olm-integration/tutorial-bundle/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/tutorial-bundle/</guid>
      <description>
        
        
        &lt;p&gt;The &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/&#34;&gt;Operator Lifecycle Manager (OLM)&lt;/a&gt; is a set of cluster resources that manage the lifecycle of an Operator.
The Operator SDK supports both creating manifests for OLM deployment, and testing your Operator on an OLM-enabled
Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;This document succinctly walks through getting an Operator OLM-ready with &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundles&lt;/a&gt;, and glosses over
explanations of certain steps for brevity. The following documents contain more detail on these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All operator-framework manifest commands supported by the SDK: &lt;a href=&#34;/docs/olm-integration/cli-overview&#34;&gt;CLI overview&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Generating operator-framework manifests: &lt;a href=&#34;/docs/olm-integration/generation&#34;&gt;generation overview&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are working with package manifests, see the &lt;a href=&#34;/docs/olm-integration/tutorial-package-manifests&#34;&gt;package manifests tutorial&lt;/a&gt;
once you have completed the &lt;em&gt;Setup&lt;/em&gt; section below.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; this guide assumes your project was scaffolded with &lt;code&gt;operator-sdk init --project-version=3&lt;/code&gt;.
These features are unavailable to projects of version &lt;code&gt;2&lt;/code&gt; or less; this information can be found by inspecting
your &lt;code&gt;PROJECT&lt;/code&gt; file&amp;rsquo;s &lt;code&gt;version&lt;/code&gt; value.&lt;/p&gt;
&lt;h2 id=&#34;setup&#34;&gt;Setup&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s first walk through creating an Operator for &lt;code&gt;memcached&lt;/code&gt;, a distributed key-value store.&lt;/p&gt;
&lt;p&gt;Follow one of the user guides to develop the memcached-operator in either &lt;a href=&#34;/docs/building-operators/golang/quickstart&#34;&gt;Go&lt;/a&gt;,
&lt;a href=&#34;/docs/building-operators/ansible/quickstart&#34;&gt;Ansible&lt;/a&gt;, or &lt;a href=&#34;/docs/building-operators/helm/quickstart&#34;&gt;Helm&lt;/a&gt;, depending on which Operator type you are interested in.
This guide assumes memcached-operator is on version &lt;code&gt;0.0.1&lt;/code&gt;, which is set in the &lt;code&gt;Makefile&lt;/code&gt; variable &lt;code&gt;VERSION&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;enabling-olm&#34;&gt;Enabling OLM&lt;/h3&gt;
&lt;p&gt;Ensure OLM is enabled on your cluster before following this guide. &lt;a href=&#34;/docs/cli/operator-sdk_olm&#34;&gt;&lt;code&gt;operator-sdk olm&lt;/code&gt;&lt;/a&gt;
has several subcommands that can install, uninstall, and check the status of particular OLM versions in a cluster.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Certain cluster types may already have OLM enabled, but under a non-default (&lt;code&gt;&amp;quot;olm&amp;quot;&lt;/code&gt;) namespace,
which can be configured by setting &lt;code&gt;--olm-namespace=[non-default-olm-namespace]&lt;/code&gt; for &lt;code&gt;operator-sdk olm status|uninstall&lt;/code&gt; subcommands.&lt;/p&gt;
&lt;p&gt;You can check if OLM is already installed by running the following command,
which will detect the installed OLM version automatically (0.15.1 in this example):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk olm status
INFO[0000] Fetching CRDs for version &amp;quot;0.15.1&amp;quot;
INFO[0002] Fetching resources for version &amp;quot;0.15.1&amp;quot;
INFO[0002] Successfully got OLM status for version &amp;quot;0.15.1&amp;quot;

NAME                                            NAMESPACE    KIND                        STATUS
olm                                                          Namespace                   Installed
operatorgroups.operators.coreos.com                          CustomResourceDefinition    Installed
catalogsources.operators.coreos.com                          CustomResourceDefinition    Installed
subscriptions.operators.coreos.com                           CustomResourceDefinition    Installed
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All resources listed should have status &lt;code&gt;Installed&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;operator-sdk olm status&lt;/code&gt; command is geared to detect the status of OLM that was installed by installation methods like &lt;code&gt;operator-sdk olm install&lt;/code&gt; or by applying OLM &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/master/deploy/upstream/quickstart/olm.yaml&#34;&gt;manifests&lt;/a&gt; directly on the cluster. This command retrieves the resources that were compiled into SDK at the time of installation from the OLM &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/master/deploy/upstream/quickstart/olm.yaml&#34;&gt;manifests&lt;/a&gt;. However, if OLM was installed in a cluster in a custom fashion (such as in OpenShift clusters), it is possible that some resources will show a &lt;code&gt;Not Found&lt;/code&gt; status when the &lt;code&gt;operator-sdk olm status&lt;/code&gt; command is issued.&lt;/p&gt;
&lt;p&gt;To check the true status of such resources in OCP clusters, run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;oc get &amp;lt;resource-name&amp;gt; -n &amp;lt;resource-namespace&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If OLM is not already installed, go ahead and install the latest version:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk olm install
INFO[0000] Fetching CRDs for version &amp;quot;latest&amp;quot;
INFO[0001] Fetching resources for version &amp;quot;latest&amp;quot;
INFO[0007] Creating CRDs and resources
INFO[0007]   Creating CustomResourceDefinition &amp;quot;clusterserviceversions.operators.coreos.com&amp;quot;
INFO[0007]   Creating CustomResourceDefinition &amp;quot;installplans.operators.coreos.com&amp;quot;
INFO[0007]   Creating CustomResourceDefinition &amp;quot;subscriptions.operators.coreos.com&amp;quot;
...
NAME                                            NAMESPACE    KIND                        STATUS
clusterserviceversions.operators.coreos.com                  CustomResourceDefinition    Installed
installplans.operators.coreos.com                            CustomResourceDefinition    Installed
subscriptions.operators.coreos.com                           CustomResourceDefinition    Installed
catalogsources.operators.coreos.com                          CustomResourceDefinition    Installed
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; By default, &lt;code&gt;olm status&lt;/code&gt; and &lt;code&gt;olm uninstall&lt;/code&gt; auto-detect the OLM version installed in your cluster.
This can fail if the installation is broken in some way, so the version of OLM can be overridden using the
&lt;code&gt;--version&lt;/code&gt; flag provided with these commands.&lt;/p&gt;
&lt;h2 id=&#34;creating-a-bundle&#34;&gt;Creating a bundle&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;If working with package manifests, see the &lt;a href=&#34;/docs/olm-integration/tutorial-package-manifests&#34;&gt;package manifests tutorial&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We will now create bundle manifests by running &lt;code&gt;make bundle&lt;/code&gt; in the root of the memcached-operator project.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle
/home/user/go/bin/controller-gen rbac:roleName=manager-role crd webhook paths=&amp;quot;./...&amp;quot; output:crd:artifacts:config=config/crd/bases
operator-sdk generate kustomize manifests -q
kustomize build config/manifests | operator-sdk generate bundle -q --overwrite --version 0.0.1
INFO[0000] Building annotations.yaml
INFO[0000] Writing annotations.yaml in /home/user/go/src/github.com/test-org/memcached-operator/bundle/metadata
INFO[0000] Building Dockerfile
INFO[0000] Writing bundle.Dockerfile in /home/user/go/src/github.com/test-org/memcached-operator
operator-sdk bundle validate ./bundle
INFO[0000] Found annotations file                        bundle-dir=bundle container-tool=docker
INFO[0000] Could not find optional dependencies file     bundle-dir=bundle container-tool=docker
INFO[0000] All validation tests have completed successfully
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above command will have created the following bundle artifacts: a manifests directory
(&lt;code&gt;bundle/manifests&lt;/code&gt;) containing a CSV and all CRDs from &lt;code&gt;config/crds&lt;/code&gt;, &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.12.6/docs/design/operator-bundle.md#bundle-annotations&#34;&gt;metadata&lt;/a&gt;
directory (&lt;code&gt;bundle/metadata&lt;/code&gt;), and &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.12.6/docs/design/operator-bundle.md#bundle-dockerfile&#34;&gt;&lt;code&gt;bundle.Dockerfile&lt;/code&gt;&lt;/a&gt; have been created in
the Operator project. These files have been statically validated by &lt;code&gt;operator-sdk bundle validate&lt;/code&gt;
to ensure the on-disk bundle representation is correct.&lt;/p&gt;
&lt;h2 id=&#34;deploying-an-operator-with-olm&#34;&gt;Deploying an Operator with OLM&lt;/h2&gt;
&lt;p&gt;At this point in development we&amp;rsquo;ve generated all files necessary to build the memcached-operator bundle.
Now we&amp;rsquo;re ready to test and deploy the Operator with OLM.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If testing a bundle whose image will be hosted in a registry that is private and/or
has a custom CA, these &lt;a href=&#34;/docs/olm-integration/cli-overview#private-bundle-and-catalog-image-registries&#34;&gt;configuration steps&lt;/a&gt; must be complete.&lt;/p&gt;
&lt;h3 id=&#34;testing-bundles&#34;&gt;Testing bundles&lt;/h3&gt;
&lt;p&gt;Before proceeding, make sure you&amp;rsquo;ve &lt;a href=&#34;#enabling-olm&#34;&gt;Installed OLM&lt;/a&gt; onto your
cluster.&lt;/p&gt;
&lt;p&gt;First, we need to build our bundle. To build a memcached-operator bundle, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle-build bundle-push BUNDLE_IMG=&amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now that the bundle image is present in a registry, &lt;a href=&#34;/docs/cli/operator-sdk_run_bundle&#34;&gt;&lt;code&gt;operator-sdk run bundle&lt;/code&gt;&lt;/a&gt;
can create a pod to serve that bundle to OLM via a &lt;a href=&#34;https://olm.operatorframework.io/docs/tasks/install-operator-with-olm/#install-your-operator&#34;&gt;&lt;code&gt;Subscription&lt;/code&gt;&lt;/a&gt;,
along with other OLM objects, ephemerally.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk run bundle &amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.1
INFO[0008] Successfully created registry pod: &amp;lt;some-registry&amp;gt;-memcached-operator-bundle-0-0-1
INFO[0008] Created CatalogSource: memcached-operator-catalog
INFO[0008] OperatorGroup &amp;quot;operator-sdk-og&amp;quot; created
INFO[0008] Created Subscription: memcached-operator-v0-0-1-sub
INFO[0019] Approved InstallPlan install-krv7q for the Subscription: memcached-operator-v0-0-1-sub
INFO[0019] Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; to reach &#39;Succeeded&#39; phase
INFO[0019]   Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; to appear
INFO[0031]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Pending
INFO[0032]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Installing
INFO[0040]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Succeeded
INFO[0040] OLM has successfully installed &amp;quot;memcached-operator.v0.0.1&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If the bundle that is being installed has dependencies, the &lt;code&gt;--index-image&lt;/code&gt; flag allows adding a bundle to a catalog that contains that bundle&amp;rsquo;s dependencies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Version &lt;code&gt;v1.22.0&lt;/code&gt; and later of the &lt;code&gt;operator-sdk&lt;/code&gt; use the new file-based catalog (FBC) bundle format by default. Earlier releases use the deprecated SQLite bundle format. If you use an earlier version of the Operator SDK, you must update to a newer version or specify the index image by adding the &lt;code&gt;--index-image=quay.io/operator-framework/opm:v1.23.0&lt;/code&gt; flag. For more information about this known issue, see the &lt;a href=&#34;https://sdk.operatorframework.io/docs/faqs/#operator-sdk-run-bundle-command-fails-and-the-registry-pod-has-an-error-of-mkdir-cant-create-directory-database-permission-denied&#34;&gt;FAQ&lt;/a&gt;.&lt;/p&gt;
&lt;!-- TODO(jmccormick2001): add `scorecard` usage here --&gt;
&lt;h3 id=&#34;upgrading-a-bundle-to-a-newer-version&#34;&gt;Upgrading a bundle to a newer version&lt;/h3&gt;
&lt;p&gt;We can use the &lt;code&gt;operator-sdk run bundle-upgrade&lt;/code&gt; command with a newer version of bundle image to upgrade
an existing operator bundle deployed on cluster. The command automates the manual orchestration typically required to upgrade an operator
from one version to another. It extracts the package name from bundle, finds the existing subscription, updates the catalog
source, deletes the existing registry pod and creates a new registry pod with the version of bundle image provided in the command.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s upgrade the previously deployed memcached-operator bundle from version &lt;code&gt;0.0.1&lt;/code&gt; to &lt;code&gt;0.0.2&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk run bundle-upgrade &amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.2
INFO[0002] Found existing subscription with name memcached-operator-bundle-0-0-1-sub and namespace default
INFO[0002] Found existing catalog source with name memcached-operator-catalog and namespace default
INFO[0007] Successfully created registry pod: &amp;lt;some-registry&amp;gt;-memcached-operator-bundle-0-0-2
INFO[0007] Updated catalog source memcached-operator-catalog with address and annotations
INFO[0008] Deleted previous registry pod with name &amp;quot;&amp;lt;some-registry&amp;gt;-memcached-operator-bundle-0-0-1&amp;quot;
INFO[0050] Approved InstallPlan install-c8fkh for the Subscription: memcached-operator-bundle-0-0-1-sub
INFO[0050] Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; to reach &#39;Succeeded&#39; phase
INFO[0050]   Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; to appear
INFO[0052]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; phase: Pending
INFO[0057]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; phase: InstallReady
INFO[0058]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; phase: Installing
INFO[0095]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; phase: Succeeded
INFO[0095] Successfully upgraded to &amp;quot;memcached-operator.v0.0.2&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If a bundle was installed using &lt;a href=&#34;https://sdk.operatorframework.io/docs/cli/operator-sdk_run_bundle/&#34;&gt;&lt;code&gt;operator-sdk run bundle&lt;/code&gt;&lt;/a&gt; with a SQLite index image, the &lt;code&gt;replaces&lt;/code&gt; field &lt;em&gt;must&lt;/em&gt; be present and populated in the upgraded CSV&amp;rsquo;s spec.&lt;/p&gt;
&lt;h4 id=&#34;upgrading-a-bundle-that-was-installed-traditionally-using-olm&#34;&gt;Upgrading a bundle that was installed traditionally using OLM&lt;/h4&gt;
&lt;p&gt;An operator bundle can be upgraded even if it was originally deployed using OLM without using the &lt;code&gt;run bundle&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see how to deploy an operator bundle traditionally using OLM and then upgrade the operator bundle to a newer version.&lt;/p&gt;
&lt;p&gt;First, create a CatalogSource by building the CatalogSource from a catalog.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ oc create -f catalogsource.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# catalogsource.yaml&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;operators.coreos.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;CatalogSource&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;etcdoperator&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;displayName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Etcd&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Operators&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&amp;lt;some-registry&amp;gt;/etcd-catalog&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;latest&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;sourceType&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;grpc&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, install the operator bundle by creating a subscription.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ oc create -f subscription.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# subscription.yaml&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;items&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;operators.coreos.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Subscription&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;etcd&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;channel&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;stable&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;installPlanApproval&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Manual&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;etcd&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;source&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;etcdoperator&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;sourceNamespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;startingCSV&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;etcdoperator.v0&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;.0.1&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the Operator bundle is deployed, you can use the &lt;code&gt;run bundle-upgrade&lt;/code&gt; command by specifying the new bundle image that you want to upgrade to.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk run bundle-upgrade &amp;lt;some-registry&amp;gt;/etcd-bundle:v0.0.2
INFO[0000] Found existing subscription with name etcd and namespace default
INFO[0000] Found existing catalog source with name etcdoperator and namespace default
INFO[0005] Successfully created registry pod: &amp;lt;some-registry&amp;gt;-etcd-bundle-0-0-2
INFO[0005] Updated catalog source etcdoperator with address and annotations
INFO[0005] Deleted previous registry pod with name &amp;quot;&amp;lt;some-registry&amp;gt;-etcd-bundle-0-0-1&amp;quot;
INFO[0005] Approved InstallPlan install-6vrzh for the Subscription: etcd
INFO[0005] Waiting for ClusterServiceVersion &amp;quot;default/etcdoperator.v0.0.2&amp;quot; to reach &#39;Succeeded&#39; phase
INFO[0005]   Waiting for ClusterServiceVersion &amp;quot;default/etcdoperator.v0.0.2&amp;quot; to appear
INFO[0007]   Found ClusterServiceVersion &amp;quot;default/etcdoperator.v0.0.2&amp;quot; phase: Pending
INFO[0008]   Found ClusterServiceVersion &amp;quot;default/etcdoperator.v0.0.2&amp;quot; phase: Installing
INFO[0018]   Found ClusterServiceVersion &amp;quot;default/etcdoperator.v0.0.2&amp;quot; phase: Succeeded
INFO[0018] Successfully upgraded to &amp;quot;etcdoperator.v0.0.2&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;deploying-bundles-in-production&#34;&gt;Deploying bundles in production&lt;/h3&gt;
&lt;p&gt;OLM and Operator Registry consumes Operator bundles via a catalog of Operators, implemented as an
&lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/master/docs/design/opm-tooling.md#index&#34;&gt;index image&lt;/a&gt;, which are composed of one or more bundles. To build and push a
memcached-operator bundle image for version v0.0.1, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle-build bundle-push BUNDLE_IMG=&amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you can build and push the catalog by running &lt;code&gt;catalog-*&lt;/code&gt; Makfile targets, which use
the Operator package manager tool &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/master/docs/design/opm-tooling.md&#34;&gt;&lt;code&gt;opm&lt;/code&gt;&lt;/a&gt; to &lt;a href=&#34;https://github.com/operator-framework/operator-registry#building-an-index-of-operators-using-opm&#34;&gt;build&lt;/a&gt; the catalog:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make catalog-build catalog-push CATALOG_IMG=&amp;lt;some-registry&amp;gt;/memcached-operator-catalog:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Assuming &lt;code&gt;IMAGE_TAG_BASE = &amp;lt;some-registry&amp;gt;/memcached-operator&lt;/code&gt; has the desired tag base, you can inline
the above two commands to:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle-build bundle-push catalog-build catalog-push
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which will build and push both &lt;code&gt;&amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.1&lt;/code&gt;
and &lt;code&gt;&amp;lt;some-registry&amp;gt;/memcached-operator-catalog:v0.0.1&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;/h2&gt;
&lt;p&gt;In-depth discussions of OLM concepts mentioned here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/crds/catalogsource/&#34;&gt;CatalogSource&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/crds/subscription/&#34;&gt;Subscription&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://olm.operatorframework.io/docs/tasks/install-operator-with-olm/&#34;&gt;Install an Operator from a catalog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Development</title>
      <link>/docs/contribution-guidelines/developer-guide/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/contribution-guidelines/developer-guide/</guid>
      <description>
        
        
        &lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;h3 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://git-scm.com/downloads&#34;&gt;git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://golang.org/dl/&#34;&gt;go&lt;/a&gt; version 1.23&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;download-operator-sdk&#34;&gt;Download Operator SDK&lt;/h3&gt;
&lt;p&gt;Go to the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk&#34;&gt;operator-sdk repo&lt;/a&gt; and follow the &lt;a href=&#34;https://docs.github.com/en/get-started/quickstart/fork-a-repo&#34;&gt;fork guide&lt;/a&gt; to fork and set up a local repository.&lt;/p&gt;
&lt;h3 id=&#34;build-the-operator-sdk-cli&#34;&gt;Build the Operator SDK CLI&lt;/h3&gt;
&lt;p&gt;Build the Operator SDK CLI &lt;code&gt;operator-sdk&lt;/code&gt; binary:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;testing&#34;&gt;Testing&lt;/h2&gt;
&lt;p&gt;See the &lt;a href=&#34;/docs/contribution-guidelines/testing&#34;&gt;testing&lt;/a&gt; and &lt;a href=&#34;/docs/contribution-guidelines/documentation&#34;&gt;documentation&lt;/a&gt; guides for more information.&lt;/p&gt;
&lt;h2 id=&#34;releasing&#34;&gt;Releasing&lt;/h2&gt;
&lt;p&gt;See the &lt;a href=&#34;/docs/contribution-guidelines/releasing&#34;&gt;release guide&lt;/a&gt; for more information.&lt;/p&gt;
&lt;h2 id=&#34;continuous-integration-ci&#34;&gt;Continuous Integration (CI)&lt;/h2&gt;
&lt;p&gt;The operator-sdk repo uses &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/actions&#34;&gt;Github Actions&lt;/a&gt; to test each pull request and build images for both master commits
and release tags. You can alter these processes by modifying the appropriate &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/.github/workflows&#34;&gt;Action config&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;adding-new-architectures&#34;&gt;Adding new architectures&lt;/h3&gt;
&lt;p&gt;The operator-sdk project builds binaries for &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/README.md#platforms&#34;&gt;several os&amp;rsquo;s/architectures&lt;/a&gt;.
If you wish to add support for a new one, please create a feature request issue before
implementing support for that platform and submitting a PR.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d like to implement support yourself, you can test a new architecture by enabling Actions
in your repository, add a platform pair to the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/.github/workflows/deploy.yml&#34;&gt;&lt;code&gt;deploy&lt;/code&gt;&lt;/a&gt; workflow&amp;rsquo;s &lt;code&gt;build and push&lt;/code&gt; step,
and push to your main branch. Once the updated Action passes, submit a PR linking the passing Action run.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Installation Guide</title>
      <link>/docs/building-operators/ansible/installation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/installation/</guid>
      <description>
        
        
        &lt;h2 id=&#34;install-operator-sdk&#34;&gt;Install &lt;code&gt;operator-sdk&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Follow the steps in the &lt;a href=&#34;/docs/installation/&#34;&gt;installation guide&lt;/a&gt; to learn how to install the &lt;code&gt;operator-sdk&lt;/code&gt; CLI tool.&lt;/p&gt;
&lt;h2 id=&#34;additional-prerequisites&#34;&gt;Additional Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.docker.com/install/&#34;&gt;docker&lt;/a&gt; version 17.03+&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.python.org/downloads/&#34;&gt;python&lt;/a&gt; version 3.8.6+&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.ansible.com/ansible/latest/index.html&#34;&gt;ansible&lt;/a&gt; version v2.9.0+&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ansible-runner.readthedocs.io/en/latest/install.html&#34;&gt;ansible-runner&lt;/a&gt; version 2.0.2+&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ansible/ansible-runner-http&#34;&gt;ansible-runner-http&lt;/a&gt; version v1.0.0+&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pypi.org/project/openshift/&#34;&gt;openshift&lt;/a&gt; version v0.12.0+&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/install-kubectl/&#34;&gt;kubectl&lt;/a&gt; and access to a Kubernetes cluster of a &lt;a href=&#34;/docs/overview#kubernetes-version-compatibility&#34;&gt;compatible version&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Installation Guide</title>
      <link>/docs/building-operators/golang/installation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/golang/installation/</guid>
      <description>
        
        
        &lt;h2 id=&#34;install-operator-sdk&#34;&gt;Install &lt;code&gt;operator-sdk&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Follow the steps in the &lt;a href=&#34;/docs/installation/&#34;&gt;installation guide&lt;/a&gt; to learn how to install the &lt;code&gt;operator-sdk&lt;/code&gt; CLI tool.&lt;/p&gt;
&lt;h2 id=&#34;additional-prerequisites&#34;&gt;Additional Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://git-scm.com/downloads&#34;&gt;git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://golang.org/dl/&#34;&gt;go&lt;/a&gt; version 1.22&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.docker.com/install/&#34;&gt;docker&lt;/a&gt; version 17.03+.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/install-kubectl/&#34;&gt;kubectl&lt;/a&gt; and access to a Kubernetes cluster of a &lt;a href=&#34;/docs/overview#kubernetes-version-compatibility&#34;&gt;compatible version&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Installation Guide</title>
      <link>/docs/building-operators/helm/installation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/helm/installation/</guid>
      <description>
        
        
        &lt;h2 id=&#34;install-operator-sdk&#34;&gt;Install &lt;code&gt;operator-sdk&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Follow the steps in the &lt;a href=&#34;/docs/installation/&#34;&gt;installation guide&lt;/a&gt; to learn how to install the &lt;code&gt;operator-sdk&lt;/code&gt; CLI tool.&lt;/p&gt;
&lt;h3 id=&#34;additional-prerequisites&#34;&gt;Additional Prerequisites&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.docker.com/install/&#34;&gt;docker&lt;/a&gt; version 17.03+.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/install-kubectl/&#34;&gt;kubectl&lt;/a&gt; and access to a Kubernetes cluster of a &lt;a href=&#34;/docs/overview#kubernetes-version-compatibility&#34;&gt;compatible version&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Backport Policy</title>
      <link>/docs/upgrading-sdk-version/backport-policy/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/upgrading-sdk-version/backport-policy/</guid>
      <description>
        
        
        &lt;p&gt;Mainly critical issue fixes are backported to the most recent minor release.
Special backport requests can be discussed during the weekly Triage meeting; this does not guarantee an exceptional backport will be created.
Occasionally non-critical issue fixes will be backported, either at an approver&amp;rsquo;s discretion or by request as noted above.
For information on contacting maintainers and attending meetings, check the &lt;a href=&#34;https://github.com/operator-framework/community&#34;&gt;community&lt;/a&gt; repository.&lt;/p&gt;
&lt;h2 id=&#34;process&#34;&gt;Process&lt;/h2&gt;
&lt;p&gt;Typically an issue will be fixed in the &lt;code&gt;master&lt;/code&gt; branch, which will then be cherry-picked to the most recent release&amp;rsquo;s branch.
Those with approver permissions and above can create a cherry-pick PR, assuming no conflicts, by commenting &lt;code&gt;/cherry-pick &amp;lt;release branch&amp;gt;&lt;/code&gt;
in the PR fixing the issue in master. Fixes that are only relevant to a specific release branch can be made against
that branch directly.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Common recommendations and suggestions</title>
      <link>/docs/best-practices/common-recommendation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/common-recommendation/</guid>
      <description>
        
        
        &lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Any recommendations or best practices suggested by the Kubernetes community, such as how to &lt;a href=&#34;https://kubernetes.io/docs/concepts/extend-kubernetes/operator/&#34;&gt;develop Operator pattern solutions&lt;/a&gt; or how to &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime&#34;&gt;use controller-runtime&lt;/a&gt; are good recommendations for those who are looking to build operator projects with operator-sdk. Also, see &lt;a href=&#34;/docs/best-practices/best-practices&#34;&gt;Operator Best Practices&lt;/a&gt;. However, here are some common recommendations.&lt;/p&gt;
&lt;h2 id=&#34;common-recommendations&#34;&gt;Common Recommendations&lt;/h2&gt;
&lt;h3 id=&#34;develop-idempotent-reconciliation-solutions&#34;&gt;Develop idempotent reconciliation solutions&lt;/h3&gt;
&lt;p&gt;When developing operators, it is essential for the controller’s reconciliation loop to be idempotent. By following the &lt;a href=&#34;https://kubernetes.io/docs/concepts/extend-kubernetes/operator/&#34;&gt;Operator pattern&lt;/a&gt; you will create &lt;a href=&#34;https://kubernetes.io/docs/concepts/architecture/controller/&#34;&gt;Controllers&lt;/a&gt; which provide a reconcile function responsible for synchronizing resources until the desired state is reached on the cluster. Breaking this recommendation goes against  the design principles of &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime&#34;&gt;controller-runtime&lt;/a&gt; and may lead to unforeseen consequences such as resources becoming stuck and requiring manual intervention.&lt;/p&gt;
&lt;h3 id=&#34;understanding-kubernetes-apis&#34;&gt;Understanding Kubernetes APIs&lt;/h3&gt;
&lt;p&gt;Building your own operator commonly involves extending the Kubernetes API itself. It is helpful to understand exactly how &lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/&#34;&gt;Custom Resource Definitions interact with the Kubernetes API&lt;/a&gt;. Also, the Kubebuilder documentation on &lt;a href=&#34;https://book.kubebuilder.io/cronjob-tutorial/gvks.html&#34;&gt;Groups and Versions and Kinds&lt;/a&gt; may be helpful to better understand these concepts as they relate to operators.&lt;/p&gt;
&lt;h3 id=&#34;avoid-a-design-solution-where-more-than-one-kind-is-reconciled-by-the-same-controller&#34;&gt;Avoid a design solution where more than one Kind is reconciled by the same controller&lt;/h3&gt;
&lt;p&gt;Having many Kinds (such as CRDs) which are all managed by the same controller usually goes against the design proposed by &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime&#34;&gt;controller-runtime&lt;/a&gt;. Furthermore this might hurt concepts such as encapsulation, the Single Responsibility Principle, and Cohesion. Damaging these concepts may cause unexpected side effects, and increase the difficulty of extending, reusing, or maintaining the operator.&lt;/p&gt;
&lt;h3 id=&#34;ideally-operators-does-not-manage-other-operators&#34;&gt;Ideally Operators does not manage other Operators&lt;/h3&gt;
&lt;p&gt;From &lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/olm-architecture/dependency-resolution/&#34;&gt;best practices&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Operators should own a CRD and only one Operator should control a CRD on a cluster.
Two Operators managing the same CRD is not a recommended best practice. In the case where an API exists but
with multiple implementations, this is typically an example of a no-op Operator because it doesn&amp;rsquo;t
have any deployment or reconciliation loop to define the shared API and other
Operators depend on this Operator to provide one implementation of the
API, e.g. similar to PVCs or Ingress.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;An Operator shouldn&amp;rsquo;t deploy or manage other operators (such patterns are known as meta or super operators
or include CRDs in its Operands). It&amp;rsquo;s the Operator Lifecycle Manager&amp;rsquo;s job to manage the deployment and
lifecycle of operators. For further information check &lt;a href=&#34;/docs/best-practices/best-practices&#34;&gt;Dependency Resolution&lt;/a&gt;.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;what-does-it-mainly-mean&#34;&gt;What does it mainly mean:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;If you want to define that your Operator depends on APIs which are owned by another Operator or on
another whole Operator itself you should use Operator Lifecycle Manager&amp;rsquo;s &lt;a href=&#34;/docs/best-practices/best-practices&#34;&gt;Dependency Resolution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you want to reconcile core APIs (&lt;em&gt;defined by Kubernetes&lt;/em&gt;) or External APIs (&lt;em&gt;defined from other operators&lt;/em&gt;)
you should not re-define the API as owned by your project. Therefore, you can create the controller in this
cases by using the flag &lt;code&gt;--resource=false&lt;/code&gt;. (i.e. &lt;code&gt;$ operator-sdk create api --group ship --version v1beta1 --kind External --resource=false --controller=true&lt;/code&gt;).
&lt;strong&gt;Attention:&lt;/strong&gt; If you are using Golang-based language Operator then, you will need to update the markers and imports
manually until it become officially supported by the tool. For further information check the issue &lt;a href=&#34;https://github.com/kubernetes-sigs/kubebuilder/issues/1999&#34;&gt;#1999&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;WARNING:&lt;/strong&gt; if you create CRD&amp;rsquo;s via the reconciliations or via the Operands then, OLM cannot handle CRDs migration and update, validation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; By not following this guidance you might probably to be hurting concepts like as single responsibility principle
and damaging these concepts could cause unexpected side effects, such as; difficulty extending, reuse, or maintenance, only to mention a few.&lt;/p&gt;
&lt;h3 id=&#34;other-common-suggestions&#34;&gt;Other common suggestions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Provide the images and tags used by the operator solution via environment variables in the &lt;code&gt;config/manager/manager.yaml&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;- /manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;MY_IMAGE&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;quay.io/example.com/image:0.0.1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Manage your solutions using &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties&#34;&gt;Status Conditionals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&#34;/docs/building-operators/golang/advanced-topics/#handle-cleanup-on-deletion&#34;&gt;finalizers&lt;/a&gt; when/if required&lt;/li&gt;
&lt;li&gt;Cover the project with tests/CI to ensure its quality:
&lt;ul&gt;
&lt;li&gt;For any language-based operator, you can use &lt;a href=&#34;/docs/testing-operators/scorecard/&#34;&gt;Scorecard&lt;/a&gt; to implement functional tests&lt;/li&gt;
&lt;li&gt;For Go-based operators, you can also use &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest&#34;&gt;envtest&lt;/a&gt; to cover the controllers. For further information see &lt;a href=&#34;/docs/building-operators/golang/testing&#34;&gt;Testing with EnvTest&lt;/a&gt;. Also, see the &lt;code&gt;test&lt;/code&gt; directory for the Memcached sample under the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/testdata/go/v4/memcached-operator&#34;&gt;testdata/go/v3/memcached-operator&lt;/a&gt; to know how can you build e2e tests.&lt;/li&gt;
&lt;li&gt;For Ansible-based operators, you can also use &lt;a href=&#34;https://molecule.readthedocs.io/&#34;&gt;Molecule&lt;/a&gt;, an Ansible testing framework. For further information see &lt;a href=&#34;/docs/building-operators/ansible/testing-guide&#34;&gt;Testing with Molecule&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;For Helm-based operators, you can also use &lt;a href=&#34;https://helm.sh/docs/topics/chart_tests/&#34;&gt;Chart tests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ensure that you checked the &lt;a href=&#34;/docs/faqs/#can-i-customize-the-projects-initialized-with-operator-sdk&#34;&gt;Can I customize the projects initialized with operator-sdk?&lt;/a&gt; and understand the &lt;a href=&#34;/docs/overview/project-layout&#34;&gt;Project Layout&lt;/a&gt; before starting to do your customizations as please you on top.&lt;/li&gt;
&lt;li&gt;Optimize manager resource values in &lt;code&gt;config/manager/manager.yaml&lt;/code&gt; according to project requirements. It is recommended to define resources limits in order to follow good practices and for security reasons. More info: &lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/&#34;&gt;Managing Resources for Containers&lt;/a&gt; and &lt;a href=&#34;https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-7-limit-resources-memory-cpu-file-descriptors-processes-restarts&#34;&gt;Docker Security Cheat Sheet&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Look for &lt;code&gt;TODO(user)&lt;/code&gt; in the source code generated by the CLI to ensure that you follow all suggested customizations.&lt;/li&gt;
&lt;li&gt;If you wish to integrate your project with OLM, you can also check its &lt;a href=&#34;https://olm.operatorframework.io/docs/best-practices/&#34;&gt;Best Practices&lt;/a&gt; section.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: OLM Integration Package Manifests Quickstart</title>
      <link>/docs/olm-integration/tutorial-package-manifests/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/tutorial-package-manifests/</guid>
      <description>
        
        
        &lt;!-- TODO(2.0.0): remove this document --&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;
As operator framework has moved to using bundle format by default, the package manifest commands have been deprecated and will be removed soon. It is suggested that you follow the &lt;a href=&#34;/docs/olm-integration/quickstart-bundle&#34;&gt;bundle quickstart&lt;/a&gt; to package your operator.&lt;/p&gt;
&lt;p&gt;This guide assumes you have followed the introduction and &lt;em&gt;Setup&lt;/em&gt; section of the &lt;a href=&#34;/docs/olm-integration/quickstart-bundle&#34;&gt;bundle quickstart&lt;/a&gt;,
and have added the &lt;code&gt;packagemanifests&lt;/code&gt; target to your &lt;code&gt;Makefile&lt;/code&gt; as described &lt;a href=&#34;/docs/olm-integration/generation/#package-manifests-format&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; this guide assumes your project was scaffolded with &lt;code&gt;operator-sdk init --project-version=3&lt;/code&gt;.
These features are unavailable to projects of version &lt;code&gt;2&lt;/code&gt; or less; this information can be found by inspecting
your &lt;code&gt;PROJECT&lt;/code&gt; file&amp;rsquo;s &lt;code&gt;version&lt;/code&gt; value.&lt;/p&gt;
&lt;h2 id=&#34;creating-package-manifests&#34;&gt;Creating package manifests&lt;/h2&gt;
&lt;p&gt;We will now create a package manifests format by running &lt;code&gt;make packagemanifests&lt;/code&gt; in the root of the memcached-operator project:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make packagemanifests
/home/user/go/bin/controller-gen rbac:roleName=manager-role crd webhook paths=&amp;quot;./...&amp;quot; output:crd:artifacts:config=config/crd/bases
operator-sdk generate kustomize manifests -q
kustomize build config/manifests | operator-sdk generate packagemanifests -q --version 0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A versioned manifests directory &lt;code&gt;packagemanifests/0.0.1&lt;/code&gt; containing a CSV and all CRDs in &lt;code&gt;config/crds&lt;/code&gt; and a
package manifest YAML file &lt;code&gt;packagemanifests/&amp;lt;project-name&amp;gt;.package.yaml&lt;/code&gt; have been created in the Operator project.&lt;/p&gt;
&lt;h2 id=&#34;deploying-an-operator-with-olm&#34;&gt;Deploying an Operator with OLM&lt;/h2&gt;
&lt;p&gt;At this point in development we&amp;rsquo;ve generated all files necessary to build a memcached-operator registry.
Now we&amp;rsquo;re ready to test the Operator with OLM.&lt;/p&gt;
&lt;h3 id=&#34;testing-package-manifests&#34;&gt;Testing package manifests&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;operator-sdk run packagemanifests&lt;/code&gt; will create an Operator &lt;a href=&#34;https://github.com/operator-framework/operator-registry&#34;&gt;registry&lt;/a&gt;
from manifests and metadata in the memcached-operator project, and inform OLM that memcached-operator v0.0.1
is ready to be deployed. This process effectively replicates production deployment in a constrained manner
to make sure OLM can deploy our Operator successfully before attempting real production deployment.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;run packagemanifests&lt;/code&gt; performs some optionally configurable setup &lt;a href=&#34;/docs/olm-integration/testing-deployment&#34;&gt;under the hood&lt;/a&gt;, but for
most use cases the following invocation is all we need:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk run packagemanifests --version 0.0.1
INFO[0000] Running operator from directory packagemanifests
INFO[0000] Creating memcached-operator registry         
INFO[0000]   Creating ConfigMap &amp;quot;olm/memcached-operator-registry-manifests-package&amp;quot;
INFO[0000]   Creating ConfigMap &amp;quot;olm/memcached-operator-registry-manifests-0-0-1&amp;quot;
INFO[0000]   Creating Deployment &amp;quot;olm/memcached-operator-registry-server&amp;quot;
INFO[0000]   Creating Service &amp;quot;olm/memcached-operator-registry-server&amp;quot;
INFO[0000] Waiting for Deployment &amp;quot;olm/memcached-operator-registry-server&amp;quot; rollout to complete
INFO[0000]   Waiting for Deployment &amp;quot;olm/memcached-operator-registry-server&amp;quot; to rollout: 0 of 1 updated replicas are available
INFO[0066]   Deployment &amp;quot;olm/memcached-operator-registry-server&amp;quot; successfully rolled out
INFO[0066] Creating resources                           
INFO[0066]   Creating CatalogSource &amp;quot;default/memcached-operator-ocs&amp;quot;
INFO[0066]   Creating Subscription &amp;quot;default/memcached-operator-v0-0-1-sub&amp;quot;
INFO[0066]   Creating OperatorGroup &amp;quot;default/operator-sdk-og&amp;quot;
INFO[0066] Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; to reach &#39;Succeeded&#39; phase
INFO[0066]   Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; to appear
INFO[0073]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Pending
INFO[0077]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: InstallReady
INFO[0078]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Installing
INFO[0036]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Succeeded
INFO[0037] Successfully installed &amp;quot;memcached-operator.v0.0.1&amp;quot; on OLM version &amp;quot;0.15.1&amp;quot;

NAME                            NAMESPACE    KIND                        STATUS
memcacheds.cache.example.com    default      CustomResourceDefinition    Installed
memcached-operator.v0.0.1       default      ClusterServiceVersion       Installed
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As long as both the &lt;code&gt;ClusterServiceVersion&lt;/code&gt; and all &lt;code&gt;CustomResourceDefinition&lt;/code&gt;&#39;s return an &lt;code&gt;Installed&lt;/code&gt; status,
the memcached-operator has been deployed successfully.&lt;/p&gt;
&lt;p&gt;Now that we&amp;rsquo;re done testing the memcached-operator, we should probably clean up the Operator&amp;rsquo;s resources.
&lt;a href=&#34;/docs/cli/operator-sdk_cleanup&#34;&gt;&lt;code&gt;operator-sdk cleanup&lt;/code&gt;&lt;/a&gt; will do this for you:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk cleanup memcached-operator
INFO[0000] subscription &amp;quot;memcached-operator-v0-0-1-sub&amp;quot; deleted
INFO[0000] customresourcedefinition &amp;quot;memcacheds.cache.example.com&amp;quot; deleted
INFO[0000] clusterserviceversion &amp;quot;memcached-operator.v0.0.1&amp;quot; deleted
INFO[0000] clusterrole &amp;quot;memcached-operator-metrics-reader&amp;quot; deleted
INFO[0000] serviceaccount &amp;quot;default&amp;quot; deleted
INFO[0000] role &amp;quot;memcached-operator.v0.0.1-jhjk7&amp;quot; deleted
INFO[0000] rolebinding &amp;quot;memcached-operator.v0.0.1-jhjk7-default-mxv6m&amp;quot; deleted
INFO[0000] catalogsource &amp;quot;memcached-operator-ocs&amp;quot; deleted
INFO[0000] operatorgroup &amp;quot;operator-sdk-og&amp;quot; deleted
INFO[0001] operator &amp;quot;memcached-operator&amp;quot; uninstalled
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;migrating-packagemanifests-to-bundles&#34;&gt;Migrating packagemanifests to bundles&lt;/h2&gt;
&lt;p&gt;In order to migrate packagemanifests to bundles, &lt;code&gt;operator-sdk pkgman-to-bundle&lt;/code&gt; command can be used.&lt;/p&gt;
&lt;p&gt;As an example, consider the packagemanifests directory to have the following structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;packagemanifests
└── etcd
    ├── 0.0.1
    │   ├── etcdcluster.crd.yaml
    │   └── etcdoperator.clusterserviceversion.yaml
    ├── 0.0.2
    │   ├── etcdbackup.crd.yaml
    │   ├── etcdcluster.crd.yaml
    │   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml
    │   └── etcdrestore.crd.yaml
    └── etcd.package.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, we have manifests for two versions of the &lt;code&gt;etcd&lt;/code&gt; operator. The following command will generate bundles for each of these versions.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk pkgman-to-bundle packagemanifests --output-dir etcd-bundle/
INFO[0000] Packagemanifests will be migrated to bundles in bundle directory
INFO[0000] Creating etcd-bundle/bundle-0.0.1/bundle.Dockerfile
INFO[0000] Creating etcd-bundle/bundle-0.0.1/metadata/annotations.yaml
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will create output bundles in the directory &lt;code&gt;etcd-bundle&lt;/code&gt;. The output directory will look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;etcd-bundle/
├── bundle-0.0.1
│   ├── bundle
│   │   ├── manifests
│   │   │   ├── etcdcluster.crd.yaml
│   │   │   ├── etcdoperator.clusterserviceversion.yaml
│   │   ├── metadata
│   │   │   └── annotations.yaml
│   │   └── tests
│   │       └── scorecard
│   │           └── config.yaml
│   └── bundle.Dockerfile
└── bundle-0.0.2
    ├── bundle
    │   ├── manifests
    │   │   ├── etcdbackup.crd.yaml
    │   │   ├── etcdcluster.crd.yaml
    │   │   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml
    │   │   ├── etcdrestore.crd.yaml
    │   └── metadata
    │       └── annotations.yaml
    └── bundle.Dockerfile
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To build images for the bundles, the base container image name can be provided using &lt;code&gt;--image-tag-base&lt;/code&gt; flag. This name should be provided without the tag (&lt;code&gt;:&lt;/code&gt; and characters following), as the command will tag each bundle image with its packagemanifests directory name, i.e. &lt;code&gt;&amp;lt;image-tag-base&amp;gt;:&amp;lt;dir-name&amp;gt;&lt;/code&gt;. For example, the following command for the above &lt;code&gt;packagemnifests&lt;/code&gt; directory would build the bundles &lt;code&gt;quay.io/example/etcd-bundle:0.0.1&lt;/code&gt; and &lt;code&gt;quay.io/example/etcd-bundle:0.0.2&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk pkgman-to-bundle packagemanifests --image-tag-base quay.io/example/etcd-bundle
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A custom command can also be specified to build images, using the &lt;code&gt;--build-cmd&lt;/code&gt; flag. The default command is &lt;code&gt;docker build&lt;/code&gt;. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk pkgman-to-bundle packagemanifests --output-dir etcd-bundle/ --image-tag-base quay.io/example/etcd --build-cmd &amp;quot;podman build -f bundle.Dockerfile . -t&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, if using a custom command, it needs to be made sure that the command is in the &lt;code&gt;PATH&lt;/code&gt; or a fully qualified path name is provided as input to the flag.&lt;/p&gt;
&lt;p&gt;Once the command has finished building your bundle images and they have been added to a catalog image, delete all bundle directories except for the latest one. This directory will contain manifests for your operator&amp;rsquo;s head bundle, and should be versioned with version control system like git. Move this directory and its &lt;code&gt;bundle.Dockerfile&lt;/code&gt; to your project&amp;rsquo;s root:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ cp -r ./etcd-bundle/bundle-0.0.2/* .
$ rm -rf ./etcd-bundle
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Try building then running your bundle on a live cluster to make sure it works as expected:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle bundle-build bundle-push
$ operator-sdk run bundle quay.io/example/etcd-bundle:0.0.2
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Project Layout</title>
      <link>/docs/overview/project-layout/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/overview/project-layout/</guid>
      <description>
        
        
        &lt;h2 id=&#34;operator-sdk-project-layout&#34;&gt;Operator SDK Project Layout&lt;/h2&gt;
&lt;p&gt;All projects initialized with &lt;code&gt;operator-sdk init&lt;/code&gt; have a common base structure which builds on &lt;a href=&#34;https://book.kubebuilder.io/cronjob-tutorial/basic-project.html&#34;&gt;kubebuilder&amp;rsquo;s project layout&lt;/a&gt;. Each project type is customized further with code of that type&amp;rsquo;s language.&lt;/p&gt;
&lt;h3 id=&#34;common-base&#34;&gt;Common Base&lt;/h3&gt;
&lt;p&gt;The common structure contains the following items:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File/Directory&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The Dockerfile of your operator project, used to build the image with &lt;code&gt;make docker-build&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Makefile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build file with helper targets to help you work with your project.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PROJECT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This file represents the project&amp;rsquo;s configuration and is used to track useful information for the CLI and plugins.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bin/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This directory contains useful binaries such as the &lt;code&gt;manager&lt;/code&gt; which is used to run your project locally and  the &lt;code&gt;kustomize&lt;/code&gt; utility used for the project configuration. For other language types, it might have other binaries useful for developing your operator.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bundle/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This directory contains all the files used to &lt;a href=&#34;/docs/olm-integration/&#34;&gt;integrate your project&lt;/a&gt; with &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager&#34;&gt;OLM&lt;/a&gt; with the &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle&lt;/a&gt; format. It is built from the Makefile target &lt;code&gt;make bundle&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bundle/manifests/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This directory has the &lt;a href=&#34;https://github.com/operator-framework/operator-registry/tree/v1.5.3#manifest-format&#34;&gt;OLM manifests&lt;/a&gt; of your &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bundle/metadata/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This directory has the &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md#bundle-manifest-format&#34;&gt;OLM metadata&lt;/a&gt; of your &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle&lt;/a&gt; e.g the index image annotations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bundle/tests/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This directory has the &lt;a href=&#34;/docs/testing-operators/scorecard/&#34;&gt;Scorecard&lt;/a&gt; tests shipped with your operator bundle.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains configuration files to launch your project on a cluster. Plugins might use it to provide functionality. For example, for the CLI  to help create your operator bundle it will look for the CRD&amp;rsquo;s and CR&amp;rsquo;s which are scaffolded in this directory. You will also find all &lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize&#34;&gt;Kustomize&lt;/a&gt; YAML definitions as well.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/crd/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the &lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/&#34;&gt;Custom Resources Definitions&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/default/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains a &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/v1.4.2/testdata/go/v3/memcached-operator/config/default/kustomization.yaml&#34;&gt;Kustomize base&lt;/a&gt; for launching the controller in a standard configuration.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/manager/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the manifests to launch your operator project as pods on the cluster.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/manifests/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the base to generate your OLM manifests in the bundle directory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/prometheus/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the manifests required to enable project to serve metrics to &lt;a href=&#34;https://book.kubebuilder.io/reference/metrics.html&#34;&gt;Prometheus&lt;/a&gt; such as the &lt;code&gt;ServiceMonitor&lt;/code&gt; resource.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/scorecard/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the manifests required to allow you test your project with &lt;a href=&#34;/docs/testing-operators/scorecard/&#34;&gt;Scorecard&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/rbac/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the &lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/rbac/&#34;&gt;RBAC&lt;/a&gt; permissions required to run your project.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/samples/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the &lt;a href=&#34;https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#custom-resources&#34;&gt;Custom Resources&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bundle.Dockerfile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The Dockerfile to build the &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle&lt;/a&gt; image. Used to build the operator bundle image with `make bundle-build. |&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;ansible&#34;&gt;Ansible&lt;/h3&gt;
&lt;p&gt;Now, let&amp;rsquo;s look at the files and directories specific to Ansible-based operators.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File/Directory&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/testing/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Manifest files to help you test your project. For example, to change the image policy for your &lt;a href=&#34;/docs/building-operators/ansible/testing-guide&#34;&gt;Molecule tests&lt;/a&gt; or to enable debug level in the Ansible logs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;molecule/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contain the manifests for your &lt;a href=&#34;https://molecule.readthedocs.io/&#34;&gt;Molecule&lt;/a&gt; tests.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;molecule/default&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the default &lt;a href=&#34;https://molecule.readthedocs.io/&#34;&gt;Molecule&lt;/a&gt; task.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;molecule/kind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the &lt;a href=&#34;https://molecule.readthedocs.io/&#34;&gt;Molecule&lt;/a&gt; task to be executed on the cluster.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;playbooks/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the Ansible playbooks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;roles/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the Ansible role files for each Kind scaffold.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;requirements.yml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This file specifies Ansible dependencies that need to be installed for your operator to function.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;watches.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains Group, Version, Kind, and the playbooks and rules location. Used to configure the &lt;a href=&#34;/docs/building-operators/ansible/reference/watches&#34;&gt;Ansible watches&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;golang&#34;&gt;Golang&lt;/h3&gt;
&lt;p&gt;Now, let&amp;rsquo;s look at the files and directories specific to Go-based operators.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File/Directory&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;api/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the api definition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/certmanager&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the Kustomize manifests which configure the &lt;a href=&#34;https://cert-manager.io/docs/&#34;&gt;cert-manager&lt;/a&gt; by the Webhooks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config/webhook&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the Kustomize manifests to configure the Webhook.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;controllers&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the controllers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;main.go&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Implements the project initialization.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hack/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains utility files, e.g. the file used to scaffold the license header for your project files.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;helm&#34;&gt;Helm&lt;/h3&gt;
&lt;p&gt;Now, let&amp;rsquo;s look at the files and directories specific to Helm-based operators.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File/Directory&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;helm-charts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains the Helm charts for each Kind scaffold which can be initialized with &lt;code&gt;operator-sdk init --plugins=helm [options]&lt;/code&gt; or &lt;code&gt;operator-sdk create api [options]&lt;/code&gt; .&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;watches.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains Group, Version, Kind, and Helm chart location. Used to configure the &lt;a href=&#34;/docs/building-operators/helm/reference/watches&#34;&gt;Helm watches&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Quickstart for Ansible-based Operators</title>
      <link>/docs/building-operators/ansible/quickstart/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/quickstart/</guid>
      <description>
        
        
        &lt;p&gt;This guide walks through an example of building a simple memcached-operator powered by &lt;a href=&#34;https://www.ansible.com/&#34;&gt;Ansible&lt;/a&gt; using tools and libraries provided by the Operator SDK.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Go through the &lt;a href=&#34;/docs/building-operators/ansible/installation&#34;&gt;installation guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Make sure your user is authorized with &lt;code&gt;cluster-admin&lt;/code&gt; permissions.&lt;/li&gt;
&lt;li&gt;Have an accessible image registry for various operator images (ex. &lt;a href=&#34;https://hub.docker.com/signup&#34;&gt;hub.docker.com&lt;/a&gt;,
&lt;a href=&#34;https://quay.io/&#34;&gt;quay.io&lt;/a&gt;) and be logged in to your command line environment.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;example.com&lt;/code&gt; is used as the registry Docker Hub namespace in these examples.
Replace it with another value if using a different registry or namespace.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/olm-integration/cli-overview#private-bundle-and-catalog-image-registries&#34;&gt;Authentication and certificates&lt;/a&gt; if the registry is private or uses a custom CA.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;steps&#34;&gt;Steps&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Create a project directory for your project and initialize the project:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;mkdir memcached-operator
&lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; memcached-operator
operator-sdk init --domain example.com --plugins ansible
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Create a simple Memcached API:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk create api --group cache --version v1alpha1 --kind Memcached --generate-role
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Build and push your operator&amp;rsquo;s image:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make docker-build docker-push &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example.com/memcached-operator:v0.0.1&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;olm-deployment&#34;&gt;OLM deployment&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a href=&#34;/docs/olm-integration/tutorial-bundle/#enabling-olm&#34;&gt;OLM&lt;/a&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk olm install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Bundle your operator, then build and push the bundle image (defaults to &lt;code&gt;example.com/memcached-operator-bundle:v0.0.1&lt;/code&gt;):&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make bundle &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example.com/memcached-operator:v0.0.1&amp;#34;&lt;/span&gt;
make bundle-build bundle-push
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Run your bundle. If your bundle image is hosted in a registry that is private and/or
has a custom CA, these &lt;a href=&#34;/docs/olm-integration/cli-overview#private-bundle-and-catalog-image-registries&#34;&gt;configuration steps&lt;/a&gt; must be complete.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk run bundle example.com/memcached-operator-bundle:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Create a sample Memcached custom resource:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl apply -f config/samples/cache_v1alpha1_memcached.yaml
memcached.cache.example.com/memcached-sample created
&lt;/code&gt;&lt;/pre&gt;&lt;ol&gt;
&lt;li&gt;Uninstall the operator:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk cleanup memcached-operator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;direct-deployment&#34;&gt;Direct deployment&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Deploy your operator:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make deploy &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example.com/memcached-operator:v0.0.1&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Create a sample Memcached custom resource:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl apply -f config/samples/cache_v1alpha1_memcached.yaml
memcached.cache.example.com/memcached-sample created
&lt;/code&gt;&lt;/pre&gt;&lt;ol&gt;
&lt;li&gt;Uninstall the operator:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make undeploy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Read the &lt;a href=&#34;/docs/building-operators/ansible/tutorial/&#34;&gt;full tutorial&lt;/a&gt; for an in-depth walkthrough of building an Ansible operator.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Cheat Sheet</title>
      <link>/docs/overview/cheat-sheet/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/overview/cheat-sheet/</guid>
      <description>
        
        
        &lt;p&gt;Below you will find a cheat sheet with options and helpers for projects, which are built with the SDK and are respecting its proposed layout.&lt;/p&gt;
&lt;h2 id=&#34;common-commands-and-options&#34;&gt;Common commands and options&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;To initialize an operator project in the current directory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk init --plugins=&amp;lt;plugin-key&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;To initialize an operator project in the current directory using a specific plugin. To check the available plugins you can run &lt;code&gt;operator-sdk --help&lt;/code&gt;. E.g (&lt;code&gt;operator-sdk init --plugins=helm&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk create api [flags]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lets you create your own APIs with its &lt;a href=&#34;https://book.kubebuilder.io/cronjob-tutorial/gvks.html&#34;&gt;GKV&lt;/a&gt; by &lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/&#34;&gt;Extending the Kubernetes API with CustomResourceDefinitions&lt;/a&gt;, or lets you use external/core-types. Also generates their respective &lt;a href=&#34;https://kubernetes.io/docs/concepts/architecture/controller&#34;&gt;controllers&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk create webhook [flags]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;To scaffold &lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/&#34;&gt;Webhooks&lt;/a&gt; for the APIs declared in the project. Currently, only the Go-based project supports this option.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make docker-build IMG=&amp;lt;some-registry&amp;gt;/&amp;lt;project-name&amp;gt;:&amp;lt;tag&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build the operator image.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make docker-build docker-push IMG=&amp;lt;some-registry&amp;gt;/&amp;lt;project-name&amp;gt;:&amp;lt;tag&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build and push the operator image for your registry.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Install the CRDs into the cluster.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make uninstall&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Uninstall the CRDs into the cluster.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make run&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run your controller locally and outside of the cluster. Note that this will run in the foreground, so switch to a new terminal if you want to leave it running.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make deploy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deploy your project on the cluster.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make undeploy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undeploy your project on the cluster.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;to-create-bundles-catalogs-and-develop-for-olm&#34;&gt;To create bundles, catalogs, and develop for OLM&lt;/h2&gt;
&lt;p&gt;For further information check &lt;a href=&#34;/docs/olm-integration/&#34;&gt;Operator SDK Integration with Operator Lifecycle Manager&lt;/a&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make bundle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create/update the &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle&lt;/a&gt; based on the project manifests in the &lt;code&gt;bundle/&lt;/code&gt; directory. For more info see &lt;a href=&#34;/docs/olm-integration/tutorial-bundle/#creating-a-bundle&#34;&gt;Create a bundle&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk bundle validate ./bundle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;To validate your &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle&lt;/a&gt; spec definition.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk bundle validate ./bundle --select-optional suite=operatorframework&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Validate your bundle against &lt;a href=&#34;https://operatorhub.io/&#34;&gt;OperatorHub.io&lt;/a&gt; criteria. For further information use the flag &lt;code&gt;--help&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk olm install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;To install OLM on your cluster for development purposes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk olm uninstall&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;To uninstall OLM from your cluster.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make bundle-build BUNDLE_IMG=&amp;lt;some-registry&amp;gt;/&amp;lt;project-name-bundle&amp;gt;:&amp;lt;tag&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;To build your bundle operator image.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make bundle-build bundle-push BUNDLE_IMG=&amp;lt;some-registry&amp;gt;/&amp;lt;project-name-bundle&amp;gt;:&amp;lt;tag&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;To build and push your bundle operator image.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk run bundle &amp;lt;some-registry&amp;gt;/&amp;lt;project-name-bundle&amp;gt;:&amp;lt;tag&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;To deploy your bundle operator using OLM on your cluster for development purposes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk run bundle private-registry.org/bundle:v1.2.3 --service-account sa-with-secret --pull-secret-name regcred --ca-secret-name cert-sec&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Configure &lt;code&gt;run bundle&lt;/code&gt; (and &lt;code&gt;run bundle-upgrade&lt;/code&gt;) to use an image pull secret, non-default service account configured with that secret, and custom CA certificate secret&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- TODO(estroz): remove the service account requirement once OLM releases a patch or new
minor release containing https://github.com/operator-framework/operator-lifecycle-manager/pull/1941 --&gt;
&lt;h3 id=&#34;updating-bundle-channels&#34;&gt;Updating bundle channels&lt;/h3&gt;
&lt;p&gt;The following examples let you update the &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle&lt;/a&gt; with data-informed. For further information also check &lt;a href=&#34;/docs/olm-integration/generation/#upgrade-your-operator&#34;&gt;Upgrade your Operator&lt;/a&gt; and see &lt;a href=&#34;https://olm.operatorframework.io/docs/best-practices/channel-naming/&#34;&gt;Channel Naming&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Note that it will carry over any customizations you have made and ensure a rolling update to the next version of your Operator.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make bundle &lt;span style=&#34;color:#000&#34;&gt;CHANNELS&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;fast,preview &lt;span style=&#34;color:#000&#34;&gt;DEFAULT_CHANNEL&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;stable &lt;span style=&#34;color:#000&#34;&gt;VERSION&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;1.0.0 &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&amp;lt;some-registry&amp;gt;/&amp;lt;project-name-bundle&amp;gt;:&amp;lt;tag&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; You can use environment variables to pass the values such as &lt;code&gt;export CHANNELS=fast,candidate&lt;/code&gt;. Note that, their values will be used by &lt;code&gt;make bundle&lt;/code&gt; command.&lt;/p&gt;
&lt;h2 id=&#34;to-test-your-projects&#34;&gt;To test your projects&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator-sdk scorecard ./bundle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run the &lt;a href=&#34;/docs/testing-operators/scorecard/&#34;&gt;Scorecard&lt;/a&gt; tests for your bundle.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run Go tests. It is valid only for Go-based operators.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;molecule test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run &lt;a href=&#34;/docs/building-operators/ansible/testing-guide&#34;&gt;Molecule&lt;/a&gt; tests.  It is valid only for Ansible-based operators.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;helm test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run &lt;a href=&#34;https://helm.sh/docs/topics/chart_tests/&#34;&gt;Helm chart tests&lt;/a&gt;.  It is valid only for Helm-based operators.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; This is not a comprehensive list of make targets or commands. Please see the scaffolded Makefile and &lt;code&gt;make help&lt;/code&gt; for the full list of targets. Note that you can use &lt;code&gt;operator-sdk &amp;lt;command&amp;gt; --help&lt;/code&gt; and check the &lt;a href=&#34;/docs/cli/&#34;&gt;CLI&lt;/a&gt; section to check all options.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Resource pruning</title>
      <link>/docs/best-practices/resource-pruning/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/resource-pruning/</guid>
      <description>
        
        
        &lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Operators can create &lt;a href=&#34;https://kubernetes.io/docs/concepts/workloads/controllers/job/&#34;&gt;Jobs&lt;/a&gt; or Pods as part of their normal operation, and when those Jobs or Pods
complete, they can remain on the Kubernetes cluster if not specifically removed. These resources
can consume valuable cluster resources like disk storage (e.g. etcd). These resources
are not tied to a Custom Resource using an &lt;code&gt;ownerReference&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Operator authors have traditionally had two pruning options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;leave the resource cleanup to a system admin to perform&lt;/li&gt;
&lt;li&gt;implement some form of pruning within their operator solution&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For our purposes when we say, &lt;em&gt;prune&lt;/em&gt;, we mean to remove a resource (e.g. kubectl delete) from
a Kubernetes cluster for a given namespace.&lt;/p&gt;
&lt;p&gt;This documentation describes the pattern and library useful for implementing a solution within an operator.&lt;/p&gt;
&lt;h2 id=&#34;operator-lib-prune-library&#34;&gt;operator-lib prune library&lt;/h2&gt;
&lt;p&gt;A simple pruning implementation can be found in the &lt;a href=&#34;https://github.com/operator-framework/operator-lib/tree/main/prune&#34;&gt;operator-lib prune package&lt;/a&gt;. This
package is written in Go and is meant to be used within Go-based operators. This package was
developed to include common pruning strategies as found in common operators. The package also allow
for customization of hooks and strategies.&lt;/p&gt;
&lt;h3 id=&#34;pruning-configuration&#34;&gt;Pruning Configuration&lt;/h3&gt;
&lt;p&gt;Users can configure the pruning library by creating code similar to this example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Config&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;           &lt;span style=&#34;color:#000&#34;&gt;logf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;WithName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;prune&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;DryRun&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Clientset&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;     &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;LabelSelector&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;app=churro&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Resources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GroupVersionKind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;PodKind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Namespaces&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Strategy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;StrategyConfig&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;Mode&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;            &lt;span style=&#34;color:#000&#34;&gt;MaxCountStrategy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;MaxCountSetting&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;PreDeleteHook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;myhook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Config Field&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Log&lt;/td&gt;
&lt;td&gt;a logr.Logger. It is optional if a logger is provided through the context to the Execute method, which is the case with the context of the Reconcile function of operator-sdk and controller-runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DryRun&lt;/td&gt;
&lt;td&gt;a boolean determines whether to actually remove resources; &lt;code&gt;true&lt;/code&gt; means to execute but not to remove resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clientset&lt;/td&gt;
&lt;td&gt;a client-go Kubernetes ClientSet that will be used for Kube API calls by the library&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LabelSelector&lt;/td&gt;
&lt;td&gt;Kubernetes label selector expression used to find resources to prune&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resources&lt;/td&gt;
&lt;td&gt;Kube resource Kinds, currently PodKind and JobKind are supported by the library&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespaces&lt;/td&gt;
&lt;td&gt;a list of Kube Namespaces to search for resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strategy&lt;/td&gt;
&lt;td&gt;specifies the pruning strategy to execute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strategy.Mode&lt;/td&gt;
&lt;td&gt;currently MaxCountStrategy, MaxAgeStrategy, or CustomStrategy are supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strategy.MaxCountSetting&lt;/td&gt;
&lt;td&gt;integer value for &lt;em&gt;maxcount&lt;/em&gt; strategy, specifies how many resources should remain after pruning executes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strategy.MaxAgeSetting&lt;/td&gt;
&lt;td&gt;golang time.Duration string value (e.g. 48h), specifies age of resources to prune&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strategy.CustomSettings&lt;/td&gt;
&lt;td&gt;a golang map of values that can be passed into a Custom strategy function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PreDeleteHook&lt;/td&gt;
&lt;td&gt;optionally specifies a golang function to call before pruning a resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CustomStrategy&lt;/td&gt;
&lt;td&gt;optionally specifies a golang function that implements a custom pruning strategy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;pruning-execution&#34;&gt;Pruning Execution&lt;/h3&gt;
&lt;p&gt;Users can invoke the pruning by running the &lt;em&gt;Execute&lt;/em&gt; function on the pruning configuration
as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Execute&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Users might want to implement pruning execution by means of a cron package or simply call the prune
library based on some other triggering event.&lt;/p&gt;
&lt;p&gt;If a logger has been configured in the Config structure it takes precedence on the one provided through ctx.
Adding a logger.Logger to the context can be done with &lt;a href=&#34;https://pkg.go.dev/github.com/go-logr/logr#NewContext&#34;&gt;logr.NewContext&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;pruning-strategies&#34;&gt;Pruning Strategies&lt;/h2&gt;
&lt;h3 id=&#34;maxcount-strategy&#34;&gt;maxcount Strategy&lt;/h3&gt;
&lt;p&gt;A strategy of leaving a finite set of resources is implemented called &lt;em&gt;maxcount&lt;/em&gt;. This strategy
seeks to leave a specific number of resources, sorted by latest, on your cluster. For example, if
you have 10 resources that would be pruned, and you specified a &lt;em&gt;maxcount&lt;/em&gt; value of 4, then 6
resources would be pruned (removed) from your cluster starting with the oldest resources.&lt;/p&gt;
&lt;h3 id=&#34;maxage-strategy&#34;&gt;maxage Strategy&lt;/h3&gt;
&lt;p&gt;A strategy of removing resources greater than a specific time is called &lt;em&gt;maxage&lt;/em&gt;.  This strategy
seeks to remove resources older than a specified &lt;em&gt;maxage&lt;/em&gt; duration.  For example, a library
user might specify a value of &lt;em&gt;48h&lt;/em&gt; to indicate that any resource older than 48 hours would be
pruned.  Durations are specified using golang&amp;rsquo;s &lt;a href=&#34;https://pkg.go.dev/time#Duration&#34;&gt;time.Duration formatting&lt;/a&gt; (e.g. 48h).&lt;/p&gt;
&lt;h2 id=&#34;pruning-customization&#34;&gt;Pruning Customization&lt;/h2&gt;
&lt;h3 id=&#34;predelete-hook&#34;&gt;preDelete Hook&lt;/h3&gt;
&lt;p&gt;Users can provide a &lt;em&gt;preDelete&lt;/em&gt; hook when using the &lt;a href=&#34;https://github.com/operator-framework/operator-lib/tree/main/prune&#34;&gt;operator-lib prune package&lt;/a&gt;.&lt;br&gt;
This hook function will be called by the library before removing a resource.  This provides a means to examine
the resource logs for example, extracting any valued content, before the resource is removed
from the cluster.&lt;/p&gt;
&lt;p&gt;Here is an example of a &lt;em&gt;preDelete&lt;/em&gt; hook:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;myhook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Config&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ResourceInfo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;prune&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Logger&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;V&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pre-deletion&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;GVK&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GVK&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;namespace&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
       	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GVK&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Kind&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;PodKind&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Clientset&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;CoreV1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;().&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Pods&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GetLogs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodLogOptions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{})&lt;/span&gt;
                &lt;span style=&#34;color:#000&#34;&gt;podLogs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Background&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;())&lt;/span&gt;
                &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
                &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;defer&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;podLogs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Close&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt;

                &lt;span style=&#34;color:#000&#34;&gt;buf&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;new&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;bytes&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
                &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;io&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Copy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;buf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;podLogs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
                &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

                &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;V&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod log before removing is&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;buf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;String&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;())&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; if your custom hook returns an error, then the resource will not be removed by the
prune library.&lt;/p&gt;
&lt;h3 id=&#34;custom-strategy&#34;&gt;Custom Strategy&lt;/h3&gt;
&lt;p&gt;Library users can also write their own custom pruning strategy function to support advanced
cases. Custom strategy functions are passed in the prune configuration and a list of resources selected by
the library.  The custom strategy builds up a list of resources to be removed, returning the list to the prune library which
performs the actual resource removal. Here is an example custom strategy:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;myStrategy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Config&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;resources&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ResourceInfo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;resourcesToRemove&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ResourceInfo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Logger&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;V&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;myStrategy called&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;resources&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;resources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;config&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;len&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;resources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;resourcesToRemove&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;fmt&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Errorf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;count of resources did not equal our expectation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;resourcesToRemove&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To have your custom strategy invoked, you will specify your function within the prune configuration
as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Strategy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Mode&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;CustomStrategy&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Strategy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;CustomSettings&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;make&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;interface&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{})&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;CustomStrategy&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;myStrategy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice that you can optionally pass in settings to your custom function as a map using the &lt;code&gt;cfg.Strategy.CustomSettings&lt;/code&gt; field.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Ansible Operator Tutorial</title>
      <link>/docs/building-operators/ansible/tutorial/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/tutorial/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; If your project was created with an &lt;code&gt;operator-sdk&lt;/code&gt; version prior to &lt;code&gt;v1.0.0&lt;/code&gt;
please &lt;a href=&#34;/docs/building-operators/ansible/migration&#34;&gt;migrate&lt;/a&gt;, or consult the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/v0.19.x/website/content/en/docs/ansible/quickstart.md&#34;&gt;legacy docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Go through the &lt;a href=&#34;/docs/building-operators/ansible/installation&#34;&gt;installation guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Make sure your user is authorized with &lt;code&gt;cluster-admin&lt;/code&gt; permissions.&lt;/li&gt;
&lt;li&gt;An accessible image registry for various operator images (ex. &lt;a href=&#34;https://hub.docker.com/signup&#34;&gt;hub.docker.com&lt;/a&gt;,
&lt;a href=&#34;https://quay.io/&#34;&gt;quay.io&lt;/a&gt;) and be logged in to your command line environment.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;example.com&lt;/code&gt; is used as the registry Docker Hub namespace in these examples.
Replace it with another value if using a different registry or namespace.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/olm-integration/cli-overview#private-bundle-and-catalog-image-registries&#34;&gt;Authentication and certificates&lt;/a&gt; if the registry is private or uses a custom CA.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;We will create a sample project to let you know how it works and this sample will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a Memcached Deployment if it doesn&amp;rsquo;t exist&lt;/li&gt;
&lt;li&gt;Ensure that the Deployment size is the same as specified by the Memcached CR spec&lt;/li&gt;
&lt;li&gt;Update the Memcached CR status using the status writer with the names of the CR&amp;rsquo;s pods&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;create-a-new-project&#34;&gt;Create a new project&lt;/h2&gt;
&lt;p&gt;Use the CLI to create a new memcached-operator project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;mkdir memcached-operator
&lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; memcached-operator
operator-sdk init --plugins&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;ansible --domain example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Among the files generated by this command is a Kubebuilder &lt;code&gt;PROJECT&lt;/code&gt;
file. Subsequent &lt;code&gt;operator-sdk&lt;/code&gt; commands (and help text) run from the
project root read this file and are aware that the project type is
Ansible.&lt;/p&gt;
&lt;p&gt;Next, we will create a &lt;code&gt;Memcached&lt;/code&gt; API.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk create api --group cache --version v1alpha1 --kind Memcached --generate-role
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The scaffolded operator has the following structure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Memcached&lt;/code&gt; Custom Resource Definition, and a sample &lt;code&gt;Memcached&lt;/code&gt; resource.&lt;/li&gt;
&lt;li&gt;A &amp;ldquo;Manager&amp;rdquo; that reconciles the state of the cluster to the desired state
&lt;ul&gt;
&lt;li&gt;A reconciler, which is an Ansible Role or Playbook.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;watches.yaml&lt;/code&gt; file, which connects the &lt;code&gt;Memcached&lt;/code&gt; resource to the &lt;code&gt;memcached&lt;/code&gt; Ansible Role.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a href=&#34;/docs/building-operators/ansible/reference/scaffolding&#34;&gt;scaffolded files reference&lt;/a&gt; and &lt;a href=&#34;/docs/building-operators/ansible/reference/watches&#34;&gt;watches reference&lt;/a&gt; for more detailed information.&lt;/p&gt;
&lt;h3 id=&#34;modify-the-manager&#34;&gt;Modify the Manager&lt;/h3&gt;
&lt;p&gt;Now we need to provide the reconcile logic, in the form of an Ansible
Role, which will run every time a &lt;code&gt;Memcached&lt;/code&gt; resource is created,
updated, or deleted.&lt;/p&gt;
&lt;p&gt;Update &lt;code&gt;roles/memcached/tasks/main.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;start&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kubernetes.core.k8s&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;definition&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Deployment&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;apps/v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;{{ ansible_operator_meta.name }}-memcached&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;{{ ansible_operator_meta.namespace }}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;replicas&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{size}}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;selector&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;app&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;template&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;labels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;app&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;- memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;- -m=&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;64&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;- -o&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;- modern&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;- -v&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;docker.io/memcached:1.4.36-alpine&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ports&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containerPort&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;11211&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This memcached role will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ensure a memcached Deployment exists&lt;/li&gt;
&lt;li&gt;Set the Deployment size&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that the tasks in this Ansible role file are what actually defines the behavior of the spec and status of the memcached custom resource.
As Kubernetes allows entry of arbitrary fields when creating resources, we don&amp;rsquo;t need to actually create specific fields in the CRD.
While we won&amp;rsquo;t be doing this in this tutorial, it is recommended to also define these fields in the CRD, so that Kubernetes users
can see the fields that will be used when using the custom resource.
It is also good practice to set default values for variables used in Ansible
Roles, so edit &lt;code&gt;roles/memcached/defaults/main.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# defaults file for Memcached&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;size&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, update the &lt;code&gt;Memcached&lt;/code&gt; sample, &lt;code&gt;config/samples/cache_v1alpha1_memcached.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.example.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached-sample&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;size&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The key-value pairs in the Custom Resource spec are passed
to Ansible as extra variables.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The names of all variables in the spec field are converted to
snake_case by the operator before running Ansible. For example,
serviceAccount in the spec becomes service_account in Ansible. You can
disable this case conversion by setting the &lt;code&gt;snakeCaseParameters&lt;/code&gt; option
to &lt;code&gt;false&lt;/code&gt; in your &lt;code&gt;watches.yaml&lt;/code&gt;. It is recommended that you perform some
type validation in Ansible on the variables to ensure that your
application is receiving the expected input.&lt;/p&gt;
&lt;h2 id=&#34;configure-the-operators-image-registry&#34;&gt;Configure the operator&amp;rsquo;s image registry&lt;/h2&gt;
&lt;p&gt;All that remains is to build and push the operator image to the desired image registry.
Your Makefile composes image tags either from values written at project initialization or from the CLI.
In particular, &lt;code&gt;IMAGE_TAG_BASE&lt;/code&gt; lets you define a common image registry, namespace, and partial name
for all your image tags. Update this to another registry and/or namespace if the current value is incorrect.
Afterwards you can update the &lt;code&gt;IMG&lt;/code&gt; variable definition like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-diff&#34; data-lang=&#34;diff&#34;&gt;&lt;span style=&#34;color:#a40000&#34;&gt;-IMG ?= controller:latest
&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00a000&#34;&gt;+IMG ?= $(IMAGE_TAG_BASE):$(VERSION)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once done, you do not have to set &lt;code&gt;IMG&lt;/code&gt; or any other image variable in the CLI. The following command will
build and push an operator image tagged as &lt;code&gt;example.com/memcached-operator:v0.0.1&lt;/code&gt; to Docker Hub:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;make docker-build docker-push
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;run-the-operator&#34;&gt;Run the Operator&lt;/h2&gt;
&lt;p&gt;There are three ways to run the operator:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As a Go program outside a cluster&lt;/li&gt;
&lt;li&gt;As a Deployment inside a Kubernetes cluster&lt;/li&gt;
&lt;li&gt;Managed by the &lt;a href=&#34;/docs/olm-integration/tutorial-bundle/#enabling-olm&#34;&gt;Operator Lifecycle Manager (OLM)&lt;/a&gt; in &lt;a href=&#34;/docs/olm-integration/tutorial-bundle&#34;&gt;bundle&lt;/a&gt; format&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;1-run-locally-outside-the-cluster&#34;&gt;1. Run locally outside the cluster&lt;/h3&gt;
&lt;p&gt;Execute the following command, which installs your CRDs and runs the manager locally:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make install run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;2-run-as-a-deployment-inside-the-cluster&#34;&gt;2. Run as a Deployment inside the cluster&lt;/h3&gt;
&lt;p&gt;By default, a new namespace is created with name &lt;code&gt;&amp;lt;project-name&amp;gt;-system&lt;/code&gt;, ex. &lt;code&gt;memcached-operator-system&lt;/code&gt;, and will be used for the deployment.&lt;/p&gt;
&lt;p&gt;Commonly, Operator authors may need to modify &lt;code&gt;config/rbac&lt;/code&gt; in order to
give their Operator the necessary permissions to reconcile.&lt;/p&gt;
&lt;p&gt;Run the following to customize the manifests and deploy the operator.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make deploy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The scaffolded &lt;code&gt;Makefile&lt;/code&gt; uses &lt;a href=&#34;https://kustomize.io/&#34;&gt;&lt;code&gt;kustomize&lt;/code&gt;&lt;/a&gt; to apply custom
configurations and generate manifests from the &lt;code&gt;config/&lt;/code&gt; directory, which are
piped to &lt;code&gt;kubectl&lt;/code&gt;. Run the following command to see the manifests that were
applied to the cluster.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;kustomize build config/default
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Verify that the memcached-operator is up and running:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl get deployment -n memcached-operator-system
NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
memcached-operator-controller-manager   1/1     1            1           8m
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;3-deploy-your-operator-with-olm&#34;&gt;3. Deploy your Operator with OLM&lt;/h3&gt;
&lt;p&gt;First, install &lt;a href=&#34;/docs/olm-integration/tutorial-bundle/#enabling-olm&#34;&gt;OLM&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk olm install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Bundle your operator, then build and push the bundle image. The &lt;code&gt;bundle&lt;/code&gt; target generates a &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md#operator-bundle&#34;&gt;bundle&lt;/a&gt;
in the &lt;code&gt;bundle&lt;/code&gt; directory containing manifests and metadata defining your operator.
&lt;code&gt;bundle-build&lt;/code&gt; and &lt;code&gt;bundle-push&lt;/code&gt; build and push a bundle image defined by &lt;code&gt;bundle.Dockerfile&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make bundle bundle-build bundle-push
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, run your bundle. If your bundle image is hosted in a registry that is private and/or
has a custom CA, these &lt;a href=&#34;/docs/olm-integration/cli-overview#private-bundle-and-catalog-image-registries&#34;&gt;configuration steps&lt;/a&gt; must be complete.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk run bundle example.com/memcached-operator-bundle:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check out the &lt;a href=&#34;/docs/olm-integration/tutorial-bundle&#34;&gt;docs&lt;/a&gt; for a deep dive into &lt;code&gt;operator-sdk&lt;/code&gt;&#39;s OLM integration.&lt;/p&gt;
&lt;h2 id=&#34;create-a-memcached-cr&#34;&gt;Create a Memcached CR&lt;/h2&gt;
&lt;p&gt;Update the sample Memcached CR manifest at &lt;code&gt;config/samples/cache_v1alpha1_memcached.yaml&lt;/code&gt; and define the &lt;code&gt;spec&lt;/code&gt; as the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-YAML&#34; data-lang=&#34;YAML&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.example.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached-sample&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;size&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create the CR:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;kubectl apply -f config/samples/cache_v1alpha1_memcached.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ensure that the memcached operator creates the deployment for the sample CR with the correct size:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl get deployment
NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
memcached-sample                        3/3     3            3           1m
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Check the pods and CR status to confirm the status is updated with the memcached pod names:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl get pods
NAME                                  READY     STATUS    RESTARTS   AGE
memcached-sample-6fd7c98d8-7dqdr      1/1       Running   0          1m
memcached-sample-6fd7c98d8-g5k7v      1/1       Running   0          1m
memcached-sample-6fd7c98d8-m7vn7      1/1       Running   0          1m
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl get memcached/memcached-sample -o yaml
apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
  creationTimestamp: &amp;quot;2021-03-17T19:54:42Z&amp;quot;
  generation: 1
  managedFields:
  - apiVersion: cache.example.com/v1alpha1
    fieldsType: FieldsV1
    fieldsV1:
      f:status:
        .: {}
        f:conditions: {}
    manager: ansible-operator
    operation: Update
    time: &amp;quot;2021-03-17T19:54:42Z&amp;quot;
  - apiVersion: cache.example.com/v1alpha1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec:
        .: {}
        f:size: {}
    manager: kubectl
    operation: Update
    time: &amp;quot;2021-03-17T19:54:42Z&amp;quot;
  name: memcached-sample
  namespace: default
  resourceVersion: &amp;quot;1008&amp;quot;
  uid: 4b023125-132a-44e3-80de-20801c7a9268
spec:
  size: 3
status:
  conditions:
  - ansibleResult:
      changed: 0
      completion: 2021-03-17T19:54:54.890394
      failures: 0
      ok: 1
      skipped: 0
    lastTransitionTime: &amp;quot;2021-03-17T19:54:42Z&amp;quot;
    message: Awaiting next reconciliation
    reason: Successful
    status: &amp;quot;True&amp;quot;
    type: Running
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;update-the-size&#34;&gt;Update the size&lt;/h3&gt;
&lt;p&gt;Update &lt;code&gt;config/samples/cache_v1alpha1_memcached.yaml&lt;/code&gt; to change the &lt;code&gt;spec.size&lt;/code&gt; field in the Memcached CR from 3 to 5:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;kubectl patch memcached memcached-sample -p &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;size&amp;#34;: 5}}&amp;#39;&lt;/span&gt; --type&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;merge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Confirm that the operator changes the deployment size:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl get deployment
NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
memcached-sample                        5/5     5            5           3m
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;cleanup&#34;&gt;Cleanup&lt;/h3&gt;
&lt;p&gt;Run the following to delete all deployed resources:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;kubectl delete -f config/samples/cache_v1alpha1_memcached.yaml
make undeploy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;We recommend reading through the &lt;a href=&#34;/docs/building-operators/ansible/development-tips/&#34;&gt;Ansible development section&lt;/a&gt;
for tips and tricks, including how to run the operator locally.&lt;/p&gt;
&lt;p&gt;In this tutorial, the scaffolded &lt;code&gt;watches.yaml&lt;/code&gt; could be used as-is, but
has additional optional features. See the &lt;a href=&#34;/docs/building-operators/ansible/reference/watches&#34;&gt;watches reference&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For brevity, some of the scaffolded files were left out of this guide.
See &lt;a href=&#34;/docs/building-operators/ansible/reference/scaffolding&#34;&gt;Scaffolding Reference&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This example built a namespaced scope operator, but Ansible operators
can also be used with cluster-wide scope.&lt;/p&gt;
&lt;!--
todo(camilamacedo86): Create an Ansible operator scope document.
https://github.com/operator-framework/operator-sdk/issues/3447
--&gt;
&lt;p&gt;OLM will manage creation of most if not all resources required to run your operator, using a bit of setup from other operator-sdk commands. Check out the &lt;a href=&#34;/docs/olm-integration/tutorial-bundle&#34;&gt;OLM integration guide&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Operator Capability Levels</title>
      <link>/docs/overview/operator-capabilities/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/overview/operator-capabilities/</guid>
      <description>
        
        
        &lt;p&gt;Operators come in different maturity levels in regards to their lifecycle management capabilities for the application or workload they deliver. The capability models aims to provide guidance in terminology to express what features users can expect from an operator.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/operator-capability-level.png&#34; alt=&#34;operator-capability-level&#34;&gt;&lt;/p&gt;
&lt;p&gt;Each capability level is associated with a certain set of management features the Operator offers around the managed workload. Operator that do not manage a workload and/or are delegating to off-clusters orchestration services would remain at Level 1. Capability levels are designated from level 1 to level 5. Each capability represents its own set of features and may be independent of each other.&lt;/p&gt;
&lt;h2 id=&#34;terminology&#34;&gt;Terminology&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Operator&lt;/strong&gt; - the custom controller installed on a Kubernetes cluster&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Operand&lt;/strong&gt; - the managed workload provided by the Operator as a service&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Custom Resource (CR)&lt;/strong&gt; - an instance of the &lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/&#34;&gt;&lt;code&gt;CustomResourceDefinition&lt;/code&gt;&lt;/a&gt; the Operator ships that represents the Operand or an Operation on an Operand (also known as primary resources)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Managed resources&lt;/strong&gt; - the Kubernetes objects or off-cluster services the Operator uses to constitute an Operand (also known as secondary resources)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Custom Resource Definition (CRD)&lt;/strong&gt; - an API of the Operator, providing the blueprint and validation rules for &lt;strong&gt;Custom Resources&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;level-1---basic-install&#34;&gt;Level 1 - Basic Install&lt;/h2&gt;
&lt;p&gt;Automated application provisioning and configuration management. This first capability level means your operator can fully provision an application through a custom resource, allowing all installation configuration details to be specified in the CR. It should also be possible to install the operator itself in multiple ways (kubectl, OLM, Catalog source). Any configuration required to make the Operand run should be configured through the CR if possible. Avoid the practice of requiring the user to create/manage configuration files outside of Kubernetes.&lt;/p&gt;
&lt;h3 id=&#34;installation-of-the-workload&#34;&gt;Installation of the workload&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operator deploys an Operand or configures off-cluster resources&lt;/li&gt;
&lt;li&gt;Operator waits for managed resources to reach a healthy state&lt;/li&gt;
&lt;li&gt;Operator conveys readiness of application or managed resources to the user leveraging the &lt;code&gt;status&lt;/code&gt; block of the Custom Resource&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; an Operator deploys a database by creating &lt;code&gt;Deployment&lt;/code&gt;, &lt;code&gt;ServiceAccount&lt;/code&gt;, &lt;code&gt;RoleBinding&lt;/code&gt;, &lt;code&gt;ConfigMap&lt;/code&gt;, &lt;code&gt;PersistentVolumeClaim&lt;/code&gt; and &lt;code&gt;Secret&lt;/code&gt; object, initializes an empty database schema and signals readiness of the database to accept queries.&lt;/p&gt;
&lt;h3 id=&#34;configuration-of-the-workload&#34;&gt;Configuration of the workload&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operator provides configuration via the &lt;code&gt;spec&lt;/code&gt; section of the Custom Resource&lt;/li&gt;
&lt;li&gt;Operator reconciles configuration and updates to it with the status of the managed resources&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; an Operator, managing a database, offers increasing the capacity of the database by resizing the underlying &lt;code&gt;PersistentVolumeClaim&lt;/code&gt; based on changes the databases Custom Resource instance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Guiding questions to determine Operator reaching Level 1&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;What installation configuration can be set in the CR?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What additional installation configuration could still be added?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Can you set operand configuration in the CR? If so, what configuration is supported for each operand?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Can you override the operand images through the CR or an environment variable of the Operator deployment?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does the managed application / workload get updated in a non-disruptive fashion when the configuration of the CR is changed?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does the status of the CR reflect that configuration changes are currently applied?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What additional operand configuration could still be added?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Do all of the instantiated CRs include a status block? If so, does it provide enough insight to the user about the application state?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Do all of your CRs have documentation listing valid values and mandatory fields?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If your operator is packaged for OLM, does its CSV list all images used in the CSV under &lt;code&gt;spec.relatedImages&lt;/code&gt;?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;level-2---seamless-upgrades&#34;&gt;Level 2 - Seamless Upgrades&lt;/h2&gt;
&lt;p&gt;Seamless upgrades mean the upgrade is as easy as possible for the user. You should support seamless upgrades of both your operator and operand, these would normally go hand in hand, an upgrade of the operator would automatically ensure the instantiated resources for each CR are in the new desired state and which would upgrade your operand. Upgrade may also be defined in multiple ways, such as updating the software of the operand - and other internals specific to the application - such as schema migrations. It should be very clear what is upgraded when this takes place, and what is not.&lt;/p&gt;
&lt;h3 id=&#34;upgrade-of-the-managed-workload&#34;&gt;Upgrade of the managed workload&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operand can be upgraded in the process of upgrading the Operator, or&lt;/li&gt;
&lt;li&gt;Operand can be upgraded as part of changing the CR&lt;/li&gt;
&lt;li&gt;Operator understands how to upgrade older versions of the Operand, managed previously by an older version of the Operator&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;upgrade-of-the-operator&#34;&gt;Upgrade of the Operator&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operator can be upgraded seamlessly and can either still manage older versions of the Operand or update them&lt;/li&gt;
&lt;li&gt;Operator conveys inability to manage an unsupported version of the Operand in the &lt;code&gt;status&lt;/code&gt; section of the CR&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; An Operator managing a database can update an existing database from a previous to a newer version without data loss. The Operator might do so as part of a configuration change or as part of an update of the Operator itself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Guiding questions to determine Operator reaching Level 2&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Can your Operator upgrade your Operand?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your Operator upgrade your Operand during updates of the Operator?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Can your Operator manage older Operand version versions?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Is the Operand upgrade non disruptive?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If there is downtime during an upgrade, does the Operator convey this in the &lt;code&gt;status&lt;/code&gt; of the CR?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;level-3---full-lifecycle&#34;&gt;Level 3 - Full Lifecycle&lt;/h2&gt;
&lt;p&gt;It should be possible to backup and restore the operand from the operator itself without any additional manual intervention other than triggering these operations. The operand data that should be backed up is any stateful data managed by the operand. You don’t need to backup the CR itself or the k8s resources created by the operator as the operator should return all resources to the same state if the CR is recreated. If your operator does not already setup the operand with other k8s resilient best practices, this should be completed to achieve this capability level. This includes liveness and readiness probes, multiple replicas, rolling deployment strategies, pod disruption budgets, CPU and memory requests and limits.&lt;/p&gt;
&lt;h3 id=&#34;lifecycle-features&#34;&gt;Lifecycle features&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operator provides the ability to create backups of the Operand&lt;/li&gt;
&lt;li&gt;Operator is able to restore a backup of an Operand&lt;/li&gt;
&lt;li&gt;Operator orchestrates complex re-configuration flows on the Operand&lt;/li&gt;
&lt;li&gt;Operator implements fail-over and fail-back of clustered Operands&lt;/li&gt;
&lt;li&gt;Operator supports add/removing members to a clustered Operand&lt;/li&gt;
&lt;li&gt;Operator enables application-aware scaling of the Operand&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; an Operator managing a database provides the ability to create an application consistent backup of the data by flushing the database log and quiescing the write activity to the database files.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Guiding questions to determine Operator reaching Level 3&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Does your Operator support backing up the Operand?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your Operator support restoring an Operand from a backup and get it under management again?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your Operator wait for reconfiguration work to be finished and in the expected sequence?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Is your Operator taking cluster quorum into account, if present?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your Operator allow adding/removing read-only slave instances of your Operator?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your operand have a Liveness probe?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your operand have a Readiness probe which will fail if any aspect of the operand is not ready? e.g. if the connection to the database fails.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your operand use a rolling deployment strategy?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your operator create a PodDisruptionBudget resource for your operand pods?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your operand have CPU requests and limits set?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;level-4---deep-insights&#34;&gt;Level 4 - Deep Insights&lt;/h2&gt;
&lt;p&gt;Setup full monitoring and alerting for your operand. All resources such as Prometheus rules (alerts) and Grafana dashboards should be created by the operator when the operand CR is instantiated. The RED method&lt;sup&gt;1&lt;/sup&gt; is a good place to start with knowing what metrics to expose.
Aim to have as few alerts as possible, by alerting on symptoms that are associated with end-user pain rather than trying to catch every possible way that pain could be caused. Alerts should link to relevant consoles and make it easy to figure out which component is at fault
Native k8s objects emit events (“Events” objects) for situations users or administrators should be alerted about. Your operator should do similar for state changes related to your operand. “Custom”, here, means that it should emit events specific to your operator/operand outside of the events already emitted by their deployment methodology.  This, in conjunction with status descriptors for the CR conditions, give much needed visibility into actions taken by your operator/operand. Operators are codified domain-specific knowledge. Your end user should not need this domain-specific knowledge to gain visibility into what’s happening with their resource.
Please, ensure that you look at the Kubernetes API conventions in the &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#events&#34;&gt;Events&lt;/a&gt; and &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status&#34;&gt;status&lt;/a&gt; sections to know how to properly deal with them.&lt;/p&gt;
&lt;h3 id=&#34;monitoring&#34;&gt;Monitoring&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operator exposing metrics about its health&lt;/li&gt;
&lt;li&gt;Operator exposes health and performance metrics about the Operand&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;alerting-and-events&#34;&gt;Alerting and Events&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operand sends useful alerts&lt;/li&gt;
&lt;li&gt;Custom Resources emit custom events&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A database Operator continues to parse the logging output of the database software and understands noteworthy log events, e.g. running out of space for database files and produces alerts. The operator also instruments the database and exposes application level, e.g. database queries per second&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Guiding questions to determine Operator reaching Level 4&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Does your Operator expose a health metrics endpoint?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your Operator expose Operand alerts?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Do you have Standard Operating Procedures (SOPs) for each alert?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does you operator create critical alerts when the service is down and warning alerts for all other alerts?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your Operator watch the Operand to create alerts?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your Operator emit custom Kubernetes events?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does your Operator expose Operand performance metrics?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; The RED method
The RED Method defines the three key metrics for every service in your architecture.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rate (the number of requests per second)&lt;/li&gt;
&lt;li&gt;Errors (the number of those requests that are failing)&lt;/li&gt;
&lt;li&gt;Duration (the amount of time those requests take)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that by building projects using Operator-SDK or &lt;a href=&#34;https://github.com/kubernetes-sigs/kubebuilder&#34;&gt;Kubebuilder&lt;/a&gt; CLI tools your solution leverages &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime&#34;&gt;controller-runtime&lt;/a&gt; which provides the following &lt;a href=&#34;https://book.kubebuilder.io/reference/metrics-reference.html&#34;&gt;reference&lt;/a&gt; exported by default. For further information, see the &lt;a href=&#34;https://book.kubebuilder.io/reference/metrics.html&#34;&gt;metrics&lt;/a&gt; documentation to understand how to enable monitoring and add custom metrics . Also, you may want to give a look at the &lt;a href=&#34;https://book.kubebuilder.io/plugins/available/grafana-v1-alpha&#34;&gt;(grafana/v1-alpha)&lt;/a&gt; which provides some JSON manifests to create Grafana dashboards using the default metrics exported.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;level-5---auto-pilot&#34;&gt;Level 5 - Auto Pilot&lt;/h2&gt;
&lt;p&gt;The highest capability level aims to significantly reduce/eliminate any remaining manual intervention in managing the operand. The operator should configure the Operand to auto-scale as load picks up. The Operator should understand the application-level performance indicators and determine when it&amp;rsquo;s healthy and performing well. The operator should attempt to automatically fix an unhealthy operand. The operator should tune the operands performance, this could include scheduling on another node the pods are running on or modifying operand configuration.&lt;/p&gt;
&lt;h3 id=&#34;auto-scaling&#34;&gt;Auto-scaling&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operator scales the Operand up under increased load based on Operand metric&lt;/li&gt;
&lt;li&gt;Operator scales the Operand down below a certain load based on Operand metric&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;auto-healing&#34;&gt;Auto-Healing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operator can automatically heal unhealthy Operands based on Operand metrics/alerts/logs&lt;/li&gt;
&lt;li&gt;Operator can prevent the Operand from transitioning into an unhealthy state based on Operand metrics&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;auto-tuning&#34;&gt;Auto-tuning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operator is able to automatically tune the Operand to a certain workload pattern&lt;/li&gt;
&lt;li&gt;Operator dynamically shifts workloads onto best suited nodes&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;abnormality-detection&#34;&gt;Abnormality detection&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Operator determines deviations from a standard performance profile&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A database operator monitors the query load of the database and automatically scales additional read-only slave replicas up and down. The operator also detects subpar index performance and automatically rebuilds the index in times of reduced load. Further, the operator understands the normal performance profile of the database and creates alerts on excessive amount of slow queries. In the event of slow queries and high disk latency the Operator automatically transitions the database files to another &lt;code&gt;PersistentVolume&lt;/code&gt; of a higher performance class.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Guiding questions to determine Operator reaching Level 5&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Can your operator read metrics such as requests per second or other relevant metrics and auto-scale horizontally or vertically, i.e., increasing the number of pods or  resources used by pods?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Based on question number 1 can it scale down or decrease the number of pods or the total amount of resources used by pods?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Based on the deep insights built upon level 4 capabilities can your operator determine when an operand became unhealthy and take action such as redeploying, changing configurations, restoring backups etc.?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Again considering that with level 4 deep insights the operator has information to learn the performance baseline dynamically and can learn the best configurations for peak performance can it adjust the configurations to do so?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Can it move the workloads to better nodes, storage or networks to do so?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Can it detect and alert when anything is working below the learned performance baseline that can’t be corrected automatically?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Multi-Tenancy</title>
      <link>/docs/best-practices/multi-tenancy/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/multi-tenancy/</guid>
      <description>
        
        
        &lt;h2 id=&#34;networkpolicy&#34;&gt;NetworkPolicy&lt;/h2&gt;
&lt;p&gt;If your Operator creates or manages &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/network-policies/&#34;&gt;NetworkPolicy&lt;/a&gt; configurations ensure that your solution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;applies fine-grained network policies to the extent that is required for your managed application to function properly&lt;/li&gt;
&lt;li&gt;applies fine-grained network policies to enable your managed application internal components to communicate among each other&lt;/li&gt;
&lt;li&gt;allows users to configure your operator so it does not create or manage &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/network-policies/&#34;&gt;NetworkPolicy&lt;/a&gt; instances&lt;/li&gt;
&lt;li&gt;does not create &lt;code&gt;allow traffic from everywhere in the cluster&lt;/code&gt; type policies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/network-policies/&#34;&gt;NetworkPolicies&lt;/a&gt; are popular in multi-tenant cluster to provide an extra layer
of segregation among tenants within SDN solutions. Users typically customize this extensively with goal of disallowing network traffic among unrelated
tenants. Operators that deploy an &lt;code&gt;accept all traffic from anywhere in the cluster&lt;/code&gt; style policy, are creating an obstacle in
pursuing this goal, especially in instances where these policies cannot be disabled. In security-conscious environments policies like these are not allowed
in production. In such cases your operator should minimally &lt;strong&gt;have the option to prevent &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/network-policies/&#34;&gt;NetworkPolicy&lt;/a&gt; objects from being
created&lt;/strong&gt; and leave this responsibility to the user. In more advanced cases, your operator should create &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/network-policies/&#34;&gt;NetworkPolicy&lt;/a&gt;
configurations that follow the least-privilege principle, i.e. denying access to everything and from everywhere by default and only allowing access to specific authorized resources from specific authorized components.&lt;/p&gt;
&lt;h2 id=&#34;traffic-sharding&#34;&gt;Traffic sharding&lt;/h2&gt;
&lt;p&gt;The goal is to split or to isolated ingress traffic from certain environments, e.g. production and development environments, ending up on
different routers and in this way, being managed by a different Ingress controller. This is a popular configuration
option for heavily populated multi-tenant clusters, with several &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/&#34;&gt;IngressController&lt;/a&gt; deployed.&lt;/p&gt;
&lt;p&gt;If your Operator creates ingress resources the recommendation is to allow the users to customize them,
through the use of a CRD. The required
&lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class&#34;&gt;IngressClass&lt;/a&gt; needs then to be
propagated to the ingress resources created so that they get picked up by the desired &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/&#34;&gt;IngressController&lt;/a&gt;.
Annotations are deprecated in favour of &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class&#34;&gt;IngressClass&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;route-resources&#34;&gt;Route resources&lt;/h3&gt;
&lt;p&gt;To run on the OpenShift distribution of Kubernetes you probably will use
the &lt;a href=&#34;https://docs.openshift.com/container-platform/4.9/rest_api/network_apis/route-route-openshift-io-v1.html#route-route-openshift-io-v1&#34;&gt;Route&lt;/a&gt; API. When sharding these routes may be configured with a label selector.
Based on this label selector they will amend their configuration when a route (having the label)
is created or not (if the route does not have the label). The label is applied at the &lt;code&gt;Route&lt;/code&gt; level
and there is no pre-defined convention here, so users set these custom labels in
accordance to how they configured their &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/&#34;&gt;IngressController from operator.openshift.io/v1&lt;/a&gt; instances.&lt;/p&gt;
&lt;p&gt;In this way, &lt;strong&gt;your operator should allow the user to specify custom labels for any
Route that it manages&lt;/strong&gt;. Check the &lt;a href=&#34;https://docs.openshift.com/container-platform/4.9/networking/ingress-operator.html#nw-ingress-sharding-route-labels_configuring-ingress&#34;&gt;doc&lt;/a&gt; and this &lt;a href=&#34;https://rcarrata.com/openshift/ocp4_route_sharding/&#34;&gt;blog&lt;/a&gt; for an end-to-end examples
and further information.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Release Guide</title>
      <link>/docs/contribution-guidelines/releasing/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/contribution-guidelines/releasing/</guid>
      <description>
        
        
        &lt;p&gt;These steps describe how to conduct a release of the operator-sdk repo using example versions.
Replace these versions with the current and new version you are releasing, respectively.&lt;/p&gt;
&lt;h2 id=&#34;table-of-contents&#34;&gt;Table of Contents:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#prerequisites&#34;&gt;Prerequisites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#major-and-minor-releases&#34;&gt;Major and minor releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#patch-releases&#34;&gt;Patch releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#scorecard-test-kuttl-image-releases&#34;&gt;&lt;code&gt;scorecard-test-kuttl&lt;/code&gt; image releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#helpful-tips-and-information&#34;&gt;Release tips&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;The following tools and permissions are needed to conduct a release of the operator-sdk repo.&lt;/p&gt;
&lt;h3 id=&#34;tools&#34;&gt;Tools&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://git-scm.com/downloads&#34;&gt;&lt;code&gt;git&lt;/code&gt;&lt;/a&gt;: version 2.2+&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gnu.org/software/make/&#34;&gt;&lt;code&gt;make&lt;/code&gt;&lt;/a&gt;: version 4.2+&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gnu.org/software/sed/&#34;&gt;&lt;code&gt;sed&lt;/code&gt;&lt;/a&gt;: version 4.3+&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;permissions&#34;&gt;Permissions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Must be a &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/OWNERS&#34;&gt;Netlify admin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Must be an admin on the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/settings/access&#34;&gt;operator-sdk repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;setting-up-tools-for-macos-users&#34;&gt;Setting Up Tools for MacOS Users&lt;/h3&gt;
&lt;p&gt;To install the prerequisite tools on MacOS, complete the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install GNU &lt;code&gt;sed&lt;/code&gt; and &lt;code&gt;make&lt;/code&gt;, which may not be installed by default:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt; brew install gnu-sed make
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify that the version of &lt;code&gt;make&lt;/code&gt; is higher than 4.2 using command &lt;code&gt;make --version&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the gnubin directory for &lt;code&gt;make&lt;/code&gt; to your PATH from your &lt;code&gt;~/.bashrc&lt;/code&gt;
to allow you to use &lt;code&gt;gmake&lt;/code&gt; as &lt;code&gt;make&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#204a87&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;export PATH=&amp;#34;/usr/local/opt/make/libexec/gnubin:$PATH&amp;#34;&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify that the version of &lt;code&gt;sed&lt;/code&gt; is higher than 4.3 using command &lt;code&gt;gnu-sed --version&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the gnubin directory for &lt;code&gt;gnu-sed&lt;/code&gt; to your PATH from your &lt;code&gt;~/.bashrc&lt;/code&gt;
to allow you to use &lt;code&gt;gnu-sed&lt;/code&gt; as &lt;code&gt;sed&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#204a87&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;export PATH=&amp;#34;/usr/local/opt/gnu-sed/libexec/gnubin:$PATH&amp;#34;&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;major-and-minor-releases&#34;&gt;Major and Minor Releases&lt;/h2&gt;
&lt;p&gt;We will use the &lt;code&gt;v1.3.0&lt;/code&gt; release version in this example.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Be sure to substitute
the version you are releasing into the provided commands.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To perform a major or minor release, you must perform the following actions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ensure a new Netlify branch is created&lt;/li&gt;
&lt;li&gt;Create a release branch and lock down the master branch&lt;/li&gt;
&lt;li&gt;Create and merge a PR for the release branch&lt;/li&gt;
&lt;li&gt;Unlock the master branch and push a release tag to it&lt;/li&gt;
&lt;li&gt;Perform some clean up actions and announce the new release to the community&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;procedure&#34;&gt;Procedure&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Before creating a new release branch&lt;/strong&gt;, it is imperative to perform the following initial setup steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In the &lt;a href=&#34;https://app.netlify.com/sites/operator-sdk/settings/deploys#branches&#34;&gt;Branches and deploy contexts&lt;/a&gt;
pane in Netlify, click into the Additional branches list section and add &lt;code&gt;v1.13.x&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;This will watch the branch when there are changes on Github (creating the branch, or adding a commit).&lt;/li&gt;
&lt;li&gt;NOTE: You must be a &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/OWNERS&#34;&gt;Netlify admin&lt;/a&gt; in order to edit the branches list.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a release branch by running the following, assuming the upstream SDK repo is the &lt;code&gt;upstream&lt;/code&gt; remote on your machine:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git checkout master
git fetch upstream master
git pull master
git checkout -b v1.3.x
git push upstream v1.3.x
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make sure that the list of supported OLM versions is up to date:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identify if a new version of OLM needs to be officially supported by ensuring that the latest three releases listed on the &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/releases&#34;&gt;OLM release page&lt;/a&gt; are all listed as supported in the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/website/content/en/docs/overview/_index.md#olm-version-compatibility&#34;&gt;Overview&lt;/a&gt; section of the SDK docs.&lt;/li&gt;
&lt;li&gt;If a new version of OLM needs to be added and an old version removed, follow the steps in the &lt;a href=&#34;#updating-olm-bindata&#34;&gt;updating OLM bindata&lt;/a&gt; section before moving onto the next step.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lock down the &lt;code&gt;master&lt;/code&gt; branch to prevent further commits before the release completes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;code&gt;Settings -&amp;gt; Branches&lt;/code&gt; in the SDK repo.&lt;/li&gt;
&lt;li&gt;Under &lt;code&gt;Branch protection rules&lt;/code&gt;, click &lt;code&gt;Edit&lt;/code&gt; on the &lt;code&gt;master&lt;/code&gt; branch rule.&lt;/li&gt;
&lt;li&gt;In section &lt;code&gt;Protect matching branches&lt;/code&gt; of the &lt;code&gt;Rule settings&lt;/code&gt; box, increase the number of required approving reviewers to 6.&lt;/li&gt;
&lt;li&gt;Scroll down to save your changes to protect the &lt;code&gt;master&lt;/code&gt; branch.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create and push a release commit&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new branch to push the release commit:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;RELEASE_VERSION&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;v1.3.0
git checkout master
git pull master
git checkout -b release-&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the top-level &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/Makefile&#34;&gt;Makefile&lt;/a&gt; variable &lt;code&gt;IMAGE_VERSION&lt;/code&gt;
to the upcoming release tag &lt;code&gt;v1.3.0&lt;/code&gt;. This variable ensures sample projects have been tagged
correctly prior to the release commit.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sed -i -E &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;s/(IMAGE_VERSION = ).+/\1v1\.3\.0/g&amp;#39;&lt;/span&gt; Makefile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If this command fails on MacOS with a warning &amp;ldquo;sed is not found&amp;rdquo;, follow the step 5 in the &lt;a href=&#34;#setting-up-tools-for-macos-users&#34;&gt;Setting Up Tools for MacOS Users&lt;/a&gt; section to map &lt;code&gt;gsed&lt;/code&gt; to &lt;code&gt;sed&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the pre-release &lt;code&gt;make&lt;/code&gt; target:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make prerelease
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following changes should be present:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Makefile&lt;/code&gt;: IMAGE_VERSION should be modified to the upcoming release tag. (This variable ensures sampleprojects have been tagged correctly prior to the release commit.)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;changelog/generated/v1.3.0.md&lt;/code&gt;: commit changes (created by changelog generation).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;changelog/fragments/*&lt;/code&gt;: commit deleted fragment files (deleted by changelog generation).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;website/content/en/docs/upgrading-sdk-version/v1.3.0.md&lt;/code&gt;: commit changes (created by changelog generation).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;website/config.toml&lt;/code&gt;: commit changes (modified by release script).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testdata/*&lt;/code&gt;: Generated sample code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Commit these changes and push to your remote (assuming your remote is named &lt;code&gt;origin&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git add Makefile changelog website testdata
git commit -sm &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Release &lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&lt;/span&gt;
git push origin release-&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create and merge a new PR for the release-v1.3.0 branch created in step 5.4.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can force-merge your PR to the locked-down &lt;code&gt;master&lt;/code&gt;
if you have admin access to the operator-sdk repo, or ask an administrator to do so.&lt;/li&gt;
&lt;li&gt;Note that the docs PR check will fail because the site isn&amp;rsquo;t published yet; the PR can be merged anyways.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Unlock the &lt;code&gt;master&lt;/code&gt; branch&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;code&gt;Settings -&amp;gt; Branches&lt;/code&gt; in the SDK repo.&lt;/li&gt;
&lt;li&gt;Under &lt;code&gt;Branch protection rules&lt;/code&gt;, click &lt;code&gt;Edit&lt;/code&gt; on the &lt;code&gt;master&lt;/code&gt; branch rule.&lt;/li&gt;
&lt;li&gt;In section &lt;code&gt;Protect matching branches&lt;/code&gt; of the &lt;code&gt;Rule settings&lt;/code&gt; box, reduce the number of required approving reviewers back to 1.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create and push a release tag on &lt;code&gt;master&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Refresh your local &lt;code&gt;master&lt;/code&gt; branch, tag the release PR commit, and push to the main operator-sdk repo (assumes the remote&amp;rsquo;s name is &lt;code&gt;upstream&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git checkout master
git pull master
make tag
git push upstream refs/tags/&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fast-forward the &lt;code&gt;latest&lt;/code&gt; and release branches&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;latest&lt;/code&gt; branch points to the latest release tag to keep the main website subdomain up-to-date.
Run the following commands to do so:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git checkout latest
git reset --hard refs/tags/&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;
git push -f upstream latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Similarly, to update the release branch, run:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git checkout v1.3.x
git reset --hard refs/tags/&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;
git push -f upstream v1.3.x
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Post release steps&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Publish the new Netlify subdomain for version-specific docs.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Assuming that the Netlify prestep was done before the new branch was created, a new &lt;a href=&#34;https://app.netlify.com/sites/operator-sdk/settings/domain#branch-subdomains&#34;&gt;branch option&lt;/a&gt;
should be visible to Netlify Admins under Domain management &amp;gt; Branch subdomains and can be mapped to a subdomain. (Note: you may have to scroll down to the bottom of the Branch subdomains section to find the branch that is ready to be mapped.)&lt;/li&gt;
&lt;li&gt;Please test that this subdomain works by going to the link in a browser. You can use the link in the second column to jump to the docs page for this release.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make an &lt;a href=&#34;https://groups.google.com/g/operator-framework&#34;&gt;operator-framework Google Group&lt;/a&gt; post.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href=&#34;https://groups.google.com/g/operator-framework/c/2fBHHLQOKs8/m/VAd_zd_IAwAJ&#34;&gt;this post&lt;/a&gt; as an example.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Post to Kubernetes slack in #kubernetes-operators and #operator-sdk-dev.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href=&#34;https://kubernetes.slack.com/archives/C017UU45SHL/p1679082546359389&#34;&gt;this post&lt;/a&gt; as an example.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clean up the GitHub milestone&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/milestones&#34;&gt;GitHub milestone&lt;/a&gt;, bump any open issues to the following release.&lt;/li&gt;
&lt;li&gt;Close out the milestone.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the newly unsupported branch documentation (1.1.x in this example)to mark it as archived. (Note that this step does not need to be merged before the release is complete.)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Checkout the newly unsupported release branch:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git checkout v1.1.x
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modify the &lt;code&gt;website/config.toml&lt;/code&gt; file on lines 88-90 to be the following:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;version&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;v1.1&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;archived_version&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;url_latest_version&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;https://sdk.operatorframework.io&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;patch-releases&#34;&gt;Patch releases&lt;/h2&gt;
&lt;p&gt;We will use the &lt;code&gt;v1.3.1&lt;/code&gt; release version in this example.&lt;/p&gt;
&lt;h3 id=&#34;0-lock-down-release-branches-on-github&#34;&gt;0. Lock down release branches on GitHub&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Lock down the &lt;code&gt;v1.3.x&lt;/code&gt; branch to prevent further commits before the release completes:
&lt;ol&gt;
&lt;li&gt;Go to &lt;code&gt;Settings -&amp;gt; Branches&lt;/code&gt; in the SDK repo.&lt;/li&gt;
&lt;li&gt;Under &lt;code&gt;Branch protection rules&lt;/code&gt;, click &lt;code&gt;Edit&lt;/code&gt; on the &lt;code&gt;v*.&lt;/code&gt; branch rule.&lt;/li&gt;
&lt;li&gt;In section &lt;code&gt;Protect matching branches&lt;/code&gt; of the &lt;code&gt;Rule settings&lt;/code&gt; box, increase the number of required approving reviewers to &lt;code&gt;6&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;1-branch&#34;&gt;1. Branch&lt;/h3&gt;
&lt;p&gt;Create a new branch from the release branch (v1.3.x in this example). This branch should already exist prior to cutting a patch release.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;RELEASE_VERSION&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;v1.3.1
git checkout v1.3.x
git pull
git checkout -b release-&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;2-prepare-the-release-commit&#34;&gt;2. Prepare the release commit&lt;/h3&gt;
&lt;p&gt;Using the version for your release as the IMAGE_VERSION, execute the
following commands from the root of the project.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Update the IMAGE_VERSION in the Makefile&lt;/span&gt;
sed -i -E &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;s/(IMAGE_VERSION = ).+/\1v1\.3\.1/g&amp;#39;&lt;/span&gt; Makefile
&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;#  Run the pre-release `make` target:&lt;/span&gt;
make prerelease
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All of the following changes should be present (and no others).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Makefile: IMAGE_VERSION should be modified to the upcoming release tag. (This variable ensures sampleprojects have been tagged correctpy priror to the release commit.)&lt;/li&gt;
&lt;li&gt;changelog/: all fragments should be deleted and consolidated into the new file &lt;code&gt;changelog/generated/v1.3.1.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;docs: If there are migration steps, a new migration doc will be created. The installation docs should also contain a link update.&lt;/li&gt;
&lt;li&gt;testdata/: Generated samples and tests should have version bumps&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Commit these changes and push these changes &lt;strong&gt;to your fork&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git add Makefile changelog website testdata
git commit -sm &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Release &lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&lt;/span&gt;
git push -u origin release-&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;3-create-and-merge-pull-request&#34;&gt;3. Create and merge Pull Request&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Create a pull request against the &lt;code&gt;v1.3.x&lt;/code&gt; branch.&lt;/li&gt;
&lt;li&gt;Once approving review is given, merge. You may have to unlock the branch by setting
&amp;ldquo;required approving reviewers&amp;rdquo; to back to &lt;code&gt;1&lt;/code&gt;. (See step 0).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;4-create-a-release-tag&#34;&gt;4. Create a release tag&lt;/h3&gt;
&lt;p&gt;Pull down &lt;code&gt;v1.3.x&lt;/code&gt; and tag it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git checkout v1.3.x
git pull upstream v1.3.x
make tag
git push upstream refs/tags/&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;5-fast-forward-the-latest-branch&#34;&gt;5. Fast-forward the &lt;code&gt;latest&lt;/code&gt; branch&lt;/h3&gt;
&lt;p&gt;If the patch release is on the latest y-stream (in the example you would
not ff latest if there was a y-stream for v1.4.x), you will need to
fast-forward the &lt;code&gt;latest&lt;/code&gt; git branch.&lt;/p&gt;
&lt;p&gt;(The &lt;code&gt;latest&lt;/code&gt; branch points to the latest release tag to keep the main website subdomain up-to-date.)&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git checkout latest
git reset --hard tags/&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;
git push -f upstream latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;6-post-release-steps&#34;&gt;6. Post release steps&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Make an &lt;a href=&#34;https://groups.google.com/g/operator-framework&#34;&gt;operator-framework Google Group&lt;/a&gt; post.&lt;/li&gt;
&lt;li&gt;Post to Kubernetes slack in #kubernetes-operators and #operator-sdk-dev.&lt;/li&gt;
&lt;li&gt;In the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/milestones&#34;&gt;GitHub milestone&lt;/a&gt;, bump any open issues to the following release.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;
In case there are non-transient errors while building the release job, you must:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Revert the release PR. To do so, create a PR which reverts the patch release PR created in step &lt;a href=&#34;#3-create-and-merge-pull-request&#34;&gt;3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Fix what broke in the release branch.&lt;/li&gt;
&lt;li&gt;Re-run the release with an incremented minor version to avoid Go module errors (ex. if v1.3.1 broke, then re-run the release as v1.3.2). Patch versions are cheap so this is not a big deal.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;scorecard-test-kuttl-image-releases&#34;&gt;&lt;code&gt;scorecard-test-kuttl&lt;/code&gt; image releases&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;quay.io/operator-framework/scorecard-test-kuttl&lt;/code&gt; image is released separately from other images because it
contains the &lt;a href=&#34;https://hub.docker.com/r/kudobuilder/kuttl/tags&#34;&gt;&lt;code&gt;kudobuilder/kuttl&lt;/code&gt;&lt;/a&gt; image, which is subject to breaking changes.&lt;/p&gt;
&lt;p&gt;Release tags of this image are of the form: &lt;code&gt;scorecard-kuttl/vX.Y.Z&lt;/code&gt;, where &lt;code&gt;X.Y.Z&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; the current operator-sdk version.
For the latest version, query the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tags&#34;&gt;operator-sdk repo tags&lt;/a&gt; for &lt;code&gt;scorecard-kuttl/v&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The only step required is to create and push a tag.
This example uses version &lt;code&gt;v2.0.0&lt;/code&gt;, the first independent release version of this image:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;RELEASE_VERSION&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;scorecard-kuttl/v2.0.0
make tag
git push upstream refs/tags/&lt;span style=&#34;color:#000&#34;&gt;$RELEASE_VERSION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/actions/workflows/deploy.yml&#34;&gt;&lt;code&gt;deploy/image-scorecard-test-kuttl&lt;/code&gt;&lt;/a&gt;
Action workflow will build and push this image.&lt;/p&gt;
&lt;h2 id=&#34;helpful-tips-and-information&#34;&gt;Helpful Tips and Information&lt;/h2&gt;
&lt;h3 id=&#34;binaries-and-signatures&#34;&gt;Binaries and Signatures&lt;/h3&gt;
&lt;p&gt;Binaries will be signed using our CI system&amp;rsquo;s GPG key. Both binary and signature will be uploaded to the release.&lt;/p&gt;
&lt;h3 id=&#34;release-branches&#34;&gt;Release Branches&lt;/h3&gt;
&lt;p&gt;Each minor release has a corresponding release branch of the form &lt;code&gt;vX.Y.x&lt;/code&gt;, where &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Y&lt;/code&gt; are the major and minor
release version numbers and the &lt;code&gt;x&lt;/code&gt; is literal. This branch accepts bug fixes according to our &lt;a href=&#34;/docs/upgrading-sdk-version/backport-policy&#34;&gt;backport policy&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;cherry-picking&#34;&gt;Cherry-picking&lt;/h3&gt;
&lt;p&gt;Once a minor release is complete, bug fixes can be merged into the release branch for the next patch release.
Fixes can be added automatically by posting a &lt;code&gt;/cherry-pick v1.3.x&lt;/code&gt; comment in the &lt;code&gt;master&lt;/code&gt; PR, or manually by running:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git checkout v1.3.x
git checkout -b cherrypick/some-bug
git cherry-pick &amp;lt;commit&amp;gt;
git push upstream cherrypick/some-bug
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create and merge a PR from your branch to &lt;code&gt;v1.3.x&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;github-release-information&#34;&gt;GitHub Release Information&lt;/h3&gt;
&lt;p&gt;GitHub releases live under the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/releases&#34;&gt;&lt;code&gt;Releases&lt;/code&gt; tab&lt;/a&gt; in the operator-sdk repo.&lt;/p&gt;
&lt;h3 id=&#34;updating-olm-bindata&#34;&gt;Updating OLM Bindata&lt;/h3&gt;
&lt;p&gt;Prior to an Operator SDK release, add bindata (if required) for a new OLM version by following these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the new version to the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/6002c70fe770cdaba9ba99da72685e0e7b6b69e8/Makefile#L45&#34;&gt;&lt;code&gt;OLM_VERSIONS&lt;/code&gt;&lt;/a&gt; variable in the Makefile.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remove the &lt;em&gt;lowest&lt;/em&gt; version from that variable, as &lt;code&gt;operator-sdk&lt;/code&gt; only supports 3 versions at a time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run &lt;code&gt;make bindata&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check that all files were correctly updated by running this script from the root directory of the repository:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;./hack/check-olm.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the check shows that files were missed by the make target, manually edit them to add the new version and remove the obsolete version.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check that the list of supported OLM versions stated in the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/website/content/en/docs/overview/_index.md#olm-version-compatibility&#34;&gt;&lt;code&gt;Overview&lt;/code&gt;&lt;/a&gt; section of SDK documentation is updated.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the changed files to ensure that they will be committed as part of the release commit:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git add -u
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;patch-releases-in-parallel&#34;&gt;Patch Releases in Parallel&lt;/h3&gt;
&lt;p&gt;The following should be considered when doing parallel patch releases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Releasing in order is nice but not worth the inconvenience. Release order affects the order on GitHub releases, and which
is labeled &amp;ldquo;latest release&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Do not unlock v.* branches while other releases are in progress. Instead, have an admin do the merges.&lt;/li&gt;
&lt;li&gt;Release announcements should be consolidated.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Ansible Based Operator Testing with Molecule</title>
      <link>/docs/building-operators/ansible/testing-guide/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/testing-guide/</guid>
      <description>
        
        
        &lt;h2 id=&#34;getting-started&#34;&gt;Getting started&lt;/h2&gt;
&lt;h3 id=&#34;requirements&#34;&gt;Requirements&lt;/h3&gt;
&lt;p&gt;To begin, you should have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The latest version of the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk&#34;&gt;operator-sdk&lt;/a&gt; installed.&lt;/li&gt;
&lt;li&gt;Docker installed and running&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ansible/molecule&#34;&gt;Molecule&lt;/a&gt; &amp;gt;= v3.0&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ansible/ansible&#34;&gt;Ansible&lt;/a&gt; &amp;gt;= v2.9&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-client/python&#34;&gt;The Python Kubernetes client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;An initialized Ansible Operator project, with the molecule directory present.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;  If you initialized a project with a previous version of operator-sdk, you can generate a new dummy project and copy in the &lt;code&gt;molecule&lt;/code&gt; directory. Just be sure to generate the dummy project with the same &lt;code&gt;api-version&lt;/code&gt; and &lt;code&gt;kind&lt;/code&gt;, or some of the generated files will not work without modification. Your top-level project structure should look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```
.
├── config
├── Dockerfile
├── Makefile
├── molecule
├── playbooks
├── PROJECT
├── requirements.yml
├── roles
└── watches.yaml

```
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;The Ansible content specified in &lt;code&gt;requirements.yml&lt;/code&gt; will also need to be installed. You can install them with &lt;code&gt;ansible-galaxy collection install -r requirements.yml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- TODO(fabianvf, asmacdo): update this section based on the new molecule scaffolding --&gt;
&lt;h3 id=&#34;molecule-scenarios&#34;&gt;Molecule scenarios&lt;/h3&gt;
&lt;p&gt;If you look into the &lt;code&gt;molecule&lt;/code&gt; directory, you will see four directories (&lt;code&gt;default&lt;/code&gt;, &lt;code&gt;test-local&lt;/code&gt;,&lt;code&gt;cluster&lt;/code&gt;, &lt;code&gt;templates&lt;/code&gt;). The &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;test-local&lt;/code&gt;, and &lt;code&gt;cluster&lt;/code&gt; directories contain a set of files that together make up what is known as a molecule &lt;em&gt;scenario&lt;/em&gt;. The &lt;code&gt;templates&lt;/code&gt; directory contains Jinja templates that are used by multiple scenarios to configure the Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;Our molecule scenarios have the following basic structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.
├── molecule.yml
├── prepare.yml
├── converge.yml
└── verify.yml
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;molecule.yml&lt;/code&gt; is a configuration file for molecule. It defines what driver to use to stand up an environment and the associated configuration, linting rules, and a variety of other configuration options. For full documentation on the options available here, see the &lt;a href=&#34;https://molecule.readthedocs.io/configuration/&#34;&gt;molecule configuration documentation&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;prepare.yml&lt;/code&gt; is an Ansible playbook that is run once during the set up of a scenario. You can put any arbitrary Ansible in this playbook. It is used for one-time configuration of your test environment, for example, creating the cluster-wide &lt;code&gt;CustomResourceDefinition&lt;/code&gt; that your Operator will watch.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;converge.yml&lt;/code&gt; is an Ansible playbook that contains your core logic for the scenario. In a normal molecule scenario, this would import and run the associated role. For Ansible Operators, we mostly use this to create the Kubernetes resources necessary to deploy your operator into Kubernetes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Below we will walk through the structure and function of each file for each scenario.&lt;/p&gt;
&lt;h4 id=&#34;default&#34;&gt;default&lt;/h4&gt;
&lt;p&gt;The default scenario is intended for use during the development of your Ansible role or playbook, and will run it outside of the context of an operator. You can run this scenario with
&lt;code&gt;molecule test&lt;/code&gt; or &lt;code&gt;molecule converge&lt;/code&gt;. There is no corresponding &lt;code&gt;operator-sdk&lt;/code&gt; command for this scenario.&lt;/p&gt;
&lt;p&gt;The scenario has the following structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;molecule/default
├── molecule.yml
├── prepare.yml
├── converge.yml
└── verify.yml
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;molecule.yml&lt;/code&gt; for this scenario tells molecule to use the docker driver to bring up a Kubernetes-in-Docker container,
and by default exposes the API on the host&amp;rsquo;s port 9443. It also specifies a few inventory and environment
variables which are used in &lt;code&gt;prepare.yml&lt;/code&gt; and &lt;code&gt;converge.yml&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;prepare.yml&lt;/code&gt; ensures that a kubeconfig properly configured to connect to the Kubernetes-in-Docker cluster exists and
is mapped to the proper port, and also waits for the Kubernetes API to become available before allowing testing to begin.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;converge.yml&lt;/code&gt; imports and runs your role or playbook.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;verify.yml&lt;/code&gt; is an Ansible playbook where you can put tasks to verify that the state of your cluster matches what you expect.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;configuration&#34;&gt;Configuration&lt;/h5&gt;
&lt;p&gt;There are a few parameters you can tweak at runtime to change the behavior of your molecule run.
You can change these parameters by setting the environment variable before invoking molecule.&lt;/p&gt;
&lt;p&gt;The options supported by the default scenario are:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;Environment variable&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Default&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;KUBE_VERSION&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;1.17&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;The Kubernetes version to deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;TEST_CLUSTER_PORT&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;9443&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;The port on the host to expose the Kubernetes API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;TEST_OPERATOR_NAMESPACE&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;osdk-test&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;The namespace to run your role against&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;cluster&#34;&gt;cluster&lt;/h4&gt;
&lt;p&gt;The cluster scenario runs an end-to-end test of your operator against an existing cluster.
The operator image needs to be available to the cluster for this scenario to succeed.
This scenario will deploy your CRDs, RBAC, and operator into the cluster,
and then creates an instance of your CustomResource and runs your assertions to make sure the Operator responded properly.&lt;/p&gt;
&lt;p&gt;You can run this scenario with &lt;code&gt;molecule test&lt;/code&gt; or &lt;code&gt;molecule converge&lt;/code&gt;. There is no corresponding &lt;code&gt;operator-sdk&lt;/code&gt; command for this scenario.&lt;/p&gt;
&lt;p&gt;The scenario has the following structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;molecule/default
├── molecule.yml
├── create.yml
├── prepare.yml
├── converge.yml
├── verify.yml
└── destroy.yml
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;molecule.yml&lt;/code&gt; for this scenario uses the delegated driver, and does not spin up any additional infrastructure.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;create.yml&lt;/code&gt; is a no-op, but must be present for the delegated driver to work.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;prepare.yml&lt;/code&gt; ensures the CRD, namespace, and RBAC resources are present in the cluster.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;converge.yml&lt;/code&gt; creates your operator deployment, based on the template in &lt;code&gt;molecule/templates/operator.yaml.j2&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;verify.yml&lt;/code&gt; is an Ansible playbook where you can put tasks to verify that the state of your cluster matches what you expect. By default, it creates a Custom Resource and waits for reconciliation to complete successfully. There is an example assertion present as well.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;destroy.yml&lt;/code&gt; ensures that the namespace, RBAC resources, and CRD are deleted at the end of the run.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;configuration-1&#34;&gt;Configuration&lt;/h5&gt;
&lt;p&gt;There are a few parameters you can tweak at runtime to change the behavior of your molecule run.
You can change these parameters by setting the environment variable before invoking molecule.&lt;/p&gt;
&lt;p&gt;The options supported by the default scenario are:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;Environment variable&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Default&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;OPERATOR_IMAGE&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;None&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;em&gt;Required&lt;/em&gt; The image to use when deploying the operator into the cluster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;OPERATOR_PULL_POLICY&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Always&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;The pull policy to use when deploying the operator into the cluster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;KUBECONFIG&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;~/.kube/config&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;The path to the Kubeconfig for the cluster to test against&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;TEST_OPERATOR_NAMESPACE&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;osdk-test&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;The namespace to run your role against&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;test-local&#34;&gt;test-local&lt;/h4&gt;
&lt;p&gt;The test-local scenario runs a full end-to-end test of your operator that does not require an existing
cluster or external registry, and can run in CI environments that allow users to run privileged containers
(such as Travis).
It brings up a Kubernetes-in-docker cluster, builds your Operator, deploys it into the cluster,
and then creates an instance of your CustomResource and runs your assertions to make sure the Operator responded properly.
You can run this scenario with &lt;code&gt;molecule test -s local&lt;/code&gt;, or with &lt;code&gt;molecule converge -s test-local&lt;/code&gt; which will leave the environment up afterward.&lt;/p&gt;
&lt;p&gt;The scenario has the following structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;molecule/test-local
├── molecule.yml
├── prepare.yml
├── converge.yml
└── verify.yml
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;molecule.yml&lt;/code&gt; for this scenario tells molecule to use the docker driver to bring up a Kubernetes-in-Docker container with the project root mounted, and exposes the API on the host&amp;rsquo;s port 10443. It also specifies a few inventory and environment variables which are used in &lt;code&gt;prepare.yml&lt;/code&gt; and &lt;code&gt;converge.yml&lt;/code&gt;. It is very similar to the default scenario&amp;rsquo;s configuration.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;prepare.yml&lt;/code&gt; first runs the &lt;code&gt;prepare.yml&lt;/code&gt; from the default scenario to ensure the kubeconfig is present and the API is up.
It then runs the &lt;code&gt;prepare.yml&lt;/code&gt; from the cluster scenario to configure your cluster&amp;rsquo;s CRDs and RBAC.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;converge.yml&lt;/code&gt; connects to your Kubernetes-in-Docker container, and uses your mounted project root to build your Operator. This makes your Operator available to the cluster without needing to push it to an external registry. Then, it will ensure that a fresh deployment of your Operator is present in the cluster, using the template &lt;code&gt;molecule/templates/operator.yaml.j2&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;verify.yml&lt;/code&gt; will run the &lt;code&gt;verify.yml&lt;/code&gt; from the &lt;code&gt;cluster&lt;/code&gt; scenario, as the main difference between the &lt;code&gt;test-local&lt;/code&gt; and &lt;code&gt;cluster&lt;/code&gt; scenarios is the method of deployment, but not the behavior of the operator.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;configuration-2&#34;&gt;Configuration&lt;/h5&gt;
&lt;p&gt;There are a few parameters you can tweak at runtime to change the behavior of your molecule run.
You can change these parameters by setting the environment variable before invoking molecule.&lt;/p&gt;
&lt;p&gt;The options supported by the default scenario are:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;Environment variable&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Default&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;KUBE_VERSION&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;1.17&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;The Kubernetes version to deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;TEST_CLUSTER_PORT&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;10443&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;The port on the host to expose the Kubernetes API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;TEST_OPERATOR_NAMESPACE&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;osdk-test&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;The namespace to deploy the operator and associated resources&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;converge-vs-test&#34;&gt;converge vs test&lt;/h4&gt;
&lt;p&gt;The two most common molecule commands for testing during development are &lt;code&gt;molecule test&lt;/code&gt; and &lt;code&gt;molecule converge&lt;/code&gt;.
&lt;code&gt;molecule test&lt;/code&gt; performs a full loop, bringing a cluster up, preparing it, running your tasks, and tearing it down.
&lt;code&gt;molecule converge&lt;/code&gt; is more useful for iterative development, as it leaves your environment up between runs. This
can cause unexpected problems if you end up corrupting your environment during testing, but running &lt;code&gt;molecule destroy&lt;/code&gt;
will reset it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;molecule test&lt;/code&gt; performs a full loop, bringing a cluster up, preparing it, running your tasks, and tearing it down.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;molecule converge&lt;/code&gt; is more useful for iterative development, as it leaves your environment up between runs. This can cause unexpected problems if you end up corrupting your environment during testing, but running &lt;code&gt;molecule destroy&lt;/code&gt; will reset it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;writing-tests&#34;&gt;Writing tests&lt;/h2&gt;
&lt;h3 id=&#34;adding-a-task&#34;&gt;Adding a task&lt;/h3&gt;
&lt;p&gt;The default operator that is generated by &lt;code&gt;operator-sdk new&lt;/code&gt; doesn&amp;rsquo;t do anything, so first we will need to add an
Ansible task so that the Operator does something we can verify. For this example, we will create a simple ConfigMap
with a single key.
We&amp;rsquo;ll be adding the task to &lt;code&gt;roles/example/tasks/main.yml&lt;/code&gt;, which should now look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
# tasks file for exampleapp
- name: create Example configmap
  kubernetes.core.k8s:
    definition:
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: &#39;test-data&#39;
        namespace: &#39;{{ ansible_operator_meta.namespace }}&#39;
      data:
        hello: world
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;adding-a-test&#34;&gt;Adding a test&lt;/h3&gt;
&lt;p&gt;Now that our Operator actually does some work, we can add a corresponding assert to &lt;code&gt;molecule/cluster/verify.yml&lt;/code&gt;.
We&amp;rsquo;ll also add a debug message so that we can see what the ConfigMap looks like.
The file should now look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---

- name: Verify
  hosts: localhost
  connection: local
  tasks:
    - debug: var=cm
      vars:
        cm: &#39;{{ lookup(&amp;quot;kubernetes.core.k8s&amp;quot;, api_version=&amp;quot;v1&amp;quot;, kind=&amp;quot;ConfigMap&amp;quot;, namespace=namespace, resource_name=&amp;quot;test-data&amp;quot;) }}&#39;
    - assert:
        that: cm.data.hello == &#39;world&#39;
      vars:
        cm: &#39;{{ lookup(&amp;quot;kubernetes.core.k8s&amp;quot;, api_version=&amp;quot;v1&amp;quot;, kind=&amp;quot;ConfigMap&amp;quot;, namespace=namespace, resource_name=&amp;quot;test-data&amp;quot;) }}&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now that we have a functional Operator, and an assertion of its behavior, we can verify that everything is working
by running &lt;code&gt;molecule test -s local&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;the-ansible-assert-and-fail-modules&#34;&gt;The Ansible &lt;code&gt;assert&lt;/code&gt; and &lt;code&gt;fail&lt;/code&gt; modules&lt;/h4&gt;
&lt;p&gt;These modules are handy for adding assertions and failure conditions to your Ansible Operator tests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.ansible.com/ansible/2.9/modules/assert_module.html&#34;&gt;assert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.ansible.com/ansible/2.9/modules/fail_module.html&#34;&gt;fail&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Designing Lean Operators</title>
      <link>/docs/best-practices/designing-lean-operators/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/designing-lean-operators/</guid>
      <description>
        
        
        &lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;One of the pitfalls that many operators are failing into is that they watch resources with high cardinality like secrets possibly in all namespaces. This has a massive impact on the memory used by the controller on big clusters. Such resources can be filtered by label or fields. The original doc design for &lt;code&gt;Filter cache ListWatch using selectors&lt;/code&gt; can be accessed from &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime/blob/master/designs/use-selectors-at-cache.md&#34;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT NOTE&lt;/strong&gt;
Requests to a client backed by a filtered cache for objects that do not match the filter will never return anything. In other words, filtered caches make the filtered-out objects invisible to the client.&lt;/p&gt;
&lt;h2 id=&#34;how-is-this-done-&#34;&gt;How is this done ?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;When creating the manager, you can add an Options struct to configure the Cache&lt;/li&gt;
&lt;li&gt;Each client.Object can be filtered with labels and fields&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;In this scenario, the user will configure the Cache to filter the secret object by it&amp;rsquo;s label. This will return a filtered cache for objects that match the filter.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;mgr&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;err&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;=&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ctrl.NewManager(ctrl.GetConfigOrDie()&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ctrl.Options{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;Cache&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.Options{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ByObject&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;map&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;client.Object&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;cache.ByObject{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&amp;amp;corev1.Secret{}:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.ByObject{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;	&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;Label&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;labels.SelectorFromSet(labels.Set{&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;app&amp;#34;: &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;app-name&amp;#34;&lt;/span&gt;})&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;})&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this scenario, the user will configure the Cache to filter the node object by it&amp;rsquo;s field name. This will return a filtered cache for objects that match the filter.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;mgr&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;err&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;=&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ctrl.NewManager(ctrl.GetConfigOrDie()&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ctrl.Options{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;Cache&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.Options{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ByObject&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;map&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;client.Object&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;cache.ByObject{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&amp;amp;corev1.Node{}:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.ByObject{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;	&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;Fields&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;labels.SelectorFromSet(fields.Set{&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;metadata.name&amp;#34;: &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;node01&amp;#34;&lt;/span&gt;})&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;})&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Development Tips</title>
      <link>/docs/building-operators/ansible/development-tips/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/development-tips/</guid>
      <description>
        
        
        &lt;p&gt;This document provides some useful information and tips for a developer
creating an operator powered by Ansible.&lt;/p&gt;
&lt;h2 id=&#34;getting-started-with-the-kubernetes-collection-for-ansible&#34;&gt;Getting started with the Kubernetes Collection for Ansible&lt;/h2&gt;
&lt;p&gt;Since we are interested in using Ansible for the lifecycle management of our
application on Kubernetes, it is beneficial for a developer to get a good
grasp of the &lt;a href=&#34;https://galaxy.ansible.com/kubernetes/core&#34;&gt;Kubernetes Collection for Ansible&lt;/a&gt;.
This Ansible collection allows a developer to either leverage their existing
Kubernetes resource files (written in YAML) or express the lifecycle
management in native Ansible. One of the biggest benefits of using Ansible in
conjunction with existing Kubernetes resource files is the ability to use
Jinja templating so that you can customize deployments with the simplicity of
a few variables in Ansible.&lt;/p&gt;
&lt;p&gt;The easiest way to get started is to install the collection on your local
machine and test it using a playbook.&lt;/p&gt;
&lt;h3 id=&#34;installing-the-kubernetes-collection-for-ansible&#34;&gt;Installing the Kubernetes Collection for Ansible&lt;/h3&gt;
&lt;p&gt;To install the Kubernetes Collection, one must first install Ansible 2.9+.
For example, on Fedora/Centos:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo dnf install ansible
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In addition to Ansible, a user must install the
&lt;a href=&#34;https://github.com/kubernetes-client/python&#34;&gt;Python Kubernetes Client&lt;/a&gt; package:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;pip3 install kubernetes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, install the Kubernetes Collection from ansible-galaxy:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;ansible-galaxy collection install kubernetes.core
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Alternatively, if you&amp;rsquo;ve already initialized your operator, you may have a
&lt;code&gt;requirements.yml&lt;/code&gt; file at the top level of your project. This file specifies
Ansible dependencies that need to be installed for your operator to function.
By default it will install the &lt;code&gt;kubernetes.core&lt;/code&gt; collection as well as
the &lt;code&gt;operator_sdk.util&lt;/code&gt; collection, which provides modules and plugins for
operator-specific operations.&lt;/p&gt;
&lt;p&gt;To install the dependent modules from this file, run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;ansible-galaxy collection install -r requirements.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;testing-the-kubernetes-collection-locally&#34;&gt;Testing the Kubernetes Collection locally&lt;/h3&gt;
&lt;p&gt;Sometimes it is beneficial for a developer to run the Ansible code from their
local machine as opposed to running/rebuilding the operator each time. To do
this, initialize a new project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;mkdir memcached-operator &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; memcached-operator
operator-sdk init --plugins&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;ansible --domain&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;example.com --group&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;cache --version&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;v1alpha1 --kind&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;Memcached --generate-role
ansible-galaxy collection install -r requirements.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Modify &lt;code&gt;roles/memcached/tasks/main.yml&lt;/code&gt; with desired Ansible logic. For this example
we will create and delete a ConfigMap based on the value of a variable named
&lt;code&gt;state&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;set&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ConfigMap&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;example-config&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;{{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;state&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;}}&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kubernetes.core.k8s&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;api_version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ConfigMap&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;example-config&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;state&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ state }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ignore_errors&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&#34;alert alert-primary&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;alert-heading&#34;&gt;Note&lt;/h4&gt;
Setting &lt;code&gt;ignore_errors: true&lt;/code&gt; is done so that deleting a nonexistent
ConfigMap doesn&amp;rsquo;t error out.
&lt;/div&gt;

&lt;p&gt;Modify &lt;code&gt;roles/memcached/defaults/main.yml&lt;/code&gt; to set &lt;code&gt;state&lt;/code&gt; to &lt;code&gt;present&lt;/code&gt; as default.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;state&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;present&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create an Ansible playbook &lt;code&gt;playbook.yml&lt;/code&gt; in the top-level directory which
includes role &lt;code&gt;memcached&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;hosts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;localhost&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;roles&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run the playbook:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ ansible-playbook playbook.yml
 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match &#39;all&#39;


PLAY [localhost] ***************************************************************************

TASK [Gathering Facts] *********************************************************************
ok: [localhost]

Task [memcached : set ConfigMap example-config to present]
changed: [localhost]

PLAY RECAP *********************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Check that the ConfigMap was created:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl get configmaps
NAME                    STATUS    AGE
example-config          Active    3s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Rerun the playbook setting &lt;code&gt;state&lt;/code&gt; to &lt;code&gt;absent&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ ansible-playbook playbook.yml --extra-vars state=absent
 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match &#39;all&#39;


PLAY [localhost] ***************************************************************************

TASK [Gathering Facts] *********************************************************************
ok: [localhost]

Task [memcached : set ConfigMap example-config to absent]
changed: [localhost]

PLAY RECAP *********************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Check that the ConfigMap was deleted:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl get configmaps
No resources found in default namespace.
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;using-ansible-inside-an-operator&#34;&gt;Using Ansible inside an Operator&lt;/h2&gt;
&lt;p&gt;Now that we have demonstrated using the Kubernetes Collection, we want to
trigger this Ansible logic when a custom resource changes. In the above
example, we want to map a role to a specific Kubernetes resource that the
operator will watch. This mapping is done in a file called &lt;code&gt;watches.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;custom-resource-file&#34;&gt;Custom Resource file&lt;/h3&gt;
&lt;p&gt;The Custom Resource (CR) file format is Kubernetes resource file. The object
has some mandatory fields:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;apiVersion&lt;/code&gt;:  The version of the Custom Resource that will be created.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kind&lt;/code&gt;:  The kind of the Custom Resource that will be created&lt;/li&gt;
&lt;li&gt;&lt;code&gt;metadata&lt;/code&gt;:  Kubernetes specific metadata to be created&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec&lt;/code&gt;:  This is the key-value list of variables which are passed to Ansible.
This field is optional and empty by default.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;annotations&lt;/code&gt;: Kubernetes specific annotations to be appended to the CR. See
the below section for Ansible Operator specific annotations. This field is optional.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;annotations-for-custom-resource&#34;&gt;Annotations for Custom Resource&lt;/h4&gt;
&lt;p&gt;This is the list of CR annotations which will modify the behavior of the operator:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ansible.operator-sdk/reconcile-period&lt;/code&gt;: Specifies the maximum time before a
reconciliation is triggered. Note that at scale, this can reduce
performance, see &lt;a href=&#34;/docs/building-operators/ansible/reference/watches&#34;&gt;watches&lt;/a&gt; reference for more information. This value
is parsed using the standard Go package &lt;a href=&#34;https://golang.org/pkg/time/&#34;&gt;time&lt;/a&gt;. Specifically
&lt;a href=&#34;https://golang.org/pkg/time/#ParseDuration&#34;&gt;ParseDuration&lt;/a&gt; is used which will apply the default
suffix of &lt;code&gt;s&lt;/code&gt; giving the value in seconds.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.example.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;example&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ansible.operator-sdk/reconcile-period&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;30s&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that a lower period will correct entropy more quickly, but reduce
responsiveness to change if there are many watched resources. Typically, this
option should only be used in advanced use cases where
&lt;code&gt;watchDependentResources&lt;/code&gt; is set to &lt;code&gt;False&lt;/code&gt;  and when is not possible to use
the watch feature. E.g To managing external resources that don’t raise
Kubernetes events.&lt;/p&gt;
&lt;h3 id=&#34;testing-an-ansible-operator-locally&#34;&gt;Testing an Ansible Operator locally&lt;/h3&gt;
&lt;p&gt;Once a developer is comfortable working with the above workflow, it will be
beneficial to test the logic inside an operator.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read the &lt;a href=&#34;../tutorial&#34;&gt;Ansible Operator tutorial&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Install &lt;code&gt;ansible-operator&lt;/code&gt; &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/c6796de/images/ansible-operator/Pipfile.lock&#34;&gt;dependencies&lt;/a&gt; using &lt;a href=&#34;https://pypi.org/project/pipenv/&#34;&gt;&lt;code&gt;pipenv&lt;/code&gt;&lt;/a&gt;
and their OS prerequisite &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/c6796de/images/ansible-operator/base.Dockerfile#L29&#34;&gt;packages&lt;/a&gt; (these will differ depending on OS) locally.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;run&lt;/code&gt; Makefile target runs the &lt;code&gt;ansible-operator&lt;/code&gt; binary locally, which reads from
&lt;code&gt;./watches.yaml&lt;/code&gt; and uses &lt;code&gt;~/.kube/config&lt;/code&gt; to communicate with a Kubernetes
cluster just as the &lt;code&gt;k8s&lt;/code&gt; modules do. The &lt;code&gt;install&lt;/code&gt; target registers the operator&amp;rsquo;s
&lt;code&gt;Memcached&lt;/code&gt; CustomResourceDefinition (CRD) with the apiserver.&lt;/p&gt;


&lt;div class=&#34;alert alert-primary&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;alert-heading&#34;&gt;Note&lt;/h4&gt;
You can customize the roles path by setting the environment variable
&lt;code&gt;ANSIBLE_ROLES_PATH&lt;/code&gt; or using the flag &lt;code&gt;ansible-roles-path&lt;/code&gt;. Note that if the
role is not found in &lt;code&gt;ANSIBLE_ROLES_PATH&lt;/code&gt;, then the operator will look for it
in &lt;code&gt;{{current directory}}/roles&lt;/code&gt;.
&lt;/div&gt;

&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make install run
/home/user/memcached-operator/bin/kustomize build config/crd | kubectl apply -f -
customresourcedefinition.apiextensions.k8s.io/memcacheds.cache.example.com created
/home/user/go/bin/ansible-operator run
{&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1595899073.9861593,&amp;quot;logger&amp;quot;:&amp;quot;cmd&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;Version&amp;quot;,&amp;quot;Go Version&amp;quot;:&amp;quot;go1.13.12&amp;quot;,&amp;quot;GOOS&amp;quot;:&amp;quot;linux&amp;quot;,&amp;quot;GOARCH&amp;quot;:&amp;quot;amd64&amp;quot;,&amp;quot;ansible-operator&amp;quot;:&amp;quot;v0.19.0+git&amp;quot;}
{&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1595899073.987384,&amp;quot;logger&amp;quot;:&amp;quot;cmd&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;WATCH_NAMESPACE environment variable not set. Watching all namespaces.&amp;quot;,&amp;quot;Namespace&amp;quot;:&amp;quot;&amp;quot;}
{&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1595899074.9504397,&amp;quot;logger&amp;quot;:&amp;quot;controller-runtime.metrics&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;metrics server is starting to listen&amp;quot;,&amp;quot;addr&amp;quot;:&amp;quot;:8080&amp;quot;}
{&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1595899074.9522583,&amp;quot;logger&amp;quot;:&amp;quot;watches&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;Environment variable not set; using default value&amp;quot;,&amp;quot;envVar&amp;quot;:&amp;quot;ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM&amp;quot;,&amp;quot;default&amp;quot;:2}
{&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1595899074.9524004,&amp;quot;logger&amp;quot;:&amp;quot;cmd&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;Environment variable not set; using default value&amp;quot;,&amp;quot;Namespace&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;envVar&amp;quot;:&amp;quot;ANSIBLE_DEBUG_LOGS&amp;quot;,&amp;quot;ANSIBLE_DEBUG_LOGS&amp;quot;:false}
{&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1595899074.9524298,&amp;quot;logger&amp;quot;:&amp;quot;ansible-controller&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;Watching resource&amp;quot;,&amp;quot;Options.Group&amp;quot;:&amp;quot;cache.example.com&amp;quot;,&amp;quot;Options.Version&amp;quot;:&amp;quot;v1&amp;quot;,&amp;quot;Options.Kind&amp;quot;:&amp;quot;Memcached&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now that the operator is watching resource &lt;code&gt;Memcached&lt;/code&gt; for events, the creation of a
Custom Resource will trigger our Ansible Role to be executed. Take a look at
&lt;code&gt;config/samples/cache_v1alpha1_memcached.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.example.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;memcached-sample&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since &lt;code&gt;spec&lt;/code&gt; is not set, Ansible is invoked with no extra variables. The next
section covers how extra variables are passed from a Custom Resource to
Ansible. This is why it is important to set sane defaults for the operator.&lt;/p&gt;
&lt;p&gt;Create a Custom Resource instance of Memcached with variable &lt;code&gt;state&lt;/code&gt; default to
&lt;code&gt;present&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;kubectl create -f config/samples/cache_v1alpha1_memcached.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check that ConfigMap &lt;code&gt;example-config&lt;/code&gt; was created:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl get configmaps
NAME                    STATUS    AGE
example-config          Active    3s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Modify &lt;code&gt;config/samples/cache_v1alpha1_memcached.yaml&lt;/code&gt; to set &lt;code&gt;state&lt;/code&gt; to
&lt;code&gt;absent&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.example.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached-sample&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;state&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;absent&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Apply the changes to Kubernetes and confirm that the ConfiMap is deleted:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;kubectl apply -f config/samples/cache_v1alpha1_memcached.yaml
kubectl get configmaps
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;testing-an-ansible-operator-on-a-cluster&#34;&gt;Testing an Ansible Operator on a cluster&lt;/h3&gt;
&lt;p&gt;Now that a developer is confident in the operator logic, testing the operator
inside of a pod on a Kubernetes cluster is desired. Running as a pod inside a
Kubernetes cluster is preferred for production use.&lt;/p&gt;
&lt;p&gt;To build the &lt;code&gt;memcached-operator&lt;/code&gt; image and push it to a registry:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make docker-build docker-push &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;example.com/memcached-operator:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Deploy the memcached-operator:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make install
make deploy &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;example.com/memcached-operator:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Verify that the memcached-operator is up and running:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl get deployment -n memcached-operator-system
NAME                     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
memcached-operator       1         1         1            1           1m
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;viewing-the-ansible-logs&#34;&gt;Viewing the Ansible logs&lt;/h3&gt;
&lt;p&gt;In order to see the logs from a particular operator you can run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;kubectl logs deployment/memcached-operator-controller-manager -n memcached-operator-system
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The logs contain the information about the Ansible run and are useful for
debugging your Ansible tasks. Note that the logs may contain much more
detailed information about the Ansible Operator&amp;rsquo;s internals and its
interactions with Kubernetes as well.&lt;/p&gt;
&lt;p&gt;Also, you can set the environment variable &lt;code&gt;ANSIBLE_DEBUG_LOGS&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt; to
check the full Ansible result in the logs in order to be able to debug it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;config/manager/manager.yaml&lt;/code&gt; and &lt;code&gt;config/default/manager_metrics_patch.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ANSIBLE_DEBUG_LOGS&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;True&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Occasionally while developing additional debug in the Operator logs is nice to have.
Using the memcached operator as an example, we can simply add the
&lt;code&gt;&amp;quot;ansible.sdk.operatorframework.io/verbosity&amp;quot;&lt;/code&gt; annotation to the Custom
Resource with the desired verbosity.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;cache.example.com/v1alpha1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Memcached&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example-memcached&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;ansible.sdk.operatorframework.io/verbosity&amp;#34;: &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;size&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;custom-resource-status-management&#34;&gt;Custom Resource Status Management&lt;/h2&gt;
&lt;p&gt;By default, an Ansible Operator will include the generic output from previous
Ansible run as the &lt;code&gt;status&lt;/code&gt; subresource of a CR. This includes the number of
successful and failed tasks and relevant error messages as shown below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;conditions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ansibleResult&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;changed&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;completion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;2018-12-03T13:45:57.13329&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;failures&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ok&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;6&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;skipped&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;lastTransitionTime&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;2018-12-03T13:45:57Z&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;message: &amp;#39;Status code was -1 and not [200]: Request failed&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&amp;lt;urlopen&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;error&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;Errno&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;113&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;No&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;route&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;host&amp;gt;&amp;#39;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;reason&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Failed&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;True&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Failure&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;lastTransitionTime&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;2018-12-03T13:46:13Z&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;message&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Running&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;reconciliation&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;reason&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Running&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;True&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Running&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;An Ansible Operator also allows you to supply custom status values with the
&lt;code&gt;k8s_status&lt;/code&gt; Ansible module, which is included in
&lt;a href=&#34;https://galaxy.ansible.com/operator_sdk/util&#34;&gt;operator_sdk.util&lt;/a&gt; collection.
You can update the &lt;code&gt;status&lt;/code&gt; from within Ansible with any key/value pairs as
desired. If you do not want the operator to update the status with Ansible
output, and you want to track the CR status manually from your application,
you can update the &lt;code&gt;watches.yaml&lt;/code&gt; file with &lt;code&gt;manageStatus&lt;/code&gt;, as shown below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;api.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;manageStatus&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The simplest way to invoke the &lt;code&gt;k8s_status&lt;/code&gt; module is to use its fully
qualified collection name (fqcn), i.e. &lt;code&gt;operator_sdk.util.k8s_status&lt;/code&gt;.  The
following example updates the &lt;code&gt;status&lt;/code&gt; subresource with key &lt;code&gt;memcached&lt;/code&gt; and value &lt;code&gt;bar&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;operator_sdk.util.k8s_status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;api_version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com/v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ ansible_operator_meta.name }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ ansible_operator_meta.namespace }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;foo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;bar&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Collections can also be declared in the role&amp;rsquo;s &lt;code&gt;meta/main.yml&lt;/code&gt;, which is
included for newly scaffolded Ansible operators.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;collections&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- operator_sdk.util&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Declaring collections in the role meta allows you to invoke the
&lt;code&gt;k8s_status&lt;/code&gt; module directly.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;k8s_status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&amp;lt;snip&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&amp;gt;
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;    status:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;foo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;bar&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;ansible-operator-conditions&#34;&gt;Ansible Operator Conditions&lt;/h3&gt;
&lt;p&gt;An Ansible Operator has a set of conditions that are used during reconciliation.
There are only a few main conditions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Running - the Ansible Operator is currently running the Ansible for
reconciliation.&lt;/li&gt;
&lt;li&gt;Successful - if the run has finished and there were no errors, the Ansible
Operator will be marked as Successful. It will then wait for the next
reconciliation action, either the reconcile period, dependent watches triggers
or the resource is updated.&lt;/li&gt;
&lt;li&gt;Failed - if there is any error during the reconciliation run, the Ansible
Operator will be marked as Failed with the error message from the error that
caused this condition. The error message is the raw output from the Ansible
run for reconciliation. If the Failure is intermittent, often times the
situation can be resolved when the Operator reruns the reconciliation loop.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;extra-vars-sent-to-ansible&#34;&gt;Extra vars sent to Ansible&lt;/h2&gt;
&lt;p&gt;The extra vars that are sent to Ansible are managed by the operator. The &lt;code&gt;spec&lt;/code&gt;
section will pass along the key-value pairs as extra vars.  This is equivalent
to how above extra vars are passed in to &lt;code&gt;ansible-playbook&lt;/code&gt;. The operator also
passes along additional variables under the &lt;code&gt;ansible_operator_meta&lt;/code&gt; field for
the name of the CR and the namespace of the CR.&lt;/p&gt;
&lt;p&gt;For the CR example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;cache.example.com/v1alpha1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Memcached&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;memcached-sample&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;message&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Hello world 2&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;newParameter&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;newParam&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The structure passed to Ansible as extra vars is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;ansible_operator_meta&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;lt;cr-name&amp;gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;namespace&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;lt;cr-namespace&amp;gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Hello world 2&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;new_parameter&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;newParam&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;_app_example_com_database&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
     &lt;span style=&#34;color:#a40000&#34;&gt;&amp;lt;Full&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;CR&amp;gt;&lt;/span&gt;
   &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;_app_example_com_database_spec&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
     &lt;span style=&#34;color:#a40000&#34;&gt;&amp;lt;Full&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;CR&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;.spec&amp;gt;&lt;/span&gt;
   &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;message&lt;/code&gt; and &lt;code&gt;newParameter&lt;/code&gt; are set in the top level as extra variables, and
&lt;code&gt;ansible_operator_meta&lt;/code&gt; provides the relevant metadata for the Custom Resource as defined in the
operator. The &lt;code&gt;ansible_operator_meta&lt;/code&gt; fields can be accessed via dot notation in Ansible as so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;debug&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;msg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;name: {{ ansible_operator_meta.name }}, {{ ansible_operator_meta.namespace }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Managing Resources</title>
      <link>/docs/best-practices/managing-resources/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/managing-resources/</guid>
      <description>
        
        
        &lt;h2 id=&#34;managing-resources&#34;&gt;Managing Resources&lt;/h2&gt;
&lt;p&gt;Note that pretty much all controllers consume:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CPU&lt;/code&gt;: largely based on the number of reconciliations they perform, which are generally related to event activity for resources they&amp;rsquo;re watching.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Memory&lt;/code&gt;: largely based on the number of primary resources that exist (multiplied by some factor based on the number of operand resources they need to watch as a result) via informer caches.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And then there is a concern that one Pod or Container could monopolize all available resources and Cluster admins must
consider the effects that one Pod or Container may have on other components.&lt;/p&gt;
&lt;p&gt;In an effort to prevent a container from consuming all the resources on a cluster or affecting other workloads
from being scheduled, many production clusters will define &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;ResourceQuota&lt;/a&gt; configurations.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;ResourceQuota&lt;/a&gt; configuration also applies to tenant workloads that are managed by
your Operator. Cluster administrators will typically set a &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;ResourceQuota&lt;/a&gt; for each
tenant&amp;rsquo;s namespace as part of the onboarding. If a &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/limit-range/&#34;&gt;LimitRange&lt;/a&gt; with default values
has &lt;strong&gt;not&lt;/strong&gt; been created in each namespace and your Operator creates Containers inside the tenant
namespace without specifying at least resource requests for CPU and Memory of its Pods then,
the system or quota may reject Pod creation.
Check the following statements obtained from K8s docs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;If a LimitRange is activated in a namespace for computing resources like CPU and memory, users must specify requests or limits for those values. Otherwise, the system may reject Pod creation.&amp;quot;&lt;/em&gt; (&lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/limit-range/&#34;&gt;Reference&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;If quota is enabled in a namespace for compute resources like cpu and memory, users must specify requests or limits for those values; otherwise, the quota system may reject pod creation.&amp;quot;&lt;/em&gt; (&lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;Reference&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In an effort to support clusters with the above configuration, to ensure safe operations and avoid negatively
impacting other workloads: Operators should &lt;strong&gt;always&lt;/strong&gt; include reasonable memory and CPU resource requests for their own deployment as well as for operands they deploy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HINT&lt;/strong&gt; Cluster admins might also able to avoid the above scenario by setting default values when they are not specified for each Pod and/or Container in a namespace.&lt;/p&gt;
&lt;p&gt;Therefore, your Operator should &lt;strong&gt;always&lt;/strong&gt; apply at least resource requests for &lt;code&gt;CPU&lt;/code&gt; and
memory for &lt;code&gt;Pods/Deployments&lt;/code&gt; that it creates as part of the reconciliation logic. Ideally your
Operator also applies memory limits to those &lt;code&gt;Pods/Deployments&lt;/code&gt;. You may also consider CPU limits.&lt;/p&gt;
&lt;p&gt;Resource requests and limits for the Operator Deployment can be defined by modifying the&lt;code&gt;config/manager/manager.yaml&lt;/code&gt;
as shown below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# TODO(user): Configure the resources accordingly based on the project requirements.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;resources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;requests&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;cpu&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;10m&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;memory&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;64Mi&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;how-to-compute-default-values&#34;&gt;How to compute default values&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; A single configuration that fits all scenarios is not possible.
In this way, Operators authors &lt;strong&gt;MUST&lt;/strong&gt; to ensure that Cluster Admins and its users can change the
resource requests/limits of the Operator/manager, and of its Operands.&lt;/p&gt;
&lt;p&gt;However, you are able to benchmark your Operator by &lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#monitoring-compute-memory-resource-usage&#34;&gt;Monitoring the resource usage&lt;/a&gt;
to ensure good and reasonable values for the general cases. Kubebuilder and SDK provide some
&lt;a href=&#34;https://book.kubebuilder.io/reference/metrics.html&#34;&gt;metrics&lt;/a&gt; which can help you with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; Also, be aware that if the project was generated by Kubebuilder or SDK scaffold
then some values for the &lt;code&gt;Operator/manager&lt;/code&gt;(See &lt;code&gt;config/manager/manager.yaml&lt;/code&gt;)
are populated by default to get you started, however, you ought to optimize them based
on your own tests and the specific needs of your operator.&lt;/p&gt;
&lt;h3 id=&#34;how-to-change-the-operatormanager-resources-values-when-under-olm-management&#34;&gt;How to change the Operator/manager resources values when under OLM management&lt;/h3&gt;
&lt;p&gt;If your operator is managed by OLM, administrators or users can configure your operator&amp;rsquo;s resource requests and limits
via the &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/subscription-config.md#resources&#34;&gt;subscription&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;general-guidelines&#34;&gt;General guidelines&lt;/h3&gt;
&lt;p&gt;Following are some general recommendations to manage the resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;/strong&gt; declare resource requests for both, CPU and Memory, for the &lt;code&gt;Operator/manager&lt;/code&gt;  and any &lt;code&gt;Pod/Deployment&lt;/code&gt; managed by it&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OPTIONALLY&lt;/strong&gt; setting the resources limit for CPU and Memory for the Operator Pod and any &lt;code&gt;Pod/Deployment&lt;/code&gt; managed by it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SHOULD&lt;/strong&gt; provide the mechanisms for &lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#monitoring-compute-memory-resource-usage&#34;&gt;Monitoring compute &amp;amp; memory resource usage&lt;/a&gt; so that,
Cluster Admins can use these metrics to monitor and resize the Operator and its Operands.&lt;em&gt;&lt;strong&gt;CAVEAT:&lt;/strong&gt; If the Operator
is integrated with OLM and the bundle has a &lt;code&gt;PodMonitor&lt;/code&gt; or a &lt;code&gt;ServiceMonitor&lt;/code&gt; the complete &lt;code&gt;InstallPlan&lt;/code&gt;
will fail on a cluster, which does not have these CRD/the Prometheus operator installed. In this case,
you might want to ensure the dependency requirement with &lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/olm-architecture/dependency-resolution/&#34;&gt;OLM dependency&lt;/a&gt; or make clear
its requirement for the Operator consumers.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SHOULD&lt;/strong&gt; allow admins to customize the &lt;code&gt;requests/limits&lt;/code&gt; amounts defined for the &lt;code&gt;Pod/Deployment&lt;/code&gt;
created by the Operator and not hardcode these values.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SHOULD&lt;/strong&gt; document how your Operator consumer can customize/rightsize the resources requests and limits for the
Operator and Operands &lt;code&gt;Pod/Deployments&lt;/code&gt; or describe how the solution could be configured to automatically adjust these values based on the environment.
the Operator automatically adjust the values to the environment rather than asking its consumers to amend them.
You might also consider leveraging the &lt;a href=&#34;https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler&#34;&gt;Vertical Pod Autoscaler&lt;/a&gt; to have the resources requested by the Operator
automatically adjusted to the cluster where it is deployed. You might also
look at allowing &lt;a href=&#34;https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-resource-metrics&#34;&gt;horizontal pod autoscaling&lt;/a&gt; for the other &lt;code&gt;Pod/Deployments&lt;/code&gt; created by your Operator.
In this case, be aware that resource requests are also required for horizontal pod autoscaling to work.&lt;em&gt;&lt;strong&gt;CAVEAT:&lt;/strong&gt; If you are using OpenShift as your Kubernetes distribution you might want to check the
doc &lt;a href=&#34;https://docs.openshift.com/container-platform/4.9/nodes/pods/nodes-pods-vertical-autoscaler.html&#34;&gt;Automatically adjust pod resource levels with the vertical pod autoscaler&lt;/a&gt;. Also, if the VPA CRD
is not available in the cluster where the operator gets deployed the InstallPlan will fail.
Please, see how to work with &lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/olm-architecture/dependency-resolution/&#34;&gt;OLM dependency&lt;/a&gt; if your project integrating with it.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;why-should-you-set-these&#34;&gt;Why should you set these?&lt;/h3&gt;
&lt;h4 id=&#34;resource-requests&#34;&gt;Resource Requests&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;What happens when the resource requests are not set?&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;configurations made by the cluster administrators such as &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;ResourceQuota&lt;/a&gt; might not work without LimitRanges. The LimitRanger admission controller can provide default values for resource requests and limits when they have not been defined.&lt;/li&gt;
&lt;li&gt;the Operators consumers might face resource shortages on a node when resource usage increases, for example, during a daily peak in request rate.&lt;/li&gt;
&lt;li&gt;the Operator&amp;rsquo;s consumers might be unable to successfully deploy the Operator because it does not have the minimal resources available.&lt;/li&gt;
&lt;li&gt;the scheduler cannot make an informed placement choice when it picks the nodes the operator pods will be running on.&lt;/li&gt;
&lt;li&gt;when there is memory contention on the node the pod is likely to get either evicted or OOM killed.&lt;/li&gt;
&lt;li&gt;when there is CPU contention on the node the pod is likely to get starved of CPU cycles making the operator unresponsive.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;resource-limits&#34;&gt;Resource Limits&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;What happens when the resource limits are not set?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Wrong configurations or code implementations can consume all resources available, affecting other components on cluster.
Also, it might leave the containers more vulnerable such as to Dos Attacks. &lt;a href=&#34;https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-7-limit-resources-memory-cp%5B%E2%80%A6%5Dle-descriptors-processes-restarts&#34;&gt;More info&lt;/a&gt;. See that when there is memory
contention on a node, pods will start getting evicted and possibly killed according to their OOM score. The node will be flagged with a
MemoryPressure condition and eventually made unschedulable. However, when there is CPU contention on the node, neighbour pods may
get slowed down to the CPU cores they requested.&lt;/p&gt;
&lt;p&gt;However, a popular practice by cluster administrators is to leverage &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;ResourceQuota&lt;/a&gt; to limit
the total amount of resources that can be requested or allowed in a single namespace.
This may protect against over consumption of resources by operands of a faulty or wrongly configured operator.
On the other hand it also means that the operator may not be able to create additional pods,
limiting its functionality when the limit has been reached.&lt;/p&gt;
&lt;p&gt;Also, see might want to check in the K8s docs the following sections:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/#motivation-for-cpu-requests-and-limits&#34;&gt;Motivation for CPU requests and limits&lt;/a&gt; and &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/#if-you-do-not-specify-a-cpu-limit&#34;&gt;If you do not specify a CPU limit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/#motivation-for-memory-requests-and-limits&#34;&gt;Motivation for Memory requests and limits&lt;/a&gt; and &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/#if-you-do-not-specify-a-memory-limit&#34;&gt;If you do not specify a memory limit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;what-happens-when&#34;&gt;What happens when:&lt;/h3&gt;
&lt;h4 id=&#34;limits-reached&#34;&gt;Limits reached&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;What happens when the resource limits have been reached?&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;For Memory&lt;/code&gt;: the container might be terminated with the reason &lt;code&gt;OOM Killed&lt;/code&gt;. If it is restartable, the kubelet will
restart it, as with any other type of runtime failure.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;For CPU&lt;/code&gt;: the container might or might not be allowed to exceed its CPU limit for extended periods of time. However,
it will not be killed for excessive CPU usage. The &lt;code&gt;CPU&lt;/code&gt; is considered a &amp;ldquo;compressible&amp;rdquo; resource,
and if the &lt;code&gt;Pod&lt;/code&gt; starts hitting the CPU limits, Kubernetes uses kernel to starts throttling the container.
That means the CPU will be artificially restricted, giving a potentially worse performance only.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You might want to check the &lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#troubleshooting&#34;&gt;Troubleshooting&lt;/a&gt; section in the Kubernetes documents to better
understand how to debug these scenarios.&lt;/p&gt;
&lt;h4 id=&#34;limits-are-specified-but-not-requests&#34;&gt;Limits are specified but not requests&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;What happens when the resource limits are defined but not the requests?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you specify a CPU or Memory limit for a Container but do not specify a request,
Kubernetes automatically assigns a CPU or Memory request that matches the limit.
In this way, you will be requesting &lt;strong&gt;always&lt;/strong&gt; the limit and will be allocating
more resources than required. (&lt;strong&gt;NOT RECOMMENDED&lt;/strong&gt;)&lt;/p&gt;
&lt;h4 id=&#34;values-are-too-big&#34;&gt;Values are too big&lt;/h4&gt;
&lt;p&gt;Memory and CPU requests and limits are associated with Containers, but be aware that the Memory and CPU
requests and limits of a Pod are the sum of its specific computing types for all the containers in the Pod.&lt;/p&gt;
&lt;p&gt;If you define that your Pods should have Memory or CPU request too big then, you might not only be allocating and
blocking the usage of more than you ought unnecessarily. Also, your Operator consumers might be able to install
your Operator via OLM, for example, but will be unable to check the Pods/Deployment running successfully
when the amount defined exceeds the capacity available. In these scenarios, the Operator consumers
will check that Pod(s) failed to schedule with event errors like &lt;code&gt;Insufficient cpu&lt;/code&gt; and/or &lt;code&gt;Insufficient memory&lt;/code&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Pod Security Standards</title>
      <link>/docs/best-practices/pod-security-standards/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/pod-security-standards/</guid>
      <description>
        
        
        &lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/#what-is-podsecuritypolicy&#34;&gt;PodSecurityPolicy&lt;/a&gt; API is deprecated and will be removed from Kubernetes in version 1.25.
This API is replaced by a new built-in admission controller (&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/2579-psp-replacement&#34;&gt;KEP-2579: Pod Security Admission Control&lt;/a&gt;) which allows cluster admins to &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/&#34;&gt;enforce
Pod Security Standards Labels&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;what-does-that-mean&#34;&gt;What does that mean?&lt;/h3&gt;
&lt;p&gt;Namespace and Pod/Container can be defined with three different policies which are; &lt;strong&gt;Privileged, Baseline and Restricted.&lt;/strong&gt;
(&lt;a href=&#34;https://kubernetes.io/docs/concepts/security/pod-security-standards/&#34;&gt;More info&lt;/a&gt;). Therefore, Pod(s)/Container(s) that
are &lt;strong&gt;not&lt;/strong&gt; configured according to the enforced security standards defined globally or
on the namespace level will &lt;strong&gt;not&lt;/strong&gt; be admitted and it will &lt;strong&gt;not&lt;/strong&gt; be possible to run them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;As a best practice, you must ensure that workloads (Operators and Operands) are defined to run under
restricted permissions unless they need further privileges. For the cases where Pod/Container(s) requires
escalating permissions, the recommendation is to use the label as described below&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;how-should-i-configure-my-operators-and-operands-to-comply-with-the-criteria&#34;&gt;How should I configure my Operators and Operands to comply with the criteria?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;For common cases that do not require escalating privileges:&lt;/strong&gt; configure all containers to comply with the &lt;a href=&#34;https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted&#34;&gt;restricted&lt;/a&gt; policy as shown in the following the examples:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT NOTE&lt;/strong&gt; The &lt;code&gt;seccompProfile&lt;/code&gt; field to define that a container is &lt;a href=&#34;https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted&#34;&gt;restricted&lt;/a&gt; was introduced with K8s &lt;code&gt;1.19&lt;/code&gt; and might &lt;strong&gt;not&lt;/strong&gt; be supported on some vendors by default.
Please, do &lt;strong&gt;not&lt;/strong&gt; use this field if you are looking to build Operators that work on K8s versions &amp;lt; &lt;code&gt;1.19&lt;/code&gt; or on vendors that do &lt;strong&gt;not&lt;/strong&gt; support this field. Having this field when it is not supported can result in your Pods/Containers &lt;strong&gt;not&lt;/strong&gt; being allowed to run (i.e. On Openshift versions &amp;lt; &lt;code&gt;4.11&lt;/code&gt; with its default configuration the deployments will fail with errors like &lt;code&gt;Forbidden: seccomp&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In Kubernetes manifests:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# WARNING: Ensure that the image used defines an UserID in the Dockerfile&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# otherwise the Pod will not run and will fail with `container has runAsNonRoot and image has non-numeric user`.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# If you want your workloads admitted in namespaces enforced with the restricted mode in OpenShift/OKD vendors&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# then, you MUST ensure that the Dockerfile defines a User ID OR you MUST leave the `RunAsNonRoot` and&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# RunAsUser fields empty.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;runAsNonRoot&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Please ensure that you can use SeccompProfile and do not use&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# if your project must work on old Kubernetes&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# versions &amp;lt; 1.19 or on vendors versions which&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# do NOT support this field by default (i.e. Openshift &amp;lt; 4.11 )&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;seccompProfile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;RuntimeDefault&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;controller-manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;allowPrivilegeEscalation&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;capabilities&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;drop&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;- ALL&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;On Reconciliations, such as code implementation in Go:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;if you are setting the &lt;code&gt;RunAsNonRoot&lt;/code&gt; value to &lt;code&gt;true&lt;/code&gt; in the &lt;code&gt;SecurityContext&lt;/code&gt; you will need to verify that the Pod or Container(s) are running with a numeric user that is not 0 (root). If the Pod or Container(s) do not use a non-zero numeric user, you can use the &lt;code&gt;RunAsUser&lt;/code&gt; value to set the user to a non-zero numeric user. In this example, the memcached container does not use a non-zero numeric user and therefore the &lt;code&gt;RunAsUser&lt;/code&gt; value is set to use a uid of &lt;code&gt;1000&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Deployment&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;ObjectMeta&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;metav1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ObjectMeta&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#a40000&#34;&gt;…&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DeploymentSpec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#a40000&#34;&gt;…&lt;/span&gt;
     &lt;span style=&#34;color:#000&#34;&gt;Template&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodTemplateSpec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
       &lt;span style=&#34;color:#a40000&#34;&gt;…&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodSpec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
           &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Ensure restricted context for the Pod    
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;           &lt;span style=&#34;color:#000&#34;&gt;SecurityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodSecurityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
              &lt;span style=&#34;color:#000&#34;&gt;RunAsNonRoot&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;bool&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}[&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;],&lt;/span&gt;
			  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Please ensure that you can use SeccompProfile and do NOT use
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;			  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// this filed if your project must work on old Kubernetes
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;			  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// versions &amp;lt; 1.19 or on vendors versions which 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;			  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// do NOT support this field by default (i.e. Openshift &amp;lt; 4.11)
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;              &lt;span style=&#34;color:#000&#34;&gt;SeccompProfile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SeccompProfile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                 &lt;span style=&#34;color:#000&#34;&gt;Type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SeccompProfileTypeRuntimeDefault&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
              &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
           &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
           &lt;span style=&#34;color:#000&#34;&gt;Containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Container&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{{&lt;/span&gt;
              &lt;span style=&#34;color:#000&#34;&gt;Image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;memcached:1.4.36-alpine&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
              &lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;memcached&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
              &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Ensure restricted context for the container  
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;              &lt;span style=&#34;color:#000&#34;&gt;SecurityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SecurityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
				 &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// WARNING: Ensure that the image used defines an UserID in the Dockerfile
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;				 &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// otherwise the Pod will not run and will fail with `container has runAsNonRoot and image has non-numeric user`.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;				 &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// If you want your workloads admitted in namespaces enforced with the restricted mode in OpenShift/OKD vendors 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;				 &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// then, you MUST ensure that the Dockerfile defines a User ID OR you MUST leave the `RunAsNonRoot` and
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;				 &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// RunAsUser fields empty. 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;                 &lt;span style=&#34;color:#000&#34;&gt;RunAsNonRoot&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;bool&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}[&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;],&lt;/span&gt;
                 &lt;span style=&#34;color:#000&#34;&gt;AllowPrivilegeEscalation&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;bool&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}[&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;],&lt;/span&gt;
                 &lt;span style=&#34;color:#000&#34;&gt;Capabilities&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Capabilities&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                    &lt;span style=&#34;color:#000&#34;&gt;Drop&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Capability&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                       &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ALL&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
                    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
                 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
              &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
           &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}},&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
     &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;For Ansible and Helm language based Operators:&lt;/strong&gt; Ansible playbooks or Helm charts MUST create manifests that comply
with the requirements in the same way. You can find some examples by looking at the samples under the
&lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/testdata&#34;&gt;testdata&lt;/a&gt; directory.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;For workloads that need elevated permissions:&lt;/strong&gt; it is recommended that you ensure the namespace containing your
solution is labeled accordingly. You can either update your operator to manage the namespace labels or include
the namespace labeling as part of the manual install instructions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is recommended that you provide a description to help cluster admins understand why elevated permissions are required.
You can add this information and the prerequisites to the description of your
Operator Bundle (CSV).&lt;/p&gt;
&lt;p&gt;Following you will find a detailed description of how to configure and test your solutions.
The most straightforward way to ensure if your workloads will work in a restricted namespace is verifying if your solution can run in namespaces enforced as restricted.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: It is recommended that you test the desired behavior as part of an e2e test suite. Examples of an e2e test for this will be shown in a later section.&lt;/p&gt;
&lt;h3 id=&#34;how-the-operator-bundle-csv-must-be-configured-to-apply-the-standards-to-the-podcontainers-which-are-installed-by-olm-operator-itself&#34;&gt;How the Operator bundle (CSV) must be configured to apply the standards to the Pod/Containers which are installed by OLM (Operator itself)?&lt;/h3&gt;
&lt;p&gt;For Operators integrated with OLM, there is an Operator bundle with a CSV where the &lt;code&gt;spec.install.spec.deployments&lt;/code&gt; has a Deployment
which defines the Pod/Container(s) that will be installed by OLM to get your Operator running on the cluster.
In order for the security standards to be followed you will need to ensure the configurations are set correctly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note: Ensure the configuration is carried to the Pod/Containers on the bundle CSV after running make bundle&lt;/strong&gt;. See that
the Operator bundle generated with the target is built from the manifests under the &lt;code&gt;config&lt;/code&gt; directory. To know more about
the layout of your operator built with Operator-SDK see &lt;a href=&#34;/docs/overview/project-layout&#34;&gt;Project Layout&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To check an example of a CSV which complies with the &lt;a href=&#34;https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted&#34;&gt;restricted&lt;/a&gt; policy, see the Golang sample
under the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml&#34;&gt;testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;how-can-i-verify-my-manifest&#34;&gt;How can I verify my manifest?&lt;/h3&gt;
&lt;h4 id=&#34;using-kind&#34;&gt;Using Kind&lt;/h4&gt;
&lt;p&gt;To verify the policy of your Pod/Container(s) you might to use a &lt;a href=&#34;https://kind.sigs.k8s.io/docs/user/quick-start/&#34;&gt;Kind&lt;/a&gt;
cluster as described in the &lt;a href=&#34;https://kubernetes.io/docs/tutorials/security/cluster-level-pss/&#34;&gt;K8s documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First lets create a namespace where we will test the files:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;kubectl create ns mytest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Now, let&amp;rsquo;s label the namespace so that we can check our manifest&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt; kubectl label --overwrite ns mytest &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;   pod-security.kubernetes.io/enforce&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;restricted &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;   pod-security.kubernetes.io/enforce-version&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;v1.24 &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;   pod-security.kubernetes.io/audit&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;restricted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Now, apply the following Pod which is &lt;strong&gt;not&lt;/strong&gt; restricted on the namespace:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;example&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;mytest&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;test&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;     &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# see that we are allowing privilege escalation  &lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;     &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;allowPrivilegeEscalation&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; 
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;busybox:1.28&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ports&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;     &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containerPort&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;8080&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;Then, when we try to apply the Pod manifest above we should see an error:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl apply -f mypodtest.yaml 
Error from server &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;Forbidden&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;: error when creating &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;mypodtest.yaml&amp;#34;&lt;/span&gt;: pods &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example&amp;#34;&lt;/span&gt; is forbidden: violates PodSecurity &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;restricted:v1.24&amp;#34;&lt;/span&gt;: allowPrivilegeEscalation !&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;false&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;container &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; must &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; securityContext.allowPrivilegeEscalation&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;, unrestricted capabilities &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;container &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; must &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; securityContext.capabilities.drop&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ALL&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;])&lt;/span&gt;, runAsNonRoot !&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;true&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;pod or container &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; must &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; securityContext.runAsNonRoot&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;, seccompProfile &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;pod or container &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; must &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; securityContext.seccompProfile.type to &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;RuntimeDefault&amp;#34;&lt;/span&gt; or &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Localhost&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;how-do-i-check-what-policy-privileged-baseline-and-restricted-is-configured-for-my-operator-and-operands&#34;&gt;How do I check what policy (Privileged, Baseline and Restricted) is configured for my Operator and Operand(s)?&lt;/h4&gt;
&lt;p&gt;An easy way might be using the tool: &lt;a href=&#34;https://github.com/stlaz/psachecker&#34;&gt;psachecker&lt;/a&gt;. This tool is only
able to be used to check locally the &lt;code&gt;Deployments/Pods&lt;/code&gt; manifests and not the CSV.&lt;/p&gt;
&lt;p&gt;Alternatively, you could test the policy enforcement by labeling the namespaces and running your operator or applying the manifests. &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/&#34;&gt;More info&lt;/a&gt;.&lt;/p&gt;
&lt;h5 id=&#34;how-do-i-install-psachecker&#34;&gt;How do I install psachecker?&lt;/h5&gt;
&lt;p&gt;The following steps will install &lt;a href=&#34;https://github.com/stlaz/psachecker&#34;&gt;psachecker&lt;/a&gt; in a Golang environment.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git clone git@github.com:stlaz/psachecker.git &lt;span style=&#34;color:#000&#34;&gt;$GOPATH&lt;/span&gt;/src/github.com/stlaz/psachecker
&lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;$GOPATH&lt;/span&gt;/src/github.com/stlaz/psachecker
make build
cp kubectl-psachecker &lt;span style=&#34;color:#000&#34;&gt;$GOPATH&lt;/span&gt;/bin/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;how-do-i-use-psachecker-to-verify-the-policy-of-a-manifests&#34;&gt;How do I use psachecker to verify the policy of a manifests?&lt;/h4&gt;
&lt;p&gt;The following steps will demonstrate how we can use &lt;a href=&#34;https://github.com/stlaz/psachecker&#34;&gt;psachecker&lt;/a&gt; to verify that our Operator and deployments are properly configured in the CSV.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a new &lt;code&gt;test.yaml&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Add Deployment schema to the file:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;apps/v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Deployment&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;test-manifest&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;test&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Now, add the CSV deployment to this test (&lt;code&gt;spec.install.spec.deployments&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Then, you can run the tool and check if its result will be &lt;code&gt;restricted&lt;/code&gt; as expected (i.e.):&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl-psachecker inspect-workloads -f test.yaml
system: restricted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;can-i-use-the-metrics-to-check-if-my-podcontainers-are-violating-the-podsecurity-policies&#34;&gt;Can I use the metrics to check if my Pod/Containers are violating the PodSecurity policies?&lt;/h3&gt;
&lt;p&gt;Yes, you can. You need to label the namespaces with &lt;code&gt;pod-security.kubernetes.io/audit: restricted&lt;/code&gt;
(i.e. &lt;code&gt;kubectl label --overwrite ns --all pod-security.kubernetes.io/enforce-version=v1.24 pod-security.kubernetes.io/audit=restricted&lt;/code&gt;).
It is important to note that the results may include metrics that do not come from your Operator and Operand(s).
If you are looking to use the metrics to do the checks, ensure that you check the
results before and after performing the tests, for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;kubectl get --raw /metrics &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; prom2json &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; jq &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;[.[] | select(.name==&amp;#34;pod_security_evaluations_total&amp;#34;) ]&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod_security_evaluations_total&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;help&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;[ALPHA] Number of policy evaluations that occurred, not counting ignored or exempt requests.&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;COUNTER&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;metrics&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;allow&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;enforce&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;privileged&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;29&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;allow&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;enforce&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;privileged&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;update&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;deny&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;audit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;controller&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;6&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;deny&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;audit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;7&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;deny&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;warn&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;controller&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;6&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;deny&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;warn&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;7&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Also, you might be able to create Prometheus alerts such as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sum &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;increase&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;pod_security_evaluations_total&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;decision&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;deny&amp;#34;&lt;/span&gt;,mode&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;audit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;}[&lt;/span&gt;1h&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;]))&lt;/span&gt; by &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;policy_level&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;recommended-how-can-i-automate-this-check-using-e2e-testing-to-ensure-that-my-solutions-can-run-under-the-policies&#34;&gt;(Recommended) How can I automate this check using e2e testing to ensure that my solutions can run under the policies?&lt;/h3&gt;
&lt;p&gt;In the tests, you can create and label a namespace with the desired policy (i.e. restricted). This would allow you to verify
if any warnings/errors occur and if the Pod(s)/Container(s) are in the &lt;code&gt;Running&lt;/code&gt; state. It can be something like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; See the &lt;code&gt;test&lt;/code&gt; directory for the Memcached sample under the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/testdata/go/v4/memcached-operator&#34;&gt;testdata/go/v3/memcached-operator&lt;/a&gt; to see a full example.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// namespace store the ns where the Operator and Operand(s) will be executed
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;namespace&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;my-operator-system&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Describe&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;my operator test&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;BeforeEach&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
        
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Where we will create the namespace for to install the Operator and Operands
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#000&#34;&gt;By&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;creating namespace&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;exec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;kubectl&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ns&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;utils&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Run&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// We will label as follows all namespaces so that we can check if warnings will be raised when 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// a manifest be applied. (Not that some namespaces might not acced the label, i.e. if it
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// has a container running with a less restrictive policy )
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#000&#34;&gt;By&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;labeling all namespaces to warn against what can violate the restricted policy&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;exec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;kubectl&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;--overwrite&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ns&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;--all&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/audit=restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/enforce-version=v1.24&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/warn=restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;utils&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Run&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;ExpectWithOffset&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NotTo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;HaveOccurred&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;())&lt;/span&gt;
        
		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// We will enforce the restricted policy so that if our Operator
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// or Operand be unable to run as restricted we will be able to check
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// it by validating their status
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#000&#34;&gt;By&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;enforcing restricted to the ns where the Operator/Operand(s) will be checked&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;exec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;kubectl&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;--overwrite&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ns&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/audit=restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/enforce-version=v1.24&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/enforce=restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;utils&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Run&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;Expect&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;To&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Not&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;HaveOccurred&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()))&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
    
    &lt;span style=&#34;color:#000&#34;&gt;AfterEach&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;It&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;should successfully run the Operator and Operand(s)&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Then, here we build the operator and deploy the
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// manager as the operand in the namespaces were 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// the policy restricted was enforced.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Therefore, we can check the Operator and Operand
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// status to ensure that all is Running.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Note that we can also verify if warns like with
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// the message Warning: would violate PodSecurity were 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// returned when the manifest were applied on the cluster
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;after-following-the-recommendations-to-be-restricted-my-workload-is-not-running-createcontainerconfigerror-what-should-i-do&#34;&gt;After following the recommendations to be restricted my workload is not running (CreateContainerConfigError). What should I do?&lt;/h3&gt;
&lt;p&gt;If you are encountering errors similar to &lt;code&gt;Error: container has runAsNonRoot and image has non-numeric user&lt;/code&gt;
or &lt;code&gt;container has runAsNonRoot and image will run as root&lt;/code&gt; that means that the image used does not have a non-zero numeric user defined, i.e.:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;USER 65532:65532 
OR
USER &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Due to the &lt;code&gt;RunAsNonRoot&lt;/code&gt; field being set to &lt;code&gt;true&lt;/code&gt;, we need to force the user in the
container to a non-zero numeric user.
It is recommended that the images used by your operator have a non-zero numeric user set in the image itself (similar to the example above). For further information check the note &lt;a href=&#34;https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user&#34;&gt;Consider an explicit UID/GID&lt;/a&gt; in the Dockerfile best practices guide.
If your Operator will be distributed and used in vanilla Kubernetes clusters you can also fix the issue by defining the user via the security context configuration). (i.e. &lt;code&gt;RunAsUser: &amp;amp;[]int64{1000}[0],&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; If your Operator should work with specific vendors please ensure that you check if they have specific rules for Pod Security Admission.  For example, we know that if you use &lt;code&gt;RunAsUser&lt;/code&gt; on OpenShift it will disqualify the Pod from their restricted-v2 SCC.
Therefore, if you want your workloads running in namespaces labeled to enforce restricted you must leave &lt;code&gt;RunAsUser&lt;/code&gt; and &lt;code&gt;RunAsNonRoot&lt;/code&gt; fields empty or if you want set &lt;code&gt;RunAsNonRoot&lt;/code&gt; then, you MUST ensure that the image itself properly defines the UserID.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Reporting Issues</title>
      <link>/docs/contribution-guidelines/reporting-issues/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/contribution-guidelines/reporting-issues/</guid>
      <description>
        
        
        &lt;p&gt;If any part of the operator-sdk project has bugs or documentation mistakes, please let us know by &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/issues/new&#34;&gt;opening an issue&lt;/a&gt;. We treat bugs and mistakes very seriously and believe no issue is too small. Before creating a bug report, please check that an issue reporting the same problem does not already exist.&lt;/p&gt;
&lt;p&gt;To make the bug report accurate and easy to understand, please try to create bug reports that are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Specific. Include as much details as possible: which version, what environment, what configuration, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reproducible. Include the steps to reproduce the problem. We understand some issues might be hard to reproduce, please include the steps that might lead to the problem.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Isolated. Please try to isolate and reproduce the bug with minimum dependencies. It would significantly slow down the speed to fix a bug if too many dependencies are involved in a bug report. Debugging external systems that rely on operator-sdk is out of scope, but we are happy to provide guidance in the right direction or help with using operator-sdk itself.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Unique. Do not duplicate existing bug report.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scoped. One bug per report. Do not follow up with another bug inside one report.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It may be worthwhile to read &lt;a href=&#34;https://fantasai.inkedblade.net/style/talks/filing-good-bugs/&#34;&gt;Elika Etemad’s article on filing good bug reports&lt;/a&gt; before creating a bug report.&lt;/p&gt;
&lt;p&gt;We might ask for further information to locate a bug. A duplicated bug report will be closed.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Operator Observability Best Practices</title>
      <link>/docs/best-practices/observability-best-practices/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/observability-best-practices/</guid>
      <description>
        
        
        &lt;h2 id=&#34;operator-observability-best-practices&#34;&gt;Operator Observability Best Practices&lt;/h2&gt;
&lt;p&gt;In this document, we provide best practices and examples for creating metrics, &lt;a href=&#34;https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules&#34;&gt;recording rules&lt;/a&gt; and alerts. It is based on the general guidelines in &lt;a href=&#34;https://sdk.operatorframework.io/docs/overview/operator-capabilities/&#34;&gt;Operator Capability Levels&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For technical documentation of how to add metrics to your operator, please read the &lt;a href=&#34;https://book.kubebuilder.io/reference/metrics.html&#34;&gt;Metrics&lt;/a&gt; section of the Kubebuilder documentation.&lt;/p&gt;
&lt;h3 id=&#34;operator-observability-recommended-components&#34;&gt;Operator Observability Recommended Components&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Health and Performance metrics&lt;/strong&gt; - for all of the operator components&lt;br&gt;
1.1. Metrics should be implemented based on the guidelines below.&lt;br&gt;
1.2. &lt;strong&gt;Metrics Documentation&lt;/strong&gt; - All metrics should have documentation.&lt;br&gt;
1.3. &lt;strong&gt;Metrics Tests&lt;/strong&gt; - Metrics should include tests that verify that they exist and that their value is correct.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alerts&lt;/strong&gt; for when things are not working as expected for each of the operator&amp;rsquo;s components&lt;br&gt;
2.1  Alerts should be implemented based on the guidelines below.&lt;br&gt;
2.2. &lt;strong&gt;Alerts Runbooks&lt;/strong&gt; - Each alert can include a &lt;code&gt;runbook_url&lt;/code&gt; annotation and an alert runbook that describes it. See additional details below.&lt;br&gt;
2.3. &lt;strong&gt;Alerts Tests&lt;/strong&gt; - Alerts should include E2E Testing and unit tests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Events&lt;/strong&gt; - Custom Resources should emit custom events for the operations taking place.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Additional components would be &lt;code&gt;Dashboards&lt;/code&gt;, &lt;code&gt;Logs&lt;/code&gt; and &lt;code&gt;Traces&lt;/code&gt;, which are not addressed in this document at this point.&lt;/p&gt;
&lt;h3 id=&#34;operators-observability-general-guidelines&#34;&gt;Operators Observability General Guidelines&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; It is highly recommended to separate your monitoring code from your core operator code.&lt;br&gt;
We recommend to create a dedicated &lt;code&gt;/monitoring&lt;/code&gt; subfolder that will include all the code of the &lt;a href=&#34;#operator-observability-recommended-components&#34;&gt;Operator Observability Recommended Components&lt;/a&gt;, that are outlined above. For example, in the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/testdata/go/v4/monitoring/memcached-operator/monitoring&#34;&gt;memcached-operator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In your core operator code only call the functions that will update the metrics value from your desired location. For example, in the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/367bd3597c30607099aa73637f5286f7120b847a/testdata/go/v3/monitoring/memcached-operator/controllers/memcached_controller.go#L242&#34;&gt;memcached-operator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All operators start small. This separation will help you, as a developer, with easier maintenance of both your operator core code and the monitoring code and for other stakeholders to understand your monitoring code better.&lt;/p&gt;
&lt;h3 id=&#34;metrics-guidelines&#34;&gt;Metrics Guidelines&lt;/h3&gt;
&lt;h4 id=&#34;metrics-naming&#34;&gt;Metrics Naming&lt;/h4&gt;
&lt;p&gt;Kubernetes components emit metrics in &lt;a href=&#34;https://prometheus.io/docs/instrumenting/exposition_formats/&#34;&gt;Prometheus format&lt;/a&gt;. This format is structured plain text, designed so that people and machines can both read it.&lt;/p&gt;
&lt;p&gt;Your operator users should get the same experience when searching for a metric across Kubernetes operators, resources and custom resources.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check if a similar Kubernetes metric, for node, container or pod, exists and try to align to it.&lt;/li&gt;
&lt;li&gt;The metrics search list, in the Prometheus, Grafana UI and even in the /metrics end point, is sorted in alphabetical order.
When searching for a metric, it should be easy to identify metrics that are related to a specific operator.
That is why we recommend that your operator metrics name will follow this format:
&lt;code&gt;operator name&lt;/code&gt; prefix + the &lt;code&gt;sub-operator name&lt;/code&gt; or &lt;code&gt;entity&lt;/code&gt; + &lt;code&gt;metric name&lt;/code&gt; based on the &lt;a href=&#34;https://prometheus.io/docs/practices/naming/&#34;&gt;Prometheus naming conventions&lt;/a&gt;. For example, in the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/0d2fa86f0d3cc92c4672cb9e1d246efaefcf7ced/testdata/go/v4-alpha/monitoring/memcached-operator/monitoring/metrics.go#L14&#34;&gt;memcached-operator&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In &lt;a href=&#34;https://github.com/prometheus/node_exporter&#34;&gt;Prometheus Node Exporter&lt;/a&gt; metrics are separated like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;node_network_**receive**_packets_total&lt;/li&gt;
&lt;li&gt;node_network_**transmit**_packets_total&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this example, based on &lt;code&gt;receive&lt;/code&gt; and &lt;code&gt;transmit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Please follow the same principle and don&amp;rsquo;t put similar metrics details as labels, so the user experience would be fluent.&lt;br&gt;
Example for this in an operator:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;kubevirt_vmi_network_**receive**_errors_total&lt;/li&gt;
&lt;li&gt;kubevirt_vmi_network_**transmit**_bytes_total&lt;/li&gt;
&lt;li&gt;kubevirt_migrate_vmi_**data_processed**_bytes&lt;/li&gt;
&lt;li&gt;kubevirt_migrate_vmi_**data_remaining**_bytes&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Your metric suffix should indicate the metric unit. For better compatibility, &lt;a href=&#34;https://prometheus.io/docs/practices/naming/#base-units&#34;&gt;Prometheus base units&lt;/a&gt; should be used.&lt;/li&gt;
&lt;li&gt;Prometheus supports four &lt;a href=&#34;https://prometheus.io/docs/concepts/metric_types/#metric-types&#34;&gt;metric types&lt;/a&gt;. &lt;code&gt;Gauge&lt;/code&gt;,&lt;code&gt;Counter&lt;/code&gt;,&lt;code&gt;Histogram&lt;/code&gt; and &lt;code&gt;Summary&lt;/code&gt;. You can read more about the different types here, &lt;a href=&#34;https://prometheus.io/docs/tutorials/understanding_metric_types/#types-of-metrics&#34;&gt;Understanding metrics types&lt;/a&gt;.&lt;br&gt;
The most common types are:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Counter&lt;/code&gt; - Value can only increase or reset.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gauge&lt;/code&gt; Value can be increased and decreased as needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;&lt;code&gt;_total&lt;/code&gt; suffix should be used for accumulating count. If your metrics has labels with high cardinality, like &lt;code&gt;pod&lt;/code&gt;/&lt;code&gt;container&lt;/code&gt; it usually means that you can aggregate it more, thus it will not require &lt;code&gt;_total&lt;/code&gt; suffix.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;prometheus-labels&#34;&gt;Prometheus Labels&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://prometheus.io/docs/practices/naming/#labels&#34;&gt;Prometheus labels&lt;/a&gt; are used to differentiate the characteristics of the thing that is being measured.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Important&lt;/strong&gt; - Be cautious when adding labels to metrics. Labels can dramatically increase the amount of data stored. Do not use labels to store dimensions with high cardinality (many different label values), such as user IDs, email addresses, or other unbounded sets of values. Note: There are still cases when we will still need to have a high cardinality label like the &lt;code&gt;pod name&lt;/code&gt;, but try to keep this to the minimum.&lt;/li&gt;
&lt;li&gt;When creating a new metric, recording rule or alert, that reports a resource like a &lt;code&gt;pod&lt;/code&gt; or a &lt;code&gt;container&lt;/code&gt;, make sure that the &lt;code&gt;namespace&lt;/code&gt; is included, in order to be able to uniquely identify it.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;metrics-help-message&#34;&gt;Metrics &lt;code&gt;Help&lt;/code&gt; message&lt;/h4&gt;
&lt;p&gt;Your operator metrics &lt;code&gt;help&lt;/code&gt; message should include the following details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What does this metric measure?&lt;/li&gt;
&lt;li&gt;What does the output mean?&lt;/li&gt;
&lt;li&gt;What important labels does the metric use? (Optional. If applicable).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;Help&lt;/code&gt; message can be used to create auto-generated documentation, like it&amp;rsquo;s done in &lt;a href=&#34;https://github.com/kubevirt/kubevirt/blob/main/docs/observability/metrics.md&#34;&gt;KubeVirt&lt;/a&gt; and generated by the &lt;a href=&#34;https://github.com/kubevirt/kubevirt/blob/main/tools/doc-generator/doc-generator.go&#34;&gt;KubeVirt metrics doc generator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We recommend to auto-generated metrics documentation and save it in your operator repository, to a location like &lt;code&gt;/docs/monitoring/&lt;/code&gt;, so that the users can find the information about your operator metrics easily.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;#alerts-metrics-and-recording-rules-tests&#34;&gt;Alerts, Metrics and Recording Rules Tests&lt;/a&gt; section for metrics testing recommendations.&lt;/p&gt;
&lt;h4 id=&#34;prometheus-recording-rules-naming&#34;&gt;Prometheus Recording Rules Naming&lt;/h4&gt;
&lt;p&gt;As per &lt;a href=&#34;https://prometheus.io/docs/prometheus&#34;&gt;Prometheus&lt;/a&gt; documentation, &lt;a href=&#34;https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules&#34;&gt;Recording rules&lt;/a&gt; allow you to pre-compute frequently needed or computationally expensive expressions and save their result as a new set of time series.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Prometheus recording rules appear in Prometheus UI as metrics.
Recording rule names should follow the &lt;code&gt;level:metric:operations&lt;/code&gt; format as specified in the &lt;a href=&#34;https://prometheus.io/docs/practices/rules/&#34;&gt;Prometheus recording rules best practices&lt;/a&gt;. This naming convention makes it clear that the metric is a recording rule and helps consumers understand they need to examine the underlying query to fully understand what the metric provides.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;level:&lt;/strong&gt; represents the aggregation level and labels of the rule output&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;metric:&lt;/strong&gt; is the metric name&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;operations:&lt;/strong&gt; is a list of operations that were applied to the metric, newest operation first&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example: &lt;code&gt;job:up:avg_over_time&lt;/code&gt; or &lt;code&gt;instance:node_cpu_utilisation:rate5m&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In addition to this format, your operator recording rules should also follow the same naming guidelines as metrics for consistency within your operator&amp;rsquo;s observability stack.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;#alerts-metrics-and-recording-rules-tests&#34;&gt;Alerts, Metrics and Recording Rules Tests&lt;/a&gt; section for recording rules testing recommendations.&lt;/p&gt;
&lt;h3 id=&#34;prometheus-alerts-guidelines&#34;&gt;Prometheus Alerts Guidelines&lt;/h3&gt;
&lt;p&gt;Clear and actionable alerts are a key component of a smooth operational experience and will result in a better experience for the end users.&lt;/p&gt;
&lt;p&gt;The following guidances aim to align alert naming, severities, labels, etc., in order to avoid alerts fatigue for administrators.&lt;/p&gt;
&lt;h4 id=&#34;recommended-reading&#34;&gt;Recommended Reading&lt;/h4&gt;
&lt;p&gt;A list of references on good alerting practices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://sre.google/sre-book/monitoring-distributed-systems/&#34;&gt;Google SRE Book - Monitoring Distributed Systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://prometheus.io/docs/practices/alerting/&#34;&gt;Prometheus Alerting Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.usenix.org/sites/default/files/conference/protected-files/srecon16europe_slides_rabenstein.pdf&#34;&gt;Alerting for Distributed Systems&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;alert-ownership&#34;&gt;Alert Ownership&lt;/h4&gt;
&lt;p&gt;Individual operator authors are responsible for writing and maintaining alerting rules for
their components, i.e. their operators and operands.&lt;/p&gt;
&lt;p&gt;Operator authors should also take into consideration how their components interact with
existing monitoring and alerting.&lt;/p&gt;
&lt;p&gt;As an example, if your operator deploys a service which creates one or more &lt;code&gt;PersistentVolume&lt;/code&gt; resources,
and these volumes are expected to be mostly full as part of normal operation, it&amp;rsquo;s likely
that this will cause unnecessary &lt;code&gt;KubePersistentVolumeFillingUp&lt;/code&gt; alerts to fire.&lt;/p&gt;
&lt;p&gt;You should work to find a solution to avoid triggering these alerts if they are not actionable.&lt;/p&gt;
&lt;h4 id=&#34;alerts-style-guide&#34;&gt;Alerts Style Guide&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Alert names MUST be CamelCase, e.g.: &lt;code&gt;PrometheusRuleFailures&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Alert names SHOULD be prefixed with a component, e.g.: &lt;code&gt;AlertmanagerFailedReload&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;There may be exceptions for some broadly scoped alerts, e.g.: &lt;code&gt;TargetDown&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Alerts MUST include a &lt;code&gt;severity&lt;/code&gt; label indicating the alert&amp;rsquo;s urgency.
&lt;ul&gt;
&lt;li&gt;Valid severities are: &lt;code&gt;critical&lt;/code&gt;, &lt;code&gt;warning&lt;/code&gt;, or &lt;code&gt;info&lt;/code&gt; — see below for
guidelines on writing alerts of each severity.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Alerts MUST include &lt;code&gt;summary&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; annotations.
&lt;ul&gt;
&lt;li&gt;Think of &lt;code&gt;summary&lt;/code&gt; as the first line of a commit message, or an email
subject line.  It should be brief but informative.  The &lt;code&gt;description&lt;/code&gt; is the
longer, more detailed explanation of the alert.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Alerts SHOULD include a &lt;code&gt;namespace&lt;/code&gt; label indicating the source of the alert.
&lt;ul&gt;
&lt;li&gt;Many alerts will include this by virtue of the fact that their PromQL
expressions result in a namespace label.  Others may require a static
namespace label — see for example, the &lt;a href=&#34;https://github.com/openshift/cluster-monitoring-operator/blob/79cdf68/assets/control-plane/prometheus-rule.yaml#L235-L247&#34;&gt;KubeCPUOvercommit&lt;/a&gt; alert.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Optional Alerts Labels and Annotations&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;priority&lt;/code&gt; label indicating the alert&amp;rsquo;s level of importance and the order in which it should be fixed.
&lt;ul&gt;
&lt;li&gt;Valid priorities are: &lt;code&gt;high&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, or &lt;code&gt;low&lt;/code&gt;.
Higher the priority the sooner the alert should be resolved.&lt;/li&gt;
&lt;li&gt;If the alert doesn&amp;rsquo;t include a &lt;code&gt;priority&lt;/code&gt; label, we can assume it is a &lt;code&gt;medium&lt;/code&gt; priority alert.
This label will usually be used for alerts with &lt;code&gt;warning&lt;/code&gt; severity, to indicate the order in which the alert should be addressed by, even though it doesn&amp;rsquo;t require immediate action.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;runbook_url&lt;/code&gt; annotation is a link to an alert runbook which is intended to guide a cluster owner and/or operator through the steps of fixing problems on clusters, which are surfaced by alerts.
&lt;ul&gt;
&lt;li&gt;An example for &lt;a href=&#34;https://github.com/openshift/runbooks/blob/master/example.md&#34;&gt;Runbook style documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Your operator alert runbooks can be saved at your operator repository, to &lt;code&gt;/docs/monitoring/runbooks/&lt;/code&gt; for example,
at &lt;a href=&#34;https://github.com/openshift/runbooks&#34;&gt;OpenShift Runbooks&lt;/a&gt; if your operator is shipped with OpenShift
or another location that fits your operator.&lt;/li&gt;
&lt;li&gt;If you are using Github, you can use &lt;a href=&#34;https://pages.github.com/&#34;&gt;Github Pages&lt;/a&gt; for a better view of the runbooks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubernetes_operator_part_of&lt;/code&gt; label indicating the operator name. Label name is based on the  &lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/#labels&#34;&gt;Kubernetes Recommended Labels&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;alerts-severity&#34;&gt;Alerts Severity&lt;/h4&gt;
&lt;h5 id=&#34;critical-alerts&#34;&gt;Critical Alerts&lt;/h5&gt;
&lt;p&gt;For alerting current and impending disaster situations. These alerts
page an SRE. The situation should warrant waking someone in the middle of the
night.&lt;/p&gt;
&lt;p&gt;Timeline:  ~5 minutes.&lt;/p&gt;
&lt;p&gt;Reserve critical level alerts only for reporting conditions that may lead to loss of data or inability to deliver service for the cluster as a whole.&lt;br&gt;
Failures of most individual components should not trigger critical level alerts, unless they would result in either of those conditions.&lt;br&gt;
Configure critical level alerts so they fire before the situation becomes irrecoverable.&lt;br&gt;
Expect users to be notified of a critical alert within a short period of time after it fires so
they can respond with corrective action quickly.&lt;/p&gt;
&lt;p&gt;Example critical alert: &lt;a href=&#34;https://github.com/openshift/cluster-monitoring-operator/blob/79cdf68/assets/control-plane/prometheus-rule.yaml#L412-L421&#34;&gt;KubeAPIDown&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;alert&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;KubeAPIDown&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;summary&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Target&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;disappeared&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;from&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Prometheus&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;target&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;discovery.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;KubeAPI&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;has&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;disappeared&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;from&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Prometheus&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;target&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;discovery.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;runbook_url&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;https&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;//github.com/openshift/runbooks/blob/master/alerts/cluster-monitoring-operator/KubeAPIDown.md&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;expr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;|
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;    absent(up{job=&amp;#34;apiserver&amp;#34;} == 1)&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;15m&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;labels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;severity&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;critical&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This alert fires if no Kubernetes API server instance has reported metrics successfully in the last 15 minutes.&lt;br&gt;
This is a clear example of a critical control-plane issue that represents a threat to the operability of the cluster as a whole, and likely warrants paging someone.&lt;br&gt;
The alert has clear summary and description annotations, and it links to a runbook with information on investigating and resolving the issue.&lt;/p&gt;
&lt;p&gt;The group of critical alerts should be small, very well defined, highly documented, polished and with a high bar set for entry.&lt;/p&gt;
&lt;h5 id=&#34;warning-alerts&#34;&gt;Warning Alerts&lt;/h5&gt;
&lt;p&gt;The vast majority of alerts should use this severity.&lt;br&gt;
Issues at the warning level should be addressed in a timely manner, but don&amp;rsquo;t pose an immediate threat to the operation of the cluster as a whole.&lt;/p&gt;
&lt;p&gt;Timeline:  ~60 minutes&lt;/p&gt;
&lt;p&gt;If your alert does not meet the criteria in &amp;ldquo;Critical Alerts&amp;rdquo; above, it belongs to the warning level or lower.&lt;/p&gt;
&lt;p&gt;Use warning level alerts for reporting conditions that may lead to inability to deliver individual features of the cluster, but not service for the cluster as a
whole. Most alerts are likely to be warnings.&lt;br&gt;
Configure warning level alerts so that they do not fire until components have sufficient time to try to recover from the interruption automatically.&lt;br&gt;
Expect users to be notified of a warning, but for them not to respond with corrective action immediately.&lt;/p&gt;
&lt;p&gt;Example warning alert: &lt;a href=&#34;https://github.com/openshift/cluster-version-operator/blob/513a2fc/install/0000_90_cluster-version-operator_02_servicemonitor.yaml#L68-L76&#34;&gt;ClusterNotUpgradeable&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;alert&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ClusterNotUpgradeable&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;summary&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;One&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;or&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;more&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cluster&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;operators&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;have&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;been&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;blocking&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;minor&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;version&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cluster&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;upgrades&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;for&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;at&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;least&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;an&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;hour.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;In&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;most&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cases&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;you&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;will&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;still&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;be&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;able&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;apply&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;patch&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;releases.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;Reason&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;{{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ with $cluster_operator_conditions := \&amp;#34;cluster_operator_conditions\&amp;#34; | query}}{{range $value := .}}{{if and (eq (label \&amp;#34;name\&amp;#34; $value) \&amp;#34;version\&amp;#34;) (eq (label \&amp;#34;condition\&amp;#34; $value) \&amp;#34;Upgradeable\&amp;#34;) (eq (label \&amp;#34;endpoint\&amp;#34; $value) \&amp;#34;metrics\&amp;#34;) (eq (value $value) 0.0) (ne (len (label \&amp;#34;reason\&amp;#34; $value)) 0) }}{{label \&amp;#34;reason\&amp;#34; $value}}.{{end}}{{end}}{{end}}&amp;#34;&lt;/span&gt;}}&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;For&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;more&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;information&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;refer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;oc adm upgrade&amp;#39;&lt;/span&gt;{{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ with $console_url := \&amp;#34;console_url\&amp;#34; | query }}{{ if ne (len (label \&amp;#34;url\&amp;#34; (first $console_url ) ) ) 0}} or {{ label \&amp;#34;url\&amp;#34; (first $console_url ) }}/settings/cluster/{{ end }}{{ end }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;}}.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;expr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;|
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;      max by (name, condition, endpoint) (cluster_operator_conditions{name=&amp;#34;version&amp;#34;, condition=&amp;#34;Upgradeable&amp;#34;, endpoint=&amp;#34;metrics&amp;#34;} == 0)&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;60m&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;labels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;severity&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;warning&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This alert fires if one or more operators have not reported their &lt;code&gt;Upgradeable&lt;/code&gt; condition as true in more than an hour.&lt;br&gt;
The alert has a clear name and informative summary and description annotations.&lt;br&gt;
The timeline is appropriate for allowing the operator a chance to resolve the issue automatically, avoiding the need to alert an administrator.&lt;/p&gt;
&lt;h5 id=&#34;info-alerts&#34;&gt;Info Alerts&lt;/h5&gt;
&lt;p&gt;Info level alerts represent situations an administrator should be aware of, but they don&amp;rsquo;t necessarily require any action.&lt;br&gt;
Use these sparingly, and consider instead reporting this information via Kubernetes events.&lt;/p&gt;
&lt;p&gt;Example info alert: &lt;a href=&#34;https://github.com/openshift/cluster-monitoring-operator/blob/79cdf68/assets/cluster-monitoring-operator/prometheus-rule.yaml#L326-L338&#34;&gt;MultipleContainersOOMKilled&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;alert&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;MultipleContainersOOMKilled&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Multiple&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;containers&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;were&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;out&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;of&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memory&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;killed&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;within&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;past&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;15&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;minutes.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;There&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;are&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;many&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;potential&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;causes&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;of&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;OOM&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;errors&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;however&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;issues&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;on&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;a&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;specific&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;node&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;or&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;containers&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;breaching&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;their&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;limits&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;is&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;common.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;summary&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Containers&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;are&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;being&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;killed&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;due&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;OOM&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;expr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;sum(max&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;by(namespace&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;container&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;pod)&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;(increase(kube_pod_container_status_restarts_total&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;12m&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;))&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;and&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;max&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;by(namespace&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;container&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;pod)&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;(kube_pod_container_status_last_terminated_reason{reason=&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;OOMKilled&amp;#34;&lt;/span&gt;})&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;==&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;)&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;5&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;15m&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;labels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;kube-system&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;severity&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;info&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This alert fires if multiple containers have been terminated due to out of memory conditions in the last 15 minutes.&lt;br&gt;
This is something the administrator should be aware of, but may not require immediate action.&lt;/p&gt;
&lt;h3 id=&#34;alerts-metrics-and-recording-rules-tests&#34;&gt;Alerts, Metrics and Recording Rules Tests&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Add tests for alerts that validate that:
&lt;ul&gt;
&lt;li&gt;Each alert includes all mandatory fields.&lt;/li&gt;
&lt;li&gt;Each &lt;code&gt;runbook_url&lt;/code&gt; link is valid.&lt;/li&gt;
&lt;li&gt;Each alert that includes a &lt;code&gt;pod&lt;/code&gt; or a &lt;code&gt;container&lt;/code&gt; also includes the &lt;code&gt;namespace&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Add e2e tests that inspect the alerts during upgrade and make sure that the alerts don’t fire when they shouldn’t (Zero noise).&lt;/li&gt;
&lt;li&gt;Add tests for metrics and recording rules that validate that:
&lt;ul&gt;
&lt;li&gt;Metric / Recording rule exists.&lt;/li&gt;
&lt;li&gt;Metric / Recording rule value is as expected.&lt;/li&gt;
&lt;li&gt;Metric / Recording rule name follows the best practices guideline.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Testing</title>
      <link>/docs/contribution-guidelines/testing/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/contribution-guidelines/testing/</guid>
      <description>
        
        
        &lt;p&gt;On all PRs, a suite of static and cluster tests is run against your changes in a CI environment.
These tests can also be run locally, which is discussed &lt;a href=&#34;#local-test-environment&#34;&gt;below&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Static tests consist of &lt;a href=&#34;https://onsi.github.io/gomega/&#34;&gt;unit&lt;/a&gt;, formatting, and doc link tests.&lt;/p&gt;
&lt;p&gt;Cluster tests consist of several test types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;End-to-end (e2e): simulate the &amp;ldquo;happy path&amp;rdquo; usage of the &lt;code&gt;operator-sdk&lt;/code&gt; binary and resulting operator project.&lt;/li&gt;
&lt;li&gt;Integration: test components of the &lt;code&gt;operator-sdk&lt;/code&gt; binary and features of scaffolded projects that are
bound to external projects, such as &lt;a href=&#34;https://olm.operatorframework.io/&#34;&gt;OLM&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Subcommand: ensure individual subcommands function as intended with a variety of input options.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;before-submitting-a-pr&#34;&gt;Before submitting a PR&lt;/h2&gt;
&lt;p&gt;Always run tests before submitting a PR to reduce the number of needless CI errors.&lt;/p&gt;
&lt;h5 id=&#34;docs-only&#34;&gt;Docs only&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make test-static
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id=&#34;code&#34;&gt;Code&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make test-all
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;local-test-environment&#34;&gt;Local Test Environment&lt;/h2&gt;
&lt;p&gt;If running tests locally, access to a Kubernetes cluster of a &lt;a href=&#34;/docs/overview#kubernetes-version-compatibility&#34;&gt;compatible version&lt;/a&gt; is required.
These tests require &lt;code&gt;KUBECONFIG&lt;/code&gt; be set or kubeconfig file be present in a default location like &lt;code&gt;$HOME/.kube/config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You will also need to set up an &lt;code&gt;envtest&lt;/code&gt; environment for cluster tests. Follow &lt;a href=&#34;https://book.kubebuilder.io/reference/envtest.html&#34;&gt;this doc&lt;/a&gt;
for setup instructions.&lt;/p&gt;
&lt;h3 id=&#34;local-clusters&#34;&gt;Local clusters&lt;/h3&gt;
&lt;p&gt;A local &lt;a href=&#34;https://kind.sigs.k8s.io/&#34;&gt;kind&lt;/a&gt; cluster is used for running tests.&lt;/p&gt;
&lt;h2 id=&#34;running-tests&#34;&gt;Running Tests&lt;/h2&gt;
&lt;p&gt;All the tests are run through the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/Makefile&#34;&gt;&lt;code&gt;Makefile&lt;/code&gt;&lt;/a&gt;. Run &lt;code&gt;make help&lt;/code&gt; for a full list of available tests.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Plugins</title>
      <link>/docs/contribution-guidelines/plugins/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/contribution-guidelines/plugins/</guid>
      <description>
        
        
        &lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;SDK uses the project &lt;a href=&#34;https://github.com/kubernetes-sigs/kubebuilder&#34;&gt;Kubebuilder&lt;/a&gt; as a library for the CLI and plugins features. For further information see the &lt;a href=&#34;https://master.book.kubebuilder.io/plugins/plugins.html&#34;&gt;Plugins&lt;/a&gt; document. To better understand its motivations, check the design documentation &lt;a href=&#34;https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/integrating-kubebuilder-and-osdk.md&#34;&gt;Integrating Kubebuilder and Operator SDK&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;sdk-language-based-plugins&#34;&gt;SDK Language-based plugins&lt;/h2&gt;
&lt;p&gt;All language-based operator projects provided by SDK (Ansible/Helm/Golang) follow the Kubebuilder standard and have a common base. The common base is generated using &lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize&#34;&gt;kustomize&lt;/a&gt; which is a project maintained and adopted by Kubernetes community to help work with the Kubernertes manifests (YAML files) that are used to configure the resources on the clusters.&lt;/p&gt;
&lt;p&gt;The specific files for each language are scaffolded for the language&amp;rsquo;s plugins. The Operator SDK CLI tool can provide custom plugins and helpers which are common and useful for all language types. To check the common base, you can also run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk init --plugins&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;kustomize
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Also, see the topic &lt;a href=&#34;https://book.kubebuilder.io/plugins/extending/external-plugins&#34;&gt;External Plugins&lt;/a&gt; to understand how it works.&lt;/p&gt;
&lt;h3 id=&#34;common-scaffolds&#34;&gt;Common scaffolds&lt;/h3&gt;
&lt;p&gt;Following the default common scaffolds for the projects which are built with SDK.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File/Directory&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dockerfile&lt;/td&gt;
&lt;td&gt;Defines the operator(manager) image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Makefile&lt;/td&gt;
&lt;td&gt;Provides the helpers and options for the users. (e.g. &lt;code&gt;make bundle&lt;/code&gt; which generate/update the OLM &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md#operator-bundle&#34;&gt;bundle&lt;/a&gt; manifests )&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PROJECT&lt;/td&gt;
&lt;td&gt;Project configuration. Stores the data used to do the scaffolds. For further information see &lt;a href=&#34;https://master.book.kubebuilder.io/reference/project-config.html&#34;&gt;Project Config&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bundle.Dockerfile&lt;/td&gt;
&lt;td&gt;Docker image which is used to provide the helpers to integrate the project with OLM. (e.g. &lt;a href=&#34;/docs/cli/operator-sdk_run&#34;&gt;operator-sdk run ./bundle&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;config/&lt;/td&gt;
&lt;td&gt;Directory which has all &lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize&#34;&gt;kustomize&amp;rsquo;s&lt;/a&gt; manifest to configure and test the project&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You can check the &lt;a href=&#34;/docs/overview/project-layout&#34;&gt;Project Layout&lt;/a&gt; to better understand the files and directories scaffolded by SDK CLI, which may be common for each language-type.&lt;/p&gt;
&lt;h2 id=&#34;custom-plugins&#34;&gt;Custom Plugins&lt;/h2&gt;
&lt;p&gt;By default plugins are used by the Operator SDK to provide the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/internal/plugins/manifests/v2&#34;&gt;manifests.sdk.operatorframework.io&lt;/a&gt;: perform the required scaffolds to provide the helpers to allow the projects to be integrated with OLM.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/internal/plugins/scorecard/v2&#34;&gt;scorecard.sdk.operatorframework.io&lt;/a&gt;: perform the required scaffolds to provide the &lt;a href=&#34;/docs/testing-operators/scorecard/&#34;&gt;Scorecard&lt;/a&gt; feature.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;optionalcustom-plugins&#34;&gt;Optional/custom plugins&lt;/h3&gt;
&lt;p&gt;Users can also use custom plugins when they execute the SDK CLI sub-commands as a helper which includes the following options:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk create api --plugins&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;go/v3,declarative&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above example will scaffold custom code in the controllers after an API is created to allow the users to develop solutions using the &lt;a href=&#34;https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern&#34;&gt;kubebuilder declarative pattern&lt;/a&gt;. (e.g &lt;a href=&#34;https://github.com/kubernetes-sigs/kubebuilder/blob/v3.13.0/testdata/project-v3/controllers/admiral_controller.go&#34;&gt;default scaffold&lt;/a&gt; versus &lt;a href=&#34;https://github.com/kubernetes-sigs/kubebuilder/blob/v3.13.0/testdata/project-v3/controllers/firstmate_controller.go&#34;&gt;example&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Note that custom plugins are called via the init sub-command to work as global plugins, and will be added in the &lt;code&gt;layout&lt;/code&gt; field of the PROJECT file. Any sub-command executed will then also be called.&lt;/p&gt;
&lt;h2 id=&#34;plugins-vision&#34;&gt;Plugins Vision&lt;/h2&gt;
&lt;p&gt;Contributors are able to create their own plugin(s) using the same standards and approach described by this document. Following them facilitates in-tree (in other words, built with the &lt;code&gt;operator-sdk&lt;/code&gt; binary) addition of such community-driven plugins to the Operator SDK project by making review easier and code maintainable. Currently, the SDK cannot discover and use plugins that are not in-tree. However, out-of-tree plugins have been discussed in &lt;a href=&#34;https://github.com/kubernetes-sigs/kubebuilder/issues/1378&#34;&gt;kubebuilder/issues/1378&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;how-to-create-your-own-plugins&#34;&gt;How to create your own plugins&lt;/h2&gt;
&lt;p&gt;If you are looking to develop similar solutions to allow users for example to create projects using other languages or that could work as helpers for the projects built with SDK/Kubebuilder projects, then see the &lt;a href=&#34;https://book.kubebuilder.io/plugins/extending&#34;&gt;Creating your own plugins&lt;/a&gt; to see how you can benefit and apply this approach.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: OLM and Bundle CLI Overview</title>
      <link>/docs/olm-integration/cli-overview/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/cli-overview/</guid>
      <description>
        
        
        &lt;p&gt;This document gives an overview of using &lt;code&gt;operator-sdk&lt;/code&gt; to work with Operator manifests related to OLM,
namely &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundles&lt;/a&gt; and &lt;a href=&#34;https://github.com/operator-framework/operator-registry/tree/v1.5.3#manifest-format&#34;&gt;package manifests&lt;/a&gt;. See the &lt;a href=&#34;/docs/olm-integration/generation&#34;&gt;manifests generation&lt;/a&gt;
doc for an in-depth discussion of these commands.&lt;/p&gt;
&lt;h2 id=&#34;olm-installation&#34;&gt;OLM installation&lt;/h2&gt;
&lt;p&gt;The following &lt;code&gt;operator-sdk&lt;/code&gt; subcommands manage an OLM installation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_olm_install&#34;&gt;&lt;code&gt;olm install&lt;/code&gt;&lt;/a&gt;: install a particular version of OLM.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_olm_status&#34;&gt;&lt;code&gt;olm status&lt;/code&gt;&lt;/a&gt;: check the status of a particular version of OLM running in a cluster. This command
can infer the version of an error-free OLM installation.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_olm_uninstall&#34;&gt;&lt;code&gt;olm uninstall&lt;/code&gt;&lt;/a&gt;: uninstall a particular version of OLM running in a cluster. This command
can infer the version of an error-free OLM installation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;manifests-and-metadata&#34;&gt;Manifests and metadata&lt;/h2&gt;
&lt;p&gt;The following &lt;code&gt;make&lt;/code&gt; recipes and &lt;code&gt;operator-sdk&lt;/code&gt; subcommands create or interact with Operator package manifests and bundles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_generate_kustomize_manifests&#34;&gt;&lt;code&gt;generate kustomize manifests&lt;/code&gt;&lt;/a&gt;: creates kustomize bases and a &lt;code&gt;kustomization.yaml&lt;/code&gt; in &lt;code&gt;config/manifests&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;bundles&#34;&gt;Bundles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;make bundle&lt;/code&gt;: runs the following commands:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;generate kustomize manifests&lt;/code&gt;: see &lt;a href=&#34;#manifests-and-metadata&#34;&gt;above&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_generate_bundle&#34;&gt;&lt;code&gt;generate bundle&lt;/code&gt;&lt;/a&gt;: creates a new or updates an existing bundle in the &lt;code&gt;&amp;lt;project-root&amp;gt;/bundle&lt;/code&gt;
directory. This command generates both manifests and metadata.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_bundle_validate&#34;&gt;&lt;code&gt;bundle validate&lt;/code&gt;&lt;/a&gt;: validates an Operator bundle image or unpacked manifests and metadata.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make bundle-build&lt;/code&gt;: builds a bundle image using the &lt;code&gt;bundle.Dockerfile&lt;/code&gt; generated by &lt;code&gt;make bundle&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_run_bundle&#34;&gt;&lt;code&gt;run bundle&lt;/code&gt;&lt;/a&gt;: runs the given Operator&amp;rsquo;s bundle image with an
existing OLM installation.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_run_bundle-upgrade&#34;&gt;&lt;code&gt;run bundle-upgrade&lt;/code&gt;&lt;/a&gt;: upgrades the Operator bundle to a specified newer version.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;private-bundle-and-catalog-image-registries&#34;&gt;Private bundle and catalog image registries&lt;/h4&gt;
&lt;p&gt;By default, projects are configured to push to and pull from a &lt;a href=&#34;https://hub.docker.com/&#34;&gt;docker.io&lt;/a&gt; registry
with namespace being the value passed to &lt;code&gt;operator-sdk init --domain=&amp;lt;value&amp;gt;&lt;/code&gt;.
Modify this value to push/pull bundle and catalog images with a different registry host or namespace.&lt;/p&gt;
&lt;p&gt;All bundle and catalog image-related commands invoke &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/496ccce/docs/design/opm-tooling.md&#34;&gt;&lt;code&gt;opm&lt;/code&gt;&lt;/a&gt; (except for bundle image builds,
for which &lt;code&gt;docker&lt;/code&gt; is used directly). &lt;code&gt;opm&lt;/code&gt; leverages the host&amp;rsquo;s image build/pull tools indirectly
to perform various image tasks, so if your image registry is private or has a custom CA you
must ensure the in-use build tool is able to push to/pull from the registry:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker&lt;/code&gt;: &lt;a href=&#34;https://docs.docker.com/engine/reference/commandline/login/&#34;&gt;&lt;code&gt;config.json&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;https://docs.docker.com/engine/security/certificates/&#34;&gt;certificate configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;podman&lt;/code&gt;: &lt;a href=&#34;http://docs.podman.io/en/latest/markdown/podman-login.1.html#description&#34;&gt;&lt;code&gt;auth.json&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;http://docs.podman.io/en/latest/markdown/podman-image-sign.1.html#cert-dir-path&#34;&gt;certificate configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;none&lt;/code&gt; (containerd): uses docker&amp;rsquo;s &lt;code&gt;config.json&lt;/code&gt;, &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/master/docs/design/opm-tooling.md#add&#34;&gt;certificate configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;run bundle&lt;/code&gt; or &lt;code&gt;run bundle-upgrade&lt;/code&gt; commands use the &lt;code&gt;none&lt;/code&gt; image tool, described above, in-cluster.
These commands accept the names of secrets available in the deployment namespace that contain configuration file data.
Ideally a cluster admin will provision a namespace and service account for bundle testing,
such that they include and reference these secrets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create an &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/&#34;&gt;image pull secret&lt;/a&gt; for your &lt;code&gt;config.json&lt;/code&gt; and &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-image-pull-secret-to-service-account&#34;&gt;add it to your service account&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- TODO(estroz): remove the service account requirement once OLM releases a patch or new
minor release containing https://github.com/operator-framework/operator-lifecycle-manager/pull/1941 --&gt;
&lt;ul&gt;
&lt;li&gt;Create a &lt;a href=&#34;https://kubernetes.io/docs/tasks/configmap-secret/managing-secret-using-kubectl/#create-a-secret&#34;&gt;generic secret&lt;/a&gt; with a &lt;code&gt;cert.pem&lt;/code&gt; key containing root certificate(s) for your registry.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once the above secrets have been created, run the either command with &lt;code&gt;--pull-secret-name=&amp;lt;image pull secret&amp;gt;&lt;/code&gt; and &lt;code&gt;--ca-secret-name=&amp;lt;certificate secret&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk run bundle private-custom-ca-reg.com/memcached-operator-bundle:v0.0.2 &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;    --index-image private-custom-ca-reg.com/memcached-operator-catalog:v0.0.1 &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;    --pull-secret-name foo-pull-sec &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;    --ca-secret-name foo-cert-sec
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You may have to set &lt;code&gt;--namespace=&amp;lt;provisioned namespace&amp;gt;&lt;/code&gt; if the namespace encoded in your kubeconfig&amp;rsquo;s current context
was not provisioned with these secrets.&lt;/p&gt;
&lt;h3 id=&#34;package-manifests&#34;&gt;Package Manifests&lt;/h3&gt;
&lt;p&gt;The operator-framework is removing support for the packagemanifests format in the near future, and migration efforts are currently underway. Therefore &lt;code&gt;generate packagemanifests&lt;/code&gt; and &lt;code&gt;run packagemanifests&lt;/code&gt; commands have been deprecated. For more
details on bundle format refer &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;here&lt;/a&gt;. To migrate from packagemanifests to the bundle format, use the &lt;a href=&#34;/docs/cli/operator-sdk_pkgman-to-bundle&#34;&gt;&lt;code&gt;operator-sdk pkgman-to-bundle&lt;/code&gt;&lt;/a&gt; command.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Controller Runtime Client API</title>
      <link>/docs/building-operators/golang/references/client/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/golang/references/client/</guid>
      <description>
        
        
        &lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime&#34;&gt;&lt;code&gt;controller-runtime&lt;/code&gt;&lt;/a&gt; library provides various abstractions to watch and reconcile resources in a Kubernetes cluster via CRUD (Create, Update, Delete, as well as Get and List in this case) operations. Operators use at least one controller to perform a coherent set of tasks within a cluster, usually through a combination of CRUD operations. The Operator SDK uses controller-runtime&amp;rsquo;s &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#Client&#34;&gt;Client&lt;/a&gt; interface, which provides the interface for these operations.&lt;/p&gt;
&lt;p&gt;controller-runtime defines several interfaces used for cluster interaction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;client.Client&lt;/code&gt;: implementers perform CRUD operations on a Kubernetes cluster.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;manager.Manager&lt;/code&gt;: manages shared dependencies, such as Caches and Clients.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reconcile.Reconciler&lt;/code&gt;: compares provided state with actual cluster state and updates the cluster on finding state differences using a Client.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Clients are the focus of this document. A separate document will discuss Managers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; this document uses parts of the sample &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/testdata/go/v4/memcached-operator&#34;&gt;&lt;code&gt;memcached-operator&lt;/code&gt;&lt;/a&gt; for example code.
Import paths may be different for brevity.&lt;/p&gt;
&lt;h2 id=&#34;client-usage&#34;&gt;Client Usage&lt;/h2&gt;
&lt;h3 id=&#34;default-client&#34;&gt;Default Client&lt;/h3&gt;
&lt;p&gt;The SDK relies on a &lt;code&gt;manager.Manager&lt;/code&gt; to create a &lt;code&gt;client.Client&lt;/code&gt; interface that performs Create, Update, Delete, Get, and List operations within a &lt;code&gt;reconcile.Reconciler&lt;/code&gt;&#39;s Reconcile function. The SDK will generate code to create a Manager, which holds a Cache and a Client to be used in CRUD operations and communicate with the API server. By default a Controller&amp;rsquo;s Reconciler will be populated with the Manager&amp;rsquo;s Client which is a &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#DelegatingClient&#34;&gt;split-client&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The following code, found in &lt;code&gt;controllers/memcached_controller.go&lt;/code&gt;, demonstrates how the Manager&amp;rsquo;s client is passed to a reconciler.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/api/apps/v1&amp;#34;&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;

	&lt;span style=&#34;color:#000&#34;&gt;cachev1alpha1&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;github.com/example/memcached-operator/api/v1alpha1&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;SetupWithManager&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;mgr&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Manager&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NewControllerManagedBy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;mgr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt; &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// mgr&amp;#39;s Client is passed to r.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#000&#34;&gt;For&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cachev1alpha1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}).&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;Owns&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Deployment&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}).&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;Complete&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt; &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Populated above from a manager.Manager.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;Log&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;logr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Logger&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;runtime&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A split client reads (Get and List) from the Cache and writes (Create, Update, Delete) to the API server. Reading from the Cache significantly reduces request load on the API server; as long as the Cache is updated by the API server, read operations are eventually consistent.&lt;/p&gt;
&lt;h3 id=&#34;non-default-client&#34;&gt;Non-default Client&lt;/h3&gt;
&lt;p&gt;An operator developer may wish to create their own Client that serves read requests(Get List) from the API server instead of the cache, for example. controller-runtime provides a &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#New&#34;&gt;constructor&lt;/a&gt; for Clients:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// New returns a new Client using the provided config and Options.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;New&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;config&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;rest&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Config&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;options&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Options&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;client.Options&lt;/code&gt; allow the caller to specify how the new Client should communicate with the API server.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Options are creation options for a Client
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Options&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Scheme, if provided, will be used to map go structs to GroupVersionKinds
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;runtime&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Mapper, if provided, will be used to map GroupVersionKinds to Resources
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;Mapper&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;meta&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;RESTMapper&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/client/config&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/client&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;config&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GetConfig&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt;
&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;c&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;New&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Options&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{})&lt;/span&gt;
&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: defaults are set by &lt;code&gt;client.New&lt;/code&gt; when Options are empty. The default &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime/blob/master/pkg/client/client.go#L51&#34;&gt;scheme&lt;/a&gt; will have the &lt;a href=&#34;https://pkg.go.dev/k8s.io/api/core/v1&#34;&gt;core&lt;/a&gt; Kubernetes resource types registered. The caller &lt;em&gt;must&lt;/em&gt; set a scheme that has custom operator types registered for the new Client to recognize these types.&lt;/p&gt;
&lt;p&gt;Creating a new Client is not usually necessary nor advised, as the default Client is sufficient for most use cases.&lt;/p&gt;
&lt;h3 id=&#34;reconcile-and-the-client-api&#34;&gt;Reconcile and the Client API&lt;/h3&gt;
&lt;p&gt;A Reconciler implements the &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/reconcile#Reconciler&#34;&gt;&lt;code&gt;reconcile.Reconciler&lt;/code&gt;&lt;/a&gt; interface, which exposes the Reconcile method. Reconcilers are added to a corresponding Controller for a Kind; Reconcile is called in response to cluster or external Events, with a &lt;code&gt;reconcile.Request&lt;/code&gt; object argument, to read and write cluster state by the Controller, and returns a &lt;code&gt;ctrl.Result&lt;/code&gt;. SDK Reconcilers have access to a Client in order to make Kubernetes API calls.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// MemcachedReconciler reconciles a Memcached object
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// client, initialized using mgr.Client() above, is a split client
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// that reads objects from the cache and writes to the apiserver
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;Log&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;logr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Logger&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// scheme defines methods for serializing and deserializing API objects,
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// a type registry for converting group, version, and kind information
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// to and from Go schemas, and mappings between Go schemas of different
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// versions. A scheme is the foundation for a versioned API and versioned
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// configuration over time.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;runtime&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Reconcile watches for Events and reconciles cluster state with desired
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// state defined in the method body.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// The Controller will requeue the Request to be processed again if an error
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// is non-nil or Result.Requeue is true, otherwise upon completion it will
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// remove the work from the queue.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Reconcile is where Controller business logic lives, i.e. where Client API calls are made via &lt;code&gt;MemcachedReconciler.client&lt;/code&gt;. A &lt;code&gt;client.Client&lt;/code&gt; implementer performs the following operations:&lt;/p&gt;
&lt;h4 id=&#34;get&#34;&gt;Get&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Get retrieves an API object for a given object key from the Kubernetes cluster
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// and stores it in obj.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;key&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ObjectKey&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;obj&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Object&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: A &lt;code&gt;client.ObjectKey&lt;/code&gt; is simply an alias for &lt;a href=&#34;https://pkg.go.dev/k8s.io/apimachinery/pkg/types#NamespacedName&#34;&gt;&lt;code&gt;types.NamespacedName&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;cachev1alpha1&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;github.com/example/memcached-operator/api/v1alpha1&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cachev1alpha1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;list&#34;&gt;List&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// List retrieves a list of objects for a given namespace and list options
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// and stores the list in obj.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;List&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;list&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Object&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ListOption&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A &lt;code&gt;client.ListOption&lt;/code&gt; is an interface that sets &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#ListOptions&#34;&gt;&lt;code&gt;client.ListOptions&lt;/code&gt;&lt;/a&gt; fields. A &lt;code&gt;client.ListOption&lt;/code&gt; is created by using one of the provided implementations: &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#MatchingLabels&#34;&gt;&lt;code&gt;MatchingLabels&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#MatchingFields&#34;&gt;&lt;code&gt;MatchingFields&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#InNamespace&#34;&gt;&lt;code&gt;InNamespace&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/api/core/v1&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/client&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Return all pods in the request namespace with a label of `instance=&amp;lt;name&amp;gt;`
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// and phase `Running`.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;podList&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodList&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ListOption&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;InNamespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchingLabels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;instance&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchingFields&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;status.phase&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Running&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;List&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;podList&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;create&#34;&gt;Create&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Create saves the object obj in the Kubernetes cluster.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Returns an error
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Create&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;obj&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Object&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;CreateOption&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A &lt;code&gt;client.CreateOption&lt;/code&gt; is an interface that sets &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#CreateOptions&#34;&gt;&lt;code&gt;client.CreateOptions&lt;/code&gt;&lt;/a&gt; fields. A &lt;code&gt;client.CreateOption&lt;/code&gt; is created by using one of the provided implementations: &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#DryRunAll&#34;&gt;&lt;code&gt;DryRunAll&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#ForceOwnership&#34;&gt;&lt;code&gt;ForceOwnership&lt;/code&gt;&lt;/a&gt;. Generally these options are not needed.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/api/apps/v1&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Deployment&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt; &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Any cluster object you want to create.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Create&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;update&#34;&gt;Update&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Update updates the given obj in the Kubernetes cluster. obj must be a
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// struct pointer so that obj can be updated with the content returned
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// by the API server. Update does *not* update the resource&amp;#39;s status
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// subresource
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Update&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;obj&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Object&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;UpdateOption&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A &lt;code&gt;client.UpdateOption&lt;/code&gt; is an interface that sets &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#UpdateOptions&#34;&gt;&lt;code&gt;client.UpdateOptions&lt;/code&gt;&lt;/a&gt; fields. A &lt;code&gt;client.UpdateOption&lt;/code&gt; is created by using one of the provided implementations: &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#DryRunAll&#34;&gt;&lt;code&gt;DryRunAll&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#ForceOwnership&#34;&gt;&lt;code&gt;ForceOwnership&lt;/code&gt;&lt;/a&gt;. Generally these options are not needed.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/api/apps/v1&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Deployment&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Selector&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchLabels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;is_running&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Update&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;patch&#34;&gt;Patch&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Patch patches the given obj in the Kubernetes cluster. obj must be a
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// struct pointer so that obj can be updated with the content returned by the Server.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Patch&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;obj&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Object&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;patch&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Patch&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PatchOption&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A &lt;code&gt;client.PatchOption&lt;/code&gt; is an interface that sets &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#PatchOption&#34;&gt;&lt;code&gt;client.PatchOptions&lt;/code&gt;&lt;/a&gt; fields. A &lt;code&gt;client.PatchOption&lt;/code&gt; is created by using one of the provided implementations: &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#DryRunAll&#34;&gt;&lt;code&gt;DryRunAll&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#ForceOwnership&#34;&gt;&lt;code&gt;ForceOwnership&lt;/code&gt;&lt;/a&gt;. Generally these options are not needed.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/api/apps/v1&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/client&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Deployment&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// A merge patch will preserve other fields modified at runtime.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;patch&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MergeFrom&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DeepCopy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;())&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Selector&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchLabels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;is_running&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Patch&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;patch&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id=&#34;updating-status-subresource&#34;&gt;Updating Status Subresource&lt;/h5&gt;
&lt;p&gt;When updating the &lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#status-subresource&#34;&gt;status subresource&lt;/a&gt; from the client, the &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#StatusWriter&#34;&gt;&lt;code&gt;StatusWriter&lt;/code&gt;&lt;/a&gt; must be used. The status subresource is retrieved with &lt;code&gt;Status()&lt;/code&gt; and updated with &lt;code&gt;Update()&lt;/code&gt; or patched with &lt;code&gt;Patch()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Update()&lt;/code&gt; takes variadic &lt;code&gt;client.UpdateOption&lt;/code&gt;&#39;s, and &lt;code&gt;Patch()&lt;/code&gt; takes variadic &lt;code&gt;client.PatchOption&lt;/code&gt;&#39;s. See &lt;a href=&#34;#update&#34;&gt;&lt;code&gt;Client.Update()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;#patch&#34;&gt;&lt;code&gt;Client.Patch()&lt;/code&gt;&lt;/a&gt; for more details. Generally these options are not needed.&lt;/p&gt;
&lt;h5 id=&#34;status&#34;&gt;Status&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Status() returns a StatusWriter object that can be used to update the
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// object&amp;#39;s status subresource
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;StatusWriter&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;cachev1alpha1&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;github.com/example/memcached-operator/api/v1alpha1&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;mem&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cachev1alpha1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;mem&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Update
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;mem&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Nodes&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod2&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;().&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Update&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;mem&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Patch
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;patch&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MergeFrom&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;mem&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DeepCopy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;())&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;mem&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Nodes&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod2&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod3&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;().&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Patch&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;mem&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;patch&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;delete&#34;&gt;Delete&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Delete deletes the given obj from Kubernetes cluster.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Delete&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;obj&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Object&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DeleteOption&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A &lt;code&gt;client.DeleteOption&lt;/code&gt; is an interface that sets &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#DeleteOptions&#34;&gt;&lt;code&gt;client.DeleteOptions&lt;/code&gt;&lt;/a&gt; fields. A &lt;code&gt;client.DeleteOption&lt;/code&gt; is created by using one of the provided implementations: &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#GracePeriodSeconds&#34;&gt;&lt;code&gt;GracePeriodSeconds&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#Preconditions&#34;&gt;&lt;code&gt;Preconditions&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#PropagationPolicy&#34;&gt;&lt;code&gt;PropagationPolicy&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/api/core/v1&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/client&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;pod&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Pod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;pod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;pod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Phase&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodUnknown&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Delete the pod after 5 seconds.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Delete&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;pod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GracePeriodSeconds&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;5&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;))&lt;/span&gt;
        &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;deleteallof&#34;&gt;DeleteAllOf&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// DeleteAllOf deletes all objects of the given type matching the given options.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;DeleteAllOf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;obj&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Object&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DeleteAllOfOption&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A &lt;code&gt;client.DeleteAllOfOption&lt;/code&gt; is an interface that sets &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client#DeleteAllOfOptions&#34;&gt;&lt;code&gt;client.DeleteAllOfOptions&lt;/code&gt;&lt;/a&gt; fields. A &lt;code&gt;client.DeleteAllOfOption&lt;/code&gt; wraps a &lt;a href=&#34;#list&#34;&gt;&lt;code&gt;client.ListOption&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;#delete&#34;&gt;&lt;code&gt;client.DeleteOption&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/api/core/v1&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/client&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Delete all pods in the request namespace with a label of `instance=&amp;lt;name&amp;gt;`
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// and phase `Failed`.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;pod&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Pod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DeleteAllOfOption&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;InNamespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchingLabels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;instance&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchingFields&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;status.phase&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Failed&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GracePeriodSeconds&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;5&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DeleteAllOf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;pod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;example-usage&#34;&gt;Example usage&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;reflect&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/api/apps/v1&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/api/core/v1&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/apimachinery/pkg/api/errors&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;metav1&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/apimachinery/pkg/apis/meta/v1&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/apimachinery/pkg/labels&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/apimachinery/pkg/runtime&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;k8s.io/apimachinery/pkg/types&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/client&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/controller/controllerutil&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;cachev1alpha1&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;github.com/example/memcached-operator/api/v1alpha1&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;Log&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;logr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Logger&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;runtime&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Fetch the Memcached instance.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cachev1alpha1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;errors&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;IsNotFound&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Check if the deployment already exists, if not create a new deployment.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;found&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Deployment&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;types&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;found&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
         &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;errors&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;IsNotFound&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Define and create a new deployment.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;deploymentForMemcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Create&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Requeue&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Ensure the deployment size is the same as the spec.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;size&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Size&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;found&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Replicas&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;size&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;found&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Replicas&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;size&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Update&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;found&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Requeue&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Update the Memcached status with the pod names.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// List the pods for this CR&amp;#39;s deployment.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;podList&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodList&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;listOpts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ListOption&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;InNamespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchingLabels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;labelsForApp&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)),&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;List&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;podList&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;listOpts&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Update status.Nodes if needed.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;podNames&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;getPodNames&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;podList&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Items&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;!&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;reflect&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DeepEqual&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;podNames&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Nodes&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Nodes&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;podNames&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;().&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Update&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// deploymentForMemcached returns a Deployment object for data from m.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;deploymentForMemcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;m&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cachev1alpha1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Deployment&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;lbls&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;labelsForApp&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;m&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;replicas&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;m&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Size&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Deployment&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;ObjectMeta&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;metav1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ObjectMeta&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            &lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;      &lt;span style=&#34;color:#000&#34;&gt;m&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;m&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DeploymentSpec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            &lt;span style=&#34;color:#000&#34;&gt;Replicas&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;replicas&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#000&#34;&gt;Selector&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;metav1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;LabelSelector&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                &lt;span style=&#34;color:#000&#34;&gt;MatchLabels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;lbls&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
            &lt;span style=&#34;color:#000&#34;&gt;Template&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodTemplateSpec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                &lt;span style=&#34;color:#000&#34;&gt;ObjectMeta&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;metav1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ObjectMeta&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                    &lt;span style=&#34;color:#000&#34;&gt;Labels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;lbls&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
                &lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodSpec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                    &lt;span style=&#34;color:#000&#34;&gt;Containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Container&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{{&lt;/span&gt;
                        &lt;span style=&#34;color:#000&#34;&gt;Image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;memcached:alpine&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
                        &lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;memcached&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
                        &lt;span style=&#34;color:#000&#34;&gt;Command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;memcached&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;-a=64&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;-b&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
                        &lt;span style=&#34;color:#000&#34;&gt;Ports&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ContainerPort&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{{&lt;/span&gt;
                            &lt;span style=&#34;color:#000&#34;&gt;ContainerPort&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;10000&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
                            &lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;memcached&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
                        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}},&lt;/span&gt;
                    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}},&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Set Memcached instance as the owner and controller.memcac
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// NOTE: calling SetControllerReference, and setting owner references in
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// general, is important as it allows deleted objects to be garbage collected.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;controllerutil&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SetControllerReference&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;m&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// labelsForApp creates a simple set of labels for Memcached.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;labelsForApp&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;cr_name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Ansible Operator Advanced Options</title>
      <link>/docs/building-operators/ansible/reference/advanced_options/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/advanced_options/</guid>
      <description>
        
        
        &lt;p&gt;This document shows the advanced options available to a developer of an ansible operator.&lt;/p&gt;
&lt;h3 id=&#34;runner-directory&#34;&gt;Runner Directory&lt;/h3&gt;
&lt;p&gt;The ansible runner will keep information about the ansible run in the container.  This is located &lt;code&gt;/tmp/ansible-operator/runner/&amp;lt;group&amp;gt;/&amp;lt;version&amp;gt;/&amp;lt;kind&amp;gt;/&amp;lt;namespace&amp;gt;/&amp;lt;name&amp;gt;&lt;/code&gt;. To learn more  about the runner directory you can read the &lt;a href=&#34;https://ansible-runner.readthedocs.io/en/latest/index.html&#34;&gt;ansible-runner docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;owner-reference-injection&#34;&gt;Owner Reference Injection&lt;/h2&gt;
&lt;p&gt;Owner references enable &lt;a href=&#34;https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/&#34;&gt;Kubernetes Garbage Collection&lt;/a&gt; to clean up after a CR is deleted. Owner references are injected by ansible operators by default by the proxy.&lt;/p&gt;
&lt;p&gt;Owner references only apply to resources in the same namespace as the CR. Resources outside the namespace of the CR will automatically be annotated with &lt;code&gt;operator-sdk/primary-resource&lt;/code&gt; and &lt;code&gt;operator-sdk/primary-resource-type&lt;/code&gt; to track creation. These resources will not be automatically garbage collected. To handle deletion of these resources, use a &lt;a href=&#34;../finalizers&#34;&gt;finalizer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You may want to manage what your operator watches and the owner references. This means that your operator will need to understand how to clean up after itself when your CR is deleted. To disable these features you will need to edit your &lt;code&gt;Dockerfile&lt;/code&gt; to include the line below.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: That if you use this feature there will be a warning that dependent watches is turned off but there will be no error.
&lt;strong&gt;WARNING&lt;/strong&gt;: Once a CR is deployed without owner reference injection, there is no automatic way to add those references.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ENTRYPOINT [&amp;quot;/usr/local/bin/entrypoint&amp;quot;, &amp;quot;--inject-owner-ref=false&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you have created resources without owner reference injection, it is
possible to manually to update resources following &lt;a href=&#34;../retroactively-owned-resources&#34;&gt;this
guide.&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;max-concurrent-reconciles&#34;&gt;Max Concurrent Reconciles&lt;/h2&gt;
&lt;p&gt;Increasing the number of concurrent reconciles allows events to be processed
concurrently, which can improve reconciliation performance.&lt;/p&gt;
&lt;p&gt;The maximum number of concurrent reconciles can be set in two ways. Operator &lt;strong&gt;authors and admins&lt;/strong&gt;
can set the max concurrent reconciles default by including extra args to the operator
container in &lt;code&gt;config/manager/manager.yaml&lt;/code&gt; and the patch in &lt;code&gt;config/default/auth_proxy_patch.yaml&lt;/code&gt;.
(Otherwise, the default is the maximum number of logical CPUs available for the process obtained
using &lt;code&gt;runtime.NumCPU()&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Admins using OLM should use the environment variable instead
of the extra args.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;quay.io/asmacdo/memcached-operator:v0.0.0&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;imagePullPolicy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Always&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;--max-concurrent-reconciles&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;3&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Operator &lt;strong&gt;admins&lt;/strong&gt; can override the value by setting an environment
variable in the format &lt;code&gt;MAX_CONCURRENT_RECONCILES_&amp;lt;kind&amp;gt;_&amp;lt;group&amp;gt;&lt;/code&gt;. This variable must be
all uppercase, and periods (e.g. in the group name) are replaced with underscores.&lt;/p&gt;
&lt;p&gt;For the memcached operator example, the component parts are retrieved
with a GET on the operator:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ kubectl get memcacheds example-memcached -o yaml

apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
  name: example-memcached
  namespace: default
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From this data, we can see that the environment variable will be
&lt;code&gt;MAX_CONCURRENT_RECONCILES_MEMCACHED_CACHE_EXAMPLE_COM&lt;/code&gt;, which we can then add to
&lt;code&gt;config/manager/manager.yaml&lt;/code&gt; and &lt;code&gt;config/default/auth_proxy_patch.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;quay.io/asmacdo/memcached-operator:v0.0.0&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;imagePullPolicy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Always&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# This default is overridden.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;--max-concurrent-reconciles&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;3&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# This value is used&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;MAX_CONCURRENT_RECONCILES_MEMCACHED_CACHE_EXAMPLE_COM&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;6&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;ansible-verbosity&#34;&gt;Ansible Verbosity&lt;/h2&gt;
&lt;p&gt;Setting the verbosity at which &lt;code&gt;ansible-runner&lt;/code&gt; is run controls how verbose the
output of &lt;code&gt;ansible-playbook&lt;/code&gt; will be. The normal rules for verbosity apply
here, where higher values mean more output. Acceptable values range from 0
(only the most severe messages are output) to 7 (all debugging messages are
output).&lt;/p&gt;
&lt;p&gt;There are three ways to configure the verbosity argument to the &lt;code&gt;ansible-runner&lt;/code&gt;
command:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Operator &lt;strong&gt;authors and admins&lt;/strong&gt; can set the Ansible verbosity by including
extra args to the operator container in the operator deployment.&lt;/li&gt;
&lt;li&gt;Operator &lt;strong&gt;admins&lt;/strong&gt; can set Ansible verbosity by setting an environment
variable in the format &lt;code&gt;ANSIBLE_VERBOSITY_&amp;lt;kind&amp;gt;_&amp;lt;group&amp;gt;&lt;/code&gt;. This variable must
be all uppercase and all periods (e.g. in the group name) are replaced with
underscore.&lt;/li&gt;
&lt;li&gt;Operator &lt;strong&gt;users, authors, and admins&lt;/strong&gt; can set the Ansible verbosity by
setting the &lt;code&gt;&amp;quot;ansible.sdk.operatorframework.io/verbosity&amp;quot;&lt;/code&gt; annotation on the Custom
Resource.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;examples&#34;&gt;Examples&lt;/h3&gt;
&lt;p&gt;For demonstration purposes, let us assume that we have a database operator that
supports two Kinds &amp;ndash; &lt;code&gt;MongoDB&lt;/code&gt; and &lt;code&gt;PostgreSQL&lt;/code&gt; &amp;ndash; in the &lt;code&gt;db.example.com&lt;/code&gt;
Group. We have only recently implemented the support for the &lt;code&gt;MongoDB&lt;/code&gt; Kind so
we want reconciles for this Kind to be more verbose. Our operator container&amp;rsquo;s
spec in our &lt;code&gt;config/manager/manager.yaml&lt;/code&gt; and &lt;code&gt;config/default/auth_proxy_patch.yaml&lt;/code&gt;
files might contain something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;quay.io/example/database-operator:v1.0.0&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;imagePullPolicy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Always&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# This value applies to all GVKs specified in watches.yaml&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# that are not overridden by environment variables.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;--ansible-verbosity&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Override the verbosity for the MongoDB kind&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ANSIBLE_VERBOSITY_MONGODB_DB_EXAMPLE_COM&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the Operator is deployed, the only way to change the verbosity is via the
&lt;code&gt;&amp;quot;ansible.sdk.operatorframework.io/verbosity&amp;quot;&lt;/code&gt; annotation. Continuing with our example, our
CR may look like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;db.example.com/v1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;PostgreSQL&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example-db&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;ansible.sdk.operatorframework.io/verbosity&amp;#34;: &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;5&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;custom-resources-with-openapi-validation&#34;&gt;Custom Resources with OpenAPI Validation&lt;/h2&gt;
&lt;p&gt;Currently, SDK tool does not support and will not generate automatically the CRD&amp;rsquo;s using the &lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation&#34;&gt;OpenAPI&lt;/a&gt; spec to perform validations.&lt;/p&gt;
&lt;p&gt;However, it can be done manually by adding its validations as you can check in the following example.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;apiextensions.k8s.io/v1beta1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;CustomResourceDefinition&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcacheds.cache.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;names&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;listKind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;MemcachedList&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;plural&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcacheds&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;singular&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;scope&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Namespaced&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;subresources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;validation&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;openAPIV3Schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;is&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Schema&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;for&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcacheds&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;API&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;properties&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;APIVersion defines the versioned schema of this representation
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;            of an object. Servers should convert recognized schemas to the latest
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;            internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;string&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;Kind is a string value representing the REST resource this
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;            object represents. Servers may infer this from the endpoint the client
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;            submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;string&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;object&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;MemcachedSpec&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;defines&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;desired&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;state&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;of&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;properties&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;size&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Size&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;is&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;size&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;of&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;deployment&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;format&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;int32&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;integer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;required&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;- size&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;object&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;status&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;MemcachedStatus&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;defines&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;observed&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;state&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;of&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;properties&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nodes&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Nodes&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;are&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;names&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;of&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;pods&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;items&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;string&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;array&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;required&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;- nodes&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;object&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;object&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;versions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;served&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;storage&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;passing-arbitrary-arguments-to-ansible&#34;&gt;Passing Arbitrary Arguments to Ansible&lt;/h2&gt;
&lt;p&gt;You are able to use the flag &lt;code&gt;--ansible-args&lt;/code&gt; to pass an arbitrary argument to the Ansible-based Operator. With this option we can, for example, allow a playbook to run a specific part of the configuration without running the whole playbook:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;ansible-operator run --ansible-args&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;--tags &amp;#34;configuration,packages&amp;#34;&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;ansible-operator run --ansible-args=&#39;--skip-tags &amp;quot;notification&amp;quot;&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ansible-runner will perform the task relevant to the command specified by the user in the &lt;code&gt;---ansible-args&lt;/code&gt; flag.&lt;/p&gt;
&lt;h2 id=&#34;using-ansible-vault&#34;&gt;Using Ansible-Vault&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.ansible.com/ansible/latest/user_guide/vault.html&#34;&gt;Ansible Vault&lt;/a&gt; allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plaintext in playbooks or roles. You can specify Ansible-Vault file via an arbitrary argument by using the &lt;code&gt;--ansible-args&lt;/code&gt; flag. For example, let&amp;rsquo;s assume that a playbook reads in a file &lt;code&gt;vars.yml&lt;/code&gt; which contains an encrypted text and stores it in a variable &lt;code&gt;secret&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
- name: Playbook to print debug messages
  hosts: localhost
  tasks:
    - name: Get the decrypted message variable
      include_vars:
        file: vars.yml
        name: secret
    - debug:
        msg: The decrypted value is {{secret.the_secret}}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, let&amp;rsquo;s also assume that we have a password file, &lt;code&gt;pwd.yml&lt;/code&gt;, that contains the password to decrypt the encrypted text. Then, by running the command &lt;code&gt;ansible-operator run --ansible-args=&#39;--vault-password-file /absolute/path/to/pwd.yml&#39;&lt;/code&gt; the operator will read in the encrypted text from the file and perform decryption using the password stored in the &lt;code&gt;pwd.yml&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--------------------------- Ansible Task StdOut -------------------------------

 TASK [debug] ******************************** 
ok: [localhost] =&amp;gt; {
    &amp;quot;msg&amp;quot;: &amp;quot;The decrypted value is DECRYPTED-TEST-VALUE&amp;quot;
}

-------------------------------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;using-ansible-log-events&#34;&gt;Using Ansible Log Events&lt;/h2&gt;
&lt;p&gt;Using the &lt;code&gt;--ansible-log-events&lt;/code&gt; CLI flag, you can determine to what degree the Ansible task logs will be outputted. The flag can take any of the following values:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Nothing&lt;/code&gt; - No tasks or task-related logs will be outputted.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Tasks&lt;/code&gt; - Only Ansible Tasks will be outputted.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Everything&lt;/code&gt; - All info logs and all tasks will be outputted.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you want more control over the logs that are outputted, consider using the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/website/content/en/docs/building-operators/golang/references/logging.md#default-zap-logger&#34;&gt;Zap Logger&lt;/a&gt; and &lt;a href=&#34;https://sdk.operatorframework.io/docs/building-operators/ansible/reference/advanced_options/#ansible-verbosity&#34;&gt;verbosity annotations&lt;/a&gt; in tandem with the &lt;code&gt;--ansible-log-events&lt;/code&gt; CLI flag.&lt;/p&gt;
&lt;h2 id=&#34;ansiblesdkoperatorframeworkioreconcile-period-custom-resource-annotation&#34;&gt;&lt;code&gt;ansible.sdk.operatorframework.io/reconcile-period&lt;/code&gt; Custom Resource Annotation&lt;/h2&gt;
&lt;p&gt;You can specify the reconcile period for an Ansible Operator by adding the ansible.sdk.operatorframework.io/reconcile-period key to the custom resource annotations.
This feature specifies the maximum interval in which a cluster will get reconciled, and defaults to 10 hours if not manually set. If changes are detected in the desired state, the cluster may be reconciled sooner than the specified interval.&lt;/p&gt;
&lt;p&gt;The reconcile period can be specified in the custom resource&amp;rsquo;s annotations in the following manner:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached-sample&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ansible.sdk.operatorframework.io/reconcile-period&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;5s&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The key only accepts a value in the &lt;code&gt;h/m/s&lt;/code&gt; format, such as &lt;code&gt;1h2m4s&lt;/code&gt;, &lt;code&gt;3m0s&lt;/code&gt;, or &lt;code&gt;4s&lt;/code&gt;. Values such as &lt;code&gt;1x3m9s&lt;/code&gt; are invalid.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Alternatively, you can specify the reconcile period for Ansible-based Operators in the following ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using the &lt;code&gt;--reconcile-period&lt;/code&gt; command-line flag&lt;/li&gt;
&lt;li&gt;Using the &amp;lsquo;reconcilePeriod&amp;rsquo; key in the &lt;code&gt;watches.yaml&lt;/code&gt; file
You should not use all three methods to specify a single reconcile period. If all three methods are used simultaneously, the order of precedence is as follows: Custom resource annotations &amp;gt; &lt;code&gt;watches.yaml&lt;/code&gt; file &amp;gt; command-line flag.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Ansible Operator Base Images</title>
      <link>/docs/building-operators/ansible/reference/ansible-base-images/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/ansible-base-images/</guid>
      <description>
        
        
        &lt;p&gt;Ansible-based operators are built on top of base images built for use
with the Operator-SDK.&lt;/p&gt;
&lt;h2 id=&#34;ansible-versions&#34;&gt;Ansible Versions&lt;/h2&gt;
&lt;p&gt;For Operator-SDK versions &amp;gt; &lt;code&gt;v1.30.0&lt;/code&gt; the &lt;code&gt;quay.io/operator-framework/ansible-operator&lt;/code&gt;
base image has been updated to use Ansible 2.15. The Ansible 2.11 preview base image
has been removed and will no longer be built/supported past Operator-SDK &lt;code&gt;v1.30&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For Operator-SDK versions &amp;lt;= &lt;code&gt;v1.30.0&lt;/code&gt;, the below information applies:&lt;/p&gt;
&lt;p&gt;There have been some major changes in the Ansible ecosystem, primarily
the addition of &lt;code&gt;collections&lt;/code&gt; and the removal of these libraries from
Ansible core. Ansible 2.9 is the last release of the &amp;ldquo;old way&amp;rdquo;, with
forward compatibility for collections. This is the version officially
supported by the Operator-SDK.&lt;/p&gt;
&lt;p&gt;Ansible 2.10 was a transition release, and it is NOT recommended for use
with operators.&lt;/p&gt;
&lt;p&gt;Ansible 2.11 is the future, and Operator-SDK will eventually provide only 2.11 images. Currently, 2.11 base images are in tech-preview.
See: &lt;a href=&#34;https://quay.io/repository/operator-framework/ansible-operator-2.11-preview&#34;&gt;ansible-operator-2.11-preview&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;changing-ansible-operator-base-images&#34;&gt;Changing Ansible Operator Base Images&lt;/h2&gt;
&lt;p&gt;For Operator-SDK versions &amp;gt; &lt;code&gt;v1.30.0&lt;/code&gt; - Operators are scaffolded with
the latest version of the base image (using Ansible 2.15). The base image
name is the same as previous versions of the Operator-SDK.&lt;/p&gt;
&lt;p&gt;For Operator-SDK versions &amp;lt;= &lt;code&gt;v1.30.0&lt;/code&gt;, the below information applies:&lt;/p&gt;
&lt;p&gt;Operators are scaffolded with the latest version of the base image
(using Ansible 2.9) in the first line of the operator Dockerfile.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;FROM quay.io/operator-framework/ansible-operator:v1.16&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Operator authors who want to try out 2.11 can simply replace their FROM with:
&lt;code&gt;FROM quay.io/operator-framework/ansible-operator-2.11-preview:v1.16&lt;/code&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Dependent Watches</title>
      <link>/docs/building-operators/ansible/reference/dependent-watches/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/dependent-watches/</guid>
      <description>
        
        
        &lt;p&gt;This document describes the &lt;code&gt;watchDependentResources&lt;/code&gt; option in &lt;a href=&#34;#example&#34;&gt;&lt;code&gt;watches.yaml&lt;/code&gt;&lt;/a&gt; file. It delves into what dependent resources are, why the option is required, how it is achieved and finally gives an example.&lt;/p&gt;
&lt;h3 id=&#34;what-are-dependent-resources&#34;&gt;What are dependent resources?&lt;/h3&gt;
&lt;p&gt;In most cases, an operator creates a bunch of Kubernetes resources in the cluster, that helps deploy and manage the application. For instance, the &lt;a href=&#34;https://github.com/coreos/etcd-operator/blob/master/doc/gif/demo.gif&#34;&gt;etcd-operator&lt;/a&gt; creates two services and a number of pods for a single &lt;code&gt;EtcdCluster&lt;/code&gt; CR. In this case, all the Kubernetes resources created by the operator for a CR is defined as dependent resources.&lt;/p&gt;
&lt;h3 id=&#34;why-the-watchdependentresources-option&#34;&gt;Why the &lt;code&gt;watchDependentResources&lt;/code&gt; option?&lt;/h3&gt;
&lt;p&gt;Often, an operator needs to watch dependent resources. To achieve this, a developer would set the field, &lt;code&gt;watchDependentResources&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt; in the &lt;code&gt;watches.yaml&lt;/code&gt; file. If enabled, a change in a dependent resource will trigger the reconciliation loop causing Ansible code to run.&lt;/p&gt;
&lt;p&gt;For example, since the &lt;em&gt;etcd-operator&lt;/em&gt; needs to ensure that all the pods are up and running, it needs to know when a pod changes. Enabling the dependent watches option would trigger the reconciliation loop to run. The Ansible logic needs to handle these cases and make sure that all the dependent resources are in the desired state as declared by the &lt;code&gt;CR spec&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Note: By default it is enabled when using ansible-operator&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;how-is-this-achieved&#34;&gt;How is this achieved?&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;ansible-operator&lt;/code&gt; base image achieves this by leveraging the concept of &lt;a href=&#34;https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/&#34;&gt;owner-references&lt;/a&gt;. Whenever a Kubernetes resource is created by Ansible code, the &lt;code&gt;ansible-operator&lt;/code&gt;&#39;s &lt;code&gt;proxy&lt;/code&gt; module injects &lt;code&gt;owner-references&lt;/code&gt; into the resource being created. The &lt;code&gt;owner-references&lt;/code&gt; means the resource is owned by the CR for which reconciliation is taking place.&lt;/p&gt;
&lt;p&gt;Whenever the &lt;code&gt;watchDependentResources&lt;/code&gt; field is enabled, the &lt;code&gt;ansible-operator&lt;/code&gt; will watch all the resources owned by the CR, registering callbacks to their change events. Upon a change, the callback will enqueue a &lt;code&gt;ReconcileRequest&lt;/code&gt; for the CR. The enqueued reconciliation request will trigger the &lt;code&gt;Reconcile&lt;/code&gt; function of the controller which will execute the ansible logic for reconciliation.&lt;/p&gt;
&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;p&gt;This is an example of a watches file with the &lt;code&gt;watchDependentResources&lt;/code&gt; field set to &lt;code&gt;True&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;AppService&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;maxRunnerArtifacts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;30&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;reconcilePeriod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;5s&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;manageStatus&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;False&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;watchDependentResources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;True&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Documentation</title>
      <link>/docs/contribution-guidelines/documentation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/contribution-guidelines/documentation/</guid>
      <description>
        
        
        &lt;p&gt;If a contribution changes the user interface or existing APIs it must include new or updated documentation.
Since the operator-sdk repository does not expose many public packages, documentation mostly comes in the form of our website&amp;rsquo;s &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/website/content/en/docs&#34;&gt;markdown docs&lt;/a&gt;.
Good &lt;a href=&#34;https://blog.golang.org/godoc&#34;&gt;godocs&lt;/a&gt; are expected nonetheless.&lt;/p&gt;
&lt;p&gt;Likewise a &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/changelog/fragments/00-template.yaml&#34;&gt;changelog fragment&lt;/a&gt; should be added containing a summary of the change and optionally a migration guide.&lt;/p&gt;
&lt;h2 id=&#34;testing-docs-changes&#34;&gt;Testing docs changes&lt;/h2&gt;
&lt;p&gt;This document discusses how to visually inspect documentation changes as they would be applied
to the live website. All changes to documentation should be inspected locally before being pushed
to a PR.&lt;/p&gt;
&lt;h3 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;The docs are built with &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; which can be installed along with the
required extensions by following the &lt;a href=&#34;https://www.docsy.dev/docs/get-started/other-options/#prerequisites-and-installation&#34;&gt;docsy install guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Note: Be sure to install hugo-extended.&lt;/p&gt;
&lt;p&gt;We use &lt;code&gt;git submodules&lt;/code&gt; to install the docsy theme. From the
&lt;code&gt;operator-sdk&lt;/code&gt; directory, update the submodules to install the theme.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git submodule update --init --recursive
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;build-and-serve&#34;&gt;Build and Serve&lt;/h3&gt;
&lt;p&gt;You can build and serve your docs to &lt;code&gt;localhost:1313&lt;/code&gt;. From the &lt;code&gt;website/&lt;/code&gt;
directory run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;hugo server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Any changes will be included in real time.&lt;/p&gt;
&lt;h3 id=&#34;check-docs&#34;&gt;Check Docs&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;make test-docs&lt;/code&gt; will validate changelog fragments, build doc HTML in a container, and check its links.
Please consider running this locally before creating a PR to save CI resources.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Ansible Operator Finalizers</title>
      <link>/docs/building-operators/ansible/reference/finalizers/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/finalizers/</guid>
      <description>
        
        
        &lt;p&gt;The default behavior of an Ansible Operator is to delete all resources the operator
created during reconciliation when a managed resource is marked for deletion. This
behavior is usually sufficient for applications that exist only in Kubernetes, but
sometimes it is necessary to perform more complex operations (for example, when
your action performed against a third party API needs to be undone). These more
complex cases can still be handled by Ansible Operator, through the use of a &lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#finalizers&#34;&gt;finalizer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finalizers allow controllers (such as an Ansible Operator) to implement asynchronous pre-delete hooks.
This allows custom logic to run after a resource has been marked for deletion, but
before the resource has actually been deleted from the Kubernetes cluster.
For Ansible Operator, this hook takes the form of an Ansible playbook or role. You can
define the mapping from your finalizer to a playbook or role by simply setting the
&lt;code&gt;finalizer&lt;/code&gt; field on the entry in your &lt;code&gt;watches.yaml&lt;/code&gt;. You can also choose to re-run
your top-level playbook or role with different variables set. The &lt;code&gt;watches.yaml&lt;/code&gt;
finalizer configuration accepts the following options:&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;/docs/building-operators/ansible/reference/watches/&#34;&gt;Ansible watches documentation&lt;/a&gt; for more information.&lt;/p&gt;
&lt;h4 id=&#34;name&#34;&gt;name&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;name&lt;/code&gt; is required.&lt;/p&gt;
&lt;p&gt;This is the name of the finalizer. This is basically an arbitrary string, the existence
of any finalizer string on a resource will prevent that resource from being deleted until
the finalizer is removed. Ansible Operator will remove this string from the list of
finalizers on successful execution of the specified role or playbook. A typical finalizer
will be &lt;code&gt;&amp;lt;qualified-group&amp;gt;/finalizer&lt;/code&gt;, where &lt;code&gt;&amp;lt;qualified-group&amp;gt;&lt;/code&gt; is the fully qualified group
of the resource being managed.&lt;/p&gt;
&lt;h4 id=&#34;playbook&#34;&gt;playbook&lt;/h4&gt;
&lt;p&gt;One of &lt;code&gt;playbook&lt;/code&gt;, &lt;code&gt;role&lt;/code&gt;, or &lt;code&gt;vars&lt;/code&gt; must be provided. If &lt;code&gt;playbook&lt;/code&gt; is not provided, it
will default to the playbook specified at the top level of the &lt;code&gt;watches.yaml&lt;/code&gt;
entry.&lt;/p&gt;
&lt;p&gt;This field is identical to the top-level &lt;code&gt;playbook&lt;/code&gt; field. It requires an absolute
path to a playbook on the operator’s file system.&lt;/p&gt;
&lt;h4 id=&#34;role&#34;&gt;role&lt;/h4&gt;
&lt;p&gt;One of &lt;code&gt;playbook&lt;/code&gt;, &lt;code&gt;role&lt;/code&gt;, or &lt;code&gt;vars&lt;/code&gt; must be provided. If &lt;code&gt;role&lt;/code&gt; is not provided, it
will default to the role specified at the top level of the [&lt;code&gt;watches.yaml&lt;/code&gt;][watches] entry.&lt;/p&gt;
&lt;p&gt;This field is identical to the top-level &lt;code&gt;role&lt;/code&gt; field.&lt;/p&gt;
&lt;h4 id=&#34;vars&#34;&gt;vars&lt;/h4&gt;
&lt;p&gt;One of &lt;code&gt;playbook&lt;/code&gt;, &lt;code&gt;role&lt;/code&gt;, or &lt;code&gt;vars&lt;/code&gt; must be provided.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;vars&lt;/code&gt; is an arbitrary map of key-value pairs. The contents of &lt;code&gt;vars&lt;/code&gt; will be passed as &lt;code&gt;extra_vars&lt;/code&gt; to the
playbook or role specified in the finalizer block, or at the top-level if neither &lt;code&gt;playbook&lt;/code&gt;
or &lt;code&gt;role&lt;/code&gt; was set for the finalizer.&lt;/p&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;Here are a few examples of &lt;code&gt;watches.yaml&lt;/code&gt; files that specify a finalizer:&lt;/p&gt;
&lt;h3 id=&#34;run-top-level-playbook-or-role-with-new-variables&#34;&gt;Run top-level playbook or role with new variables&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Database&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;/opt/ansible/playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;finalizer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com/finalizer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;vars&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;state&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;absent&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This example will run &lt;code&gt;playbook.yml&lt;/code&gt; when the Custom Resource
is deleted. Because &lt;code&gt;vars&lt;/code&gt; is set, the playbook will be run with &lt;code&gt;state&lt;/code&gt; set to &lt;code&gt;absent&lt;/code&gt;. Inside the playbook,
the author can check this value and perform whatever cleanup is necessary.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Database&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;database&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;finalizer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com/finalizer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;vars&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;state&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;absent&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This example is nearly identical to the first, except it will run the &lt;code&gt;/opt/ansible/roles/database&lt;/code&gt;
role, rather than a playbook, with the &lt;code&gt;state&lt;/code&gt; variable set to &lt;code&gt;absent&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;run-a-different-playbook-or-role&#34;&gt;Run a different playbook or role&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Database&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;finalizer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com/finalizer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;teardown_database&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This example will run the &lt;code&gt;/opt/ansible/roles/teardown_database&lt;/code&gt; role when the Custom Resource is deleted.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Database&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;finalizer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com/finalizer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;destroy.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This example will run the &lt;code&gt;/opt/ansible/destroy.yml&lt;/code&gt; playbook when the Custom Resource is deleted.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Database&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;finalizer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com/finalizer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;myNamespace.myCollection.myRole&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This example will run the &lt;code&gt;myRole&lt;/code&gt; when the Custom Resource is deleted. (The collection must have been installed.)&lt;/p&gt;
&lt;h3 id=&#34;run-a-different-playbook-or-role-with-vars&#34;&gt;Run a different playbook or role with vars&lt;/h3&gt;
&lt;p&gt;You can set &lt;code&gt;playbook&lt;/code&gt; or &lt;code&gt;role&lt;/code&gt; and &lt;code&gt;vars&lt;/code&gt; at the same time. This can be useful if only a small
part of your logic handles interacting with the component that requires cleanup. Rather than
run all the logic again, you can specify only to run the role or playbook that handled the
interaction, with a different variable set.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Database&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;finalizer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com/finalizer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;manage_credentials&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;vars&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;state&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;revoked&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For this example, assume our application configures automated backups to a third party service.
On deletion, all we want to do is revoke the credentials used to backup the data. We run
just the &lt;code&gt;/opt/ansible/roles/manage_credentials&lt;/code&gt; role, which is imported by our playbook to
create the credentials in the first place, but we pass the &lt;code&gt;state: revoked&lt;/code&gt; option, which
causes the role to invalidate our credentials. For everything else in our application,
automatic deletion of dependent resources will be sufficient, so we can exit successfully and
let the operator remove our finalizer and allow the resource to be deleted.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Generating Manifests and Metadata</title>
      <link>/docs/olm-integration/generation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/generation/</guid>
      <description>
        
        
        &lt;p&gt;This document describes how to manage packaging and shipping your Operator in the following stages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Generate your first release&lt;/strong&gt; - encapsulate the metadata needed to install your Operator with the
&lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager&#34;&gt;Operator Lifecycle Manager&lt;/a&gt; and configure the permissions it needs from the generated SDK files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update your Operator&lt;/strong&gt; - apply any updates to Operator manifests made during development.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Upgrade your Operator&lt;/strong&gt; - carry over any customizations you have made and ensure a rolling update to the
next version of your Operator.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Several &lt;code&gt;operator-sdk&lt;/code&gt; subcommands manage operator-framework manifests and metadata,
in particular &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/0.15.1/doc/design/building-your-csv.md&#34;&gt;&lt;code&gt;ClusterServiceVersion&lt;/code&gt;&#39;s (CSVs)&lt;/a&gt;, for an Operator: &lt;a href=&#34;/docs/cli/operator-sdk_generate_bundle&#34;&gt;&lt;code&gt;generate bundle&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;/docs/cli/operator-sdk_generate_kustomize_manifests&#34;&gt;&lt;code&gt;generate kustomize manifests&lt;/code&gt;&lt;/a&gt;.
See this &lt;a href=&#34;/docs/olm-integration/cli-overview&#34;&gt;CLI overview&lt;/a&gt; for details on each command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The packagemanifests format is deprecated and support will be removed in &lt;code&gt;operator-sdk&lt;/code&gt; v2.0.0.&lt;/p&gt;
&lt;h3 id=&#34;kustomize-files&#34;&gt;Kustomize files&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;operator-sdk generate kustomize manifests&lt;/code&gt; generates a CSV kustomize base
&lt;code&gt;config/manifests/bases/&amp;lt;project-name&amp;gt;.clusterserviceversion.yaml&lt;/code&gt; and a &lt;code&gt;config/manifests/kustomization.yaml&lt;/code&gt;
by default. These files are required as &lt;code&gt;kustomize build&lt;/code&gt; input in downstream commands.&lt;/p&gt;
&lt;p&gt;By default, the command starts an interactive prompt if a CSV base in &lt;code&gt;config/manifests/bases&lt;/code&gt; is not present
to collect &lt;a href=&#34;#csv-fields&#34;&gt;UI metadata&lt;/a&gt;. You can disable the interactive prompt by passing &lt;code&gt;--interactive=false&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk generate kustomize manifests
INFO[0000] Generating CSV manifest version 0.1.0

Display name for the operator (required):
&amp;gt; memcached

Comma-separated list of keywords for your operator (required):
&amp;gt; app, operator
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once this base is written, you may modify any of the fields labeled &lt;em&gt;user&lt;/em&gt; in the &lt;a href=&#34;#csv-fields&#34;&gt;fields section&lt;/a&gt; below.
These values will persist when generating a bundle, so make necessary metadata changes here and not the generated bundle.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Go Operators only:&lt;/strong&gt; the command parses &lt;a href=&#34;/docs/building-operators/golang/references/markers&#34;&gt;CSV markers&lt;/a&gt; from Go API type definitions, located
in &lt;code&gt;./api&lt;/code&gt; for single group projects and &lt;code&gt;./apis&lt;/code&gt; for multigroup projects, to populate certain CSV fields.
You can set an alternative path to the API types root directory with &lt;code&gt;--apis-dir&lt;/code&gt;. These markers are not available
to Ansible or Helm project types.&lt;/p&gt;
&lt;p&gt;The command attempts to process the local types defined in your API.
If you import a package that uses the same name as a local type, running the command causes an infinite loop. For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;PodStatus&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;SomeField&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;
  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// imported type with the same name will infinitely trigger
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// the parser to process the local PodStatus type
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodStatus&lt;/span&gt; 
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To prevent an infinite loop, edit the local type definition to use a different name. For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;PodStatusWrapper&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;SomeField&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodStatus&lt;/span&gt; 
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;clusterserviceversion-manifests&#34;&gt;ClusterServiceVersion manifests&lt;/h3&gt;
&lt;p&gt;CSV&amp;rsquo;s are manifests that define all aspects of an Operator, from what CustomResourceDefinitions (CRDs) it uses to
metadata describing the Operator&amp;rsquo;s maintainers. They are typically versioned by semver, much like Operator projects
themselves; this version is present in both their &lt;code&gt;metadata.name&lt;/code&gt; and &lt;code&gt;spec.version&lt;/code&gt; fields. The CSV generator called
by &lt;code&gt;generate &amp;lt;bundle|packagemanifests&amp;gt;&lt;/code&gt; requires certain input manifests to construct a CSV manifest; all inputs
are read when either command is invoked, along with a CSV&amp;rsquo;s &lt;a href=&#34;#kustomize-files&#34;&gt;base&lt;/a&gt;, to idempotently regenerate a CSV.&lt;/p&gt;
&lt;p&gt;The following resource kinds are typically included in a CSV, which are addressed by &lt;code&gt;config/manifests/kustomization.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Role&lt;/code&gt;: define Operator permissions within a namespace.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ClusterRole&lt;/code&gt;: define cluster-wide Operator permissions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Deployment&lt;/code&gt;: define how the Operator&amp;rsquo;s operand is run in pods.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ValidatingWebhookConfiguration&lt;/code&gt;, &lt;code&gt;MutatingWebhookConfiguration&lt;/code&gt;: configures webhooks for your manager to handle.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CustomResourceDefinition&lt;/code&gt;: definitions of custom objects your Operator reconciles.&lt;/li&gt;
&lt;li&gt;Custom resource examples: examples of objects adhering to the spec of a particular CRD.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can optionally specify an input &lt;code&gt;ClusterServiceVersion&lt;/code&gt; manifest to the set of manifests passed to
these &lt;code&gt;generate&lt;/code&gt; subcommands instead of having them read from the &lt;a href=&#34;#kustomize-files&#34;&gt;base path&lt;/a&gt;.
This is advantageous for those who would like to take full advantage of &lt;code&gt;kustomize&lt;/code&gt; for their base.
All fields unlabeled or labeled with &lt;em&gt;marker&lt;/em&gt; &lt;a href=&#34;#csv-fields&#34;&gt;below&lt;/a&gt; will be overwritten by these command,
so make sure you do not &lt;code&gt;kustomize build&lt;/code&gt; those fields!&lt;/p&gt;
&lt;h4 id=&#34;webhooks&#34;&gt;Webhooks&lt;/h4&gt;
&lt;p&gt;A CSV allows you to &lt;a href=&#34;https://olm.operatorframework.io/docs/advanced-tasks/adding-admission-and-conversion-webhooks&#34;&gt;define&lt;/a&gt; both &lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/&#34;&gt;admission&lt;/a&gt; and &lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#webhook-conversion&#34;&gt;conversion&lt;/a&gt; webhooks
at &lt;a href=&#34;https://pkg.go.dev/github.com/operator-framework/api/pkg/operators/v1alpha1#WebhookDefinition&#34;&gt;&lt;code&gt;spec.webhookdefinitions&lt;/code&gt;&lt;/a&gt;. The &lt;code&gt;generate &amp;lt;bundle|packagemanifests&amp;gt;&lt;/code&gt; commands, described below,
will automatically add webhooks to your CSV if the following holds true:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A webhook configuration must be associated with a &lt;code&gt;Service&lt;/code&gt; by name and namespace,
whether in a &lt;a href=&#34;https://pkg.go.dev/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1?utm_source=godoc#ServiceReference&#34;&gt;CRD&lt;/a&gt; or in a &lt;a href=&#34;https://pkg.go.dev/k8s.io/api/admissionregistration/v1?utm_source=godoc#ServiceReference&#34;&gt;&lt;code&gt;*WebhookConfiguration&lt;/code&gt;&lt;/a&gt; file,&lt;/li&gt;
&lt;li&gt;The associated &lt;code&gt;Service&lt;/code&gt; must expose one &lt;code&gt;spec.ports[*].targetPort&lt;/code&gt; that matches both &lt;code&gt;containerPort&lt;/code&gt;
and &lt;code&gt;protocol&lt;/code&gt; of one element in the Operator &lt;code&gt;Deployment&lt;/code&gt;&#39;s &lt;code&gt;spec.template.spec.containers[*].ports&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By default, the manager&amp;rsquo;s Deployment is configured to mount a volume containing TLS cert data
created by [cert-manager][cert-manager] into the manager&amp;rsquo;s container.
OLM does &lt;a href=&#34;https://olm.operatorframework.io/docs/advanced-tasks/adding-admission-and-conversion-webhooks/#certificate-authority-requirements&#34;&gt;not yet support cert-manager&lt;/a&gt;, so a &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/163c657/testdata/go/v3/memcached-operator/config/manifests/kustomization.yaml#L12&#34;&gt;JSON patch&lt;/a&gt; was added
to remove this volume and mount such that OLM can itself create and manage certs for your Operator.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note (for Go Operators only):&lt;/strong&gt; If targeting OLM &amp;lt; v0.17.0, the manager&amp;rsquo;s default webhook server
is not configured with the correct cert/key paths; the correct path is
&lt;code&gt;/apiserver.local.config/certificates/apiserver.{cert,key}&lt;/code&gt;.
To cover this case, make the following changes to your &lt;code&gt;main.go&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/webhook&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;main&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Configure a webhook.Server with the correct path and file names.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// If webhookServer is nil, which will be the case of OLM &amp;gt;= 0.17 is available,
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// the manager will create a server for you using Host, Port,
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// and the default CertDir, KeyName, and CertName.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;webhookServer&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;webhook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Server&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;legacyOLMCertDir&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;/apiserver.local.config/certificates&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;os&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Stat&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;legacyOLMCertDir&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;IsDir&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;webhookServer&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;webhook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Server&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;Host&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;     &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;some&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;host&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;,&lt;/span&gt; &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Set this only if normally set in ctrl.Options below.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;      &lt;span style=&#34;color:#000&#34;&gt;Port&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;     &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;some&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;port&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;,&lt;/span&gt; &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Set this only if normally set in ctrl.Options below.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;      &lt;span style=&#34;color:#000&#34;&gt;CertDir&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#000&#34;&gt;legacyOLMCertDir&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;CertName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;apiserver.crt&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;KeyName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;apiserver.key&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

  &lt;span style=&#34;color:#000&#34;&gt;mgr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NewManager&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GetConfigOrDie&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(),&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Options&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;Host&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;some&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;host&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;Port&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;some&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;port&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;WebhookServer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;webhookServer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Host/Port will not be used if webhookServer is nil.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
 
  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Now you can register webhooks.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;Service&lt;/code&gt; itself will still be placed into the &lt;code&gt;manifests/&lt;/code&gt; directory,
in case other Operator resources require routing. Feel free to remove it otherwise.&lt;/p&gt;
&lt;h2 id=&#34;generate-your-first-release&#34;&gt;Generate your first release&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ve recently run &lt;code&gt;operator-sdk init&lt;/code&gt; and created your APIs with &lt;code&gt;operator-sdk create api&lt;/code&gt;. Now you&amp;rsquo;d like to
package your Operator for deployment by OLM. Your Operator is at version &lt;code&gt;v0.0.1&lt;/code&gt;; the &lt;code&gt;Makefile&lt;/code&gt; variable &lt;code&gt;VERSION&lt;/code&gt;
should be set to &lt;code&gt;0.0.1&lt;/code&gt;. You&amp;rsquo;ve also built your operator image, &lt;code&gt;example.com/memcached-operator:v0.0.1&lt;/code&gt;;
if this image tag does not match yours, swap in the correct one in the docs below.&lt;/p&gt;
&lt;h3 id=&#34;bundle-format&#34;&gt;Bundle format&lt;/h3&gt;
&lt;p&gt;A &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle&lt;/a&gt; consists of manifests (CSV, CRDs, and other supported kinds) and metadata that define an Operator
at a particular version, and an optional &lt;a href=&#34;/docs/testing-operators/scorecard/&#34;&gt;scorecard&lt;/a&gt; configuration file. You may have also heard of a
bundle image. From the bundle docs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An Operator Bundle is built as a scratch (non-runnable) container image that
contains operator manifests and specific metadata in designated directories
inside the image. Then, it can be pushed and pulled from an OCI-compliant
container registry. Ultimately, an operator bundle will be used by Operator
Registry and OLM to install an operator in OLM-enabled clusters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At this stage in your Operator&amp;rsquo;s development, we only need to worry about generating bundle files;
bundle images become important once you&amp;rsquo;re ready to &lt;a href=&#34;https://operatorhub.io/&#34;&gt;publish&lt;/a&gt; your Operator.&lt;/p&gt;
&lt;p&gt;SDK projects are scaffolded with a &lt;code&gt;Makefile&lt;/code&gt; containing the &lt;code&gt;bundle&lt;/code&gt; recipe by default,
which wraps &lt;code&gt;generate kustomize manifests&lt;/code&gt;, &lt;code&gt;generate bundle&lt;/code&gt;, and other related commands.&lt;/p&gt;
&lt;p&gt;By default &lt;code&gt;make bundle&lt;/code&gt; will generate a CSV, copy CRDs and other supported kinds, generate metadata,
and add your scorecard configuration in the bundle format:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle
$ tree ./bundle
./bundle
├── manifests
│   ├── cache.example.com_memcacheds.yaml
│   ├── memcached-operator.clusterserviceversion.yaml
│   ├── memcached-operator-controller-manager-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml
│   ├── memcached-operator-controller-manager-metrics-service_v1_service.yaml
│   ├── memcached-operator-metrics-reader_rbac.authorization.k8s.io_v1beta1_clusterrole.yaml
│   └── memcached-operator-webhook-service_v1_service.yaml
├── metadata
│   └── annotations.yaml
└── tests
    └── scorecard
        └── config.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; bundle generation is supposed to be idempotent, so any changes to CSV fields able to be persisted
(marked &lt;em&gt;(user)&lt;/em&gt; or &lt;em&gt;(marker)&lt;/em&gt; &lt;a href=&#34;#csv-fields&#34;&gt;below&lt;/a&gt;) must be made to the base set of manifests, typically found in &lt;code&gt;config/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Bundle metadata in &lt;code&gt;bundle/metadata/annotations.yaml&lt;/code&gt; contains information about a particular Operator version
available in a registry. OLM uses this information to install specific Operator versions and resolve dependencies.
That file and &lt;code&gt;bundle.Dockerfile&lt;/code&gt; contain the same &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.12.6/docs/design/operator-bundle.md#bundle-annotations&#34;&gt;annotations&lt;/a&gt;, the latter as &lt;code&gt;LABEL&lt;/code&gt;s,
which do not need to be modified in most cases; if you do decide to modify them, both sets of annotations &lt;em&gt;must&lt;/em&gt;
be the same to ensure consistent Operator deployment.&lt;/p&gt;
&lt;h5 id=&#34;channels&#34;&gt;Channels&lt;/h5&gt;
&lt;p&gt;Metadata for each bundle contains channel information as well:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Channels allow package authors to write different upgrade paths for different users (e.g. beta vs. stable).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Channels become important when publishing, but we should still be aware of them beforehand as they&amp;rsquo;re required
values in our metadata. &lt;code&gt;make bundle&lt;/code&gt; writes the channel &lt;code&gt;alpha&lt;/code&gt; by default.&lt;/p&gt;
&lt;h4 id=&#34;validation&#34;&gt;Validation&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;bundle&lt;/code&gt; recipe includes a call to &lt;code&gt;operator-sdk bundle validate&lt;/code&gt;, which runs a set of required object
validators on your bundle that ensure both its format and content meet the &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle specification&lt;/a&gt;.
These will always be run and cannot be disabled.&lt;/p&gt;
&lt;p&gt;You may also have added &lt;a href=&#34;#csv-fields&#34;&gt;CSV fields&lt;/a&gt; containing useful UI metadata for cluster console display,
and want to ensure that metadata matches some hosted catalog&amp;rsquo;s submission requirements.
The &lt;code&gt;bundle validate&lt;/code&gt; command supports optional validators that can validate these bundle metadata.
These validators are disabled by default, and can be selectively enabled with &lt;code&gt;--select-optional &amp;lt;label-selector&amp;gt;&lt;/code&gt;.
You can list all available optional validators by setting the &lt;code&gt;--list-optional&lt;/code&gt; flag:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk bundle validate --list-optional
NAME           LABELS                                                DESCRIPTION
operatorhub    name=operatorhub                                      OperatorHub.io metadata validation. 
               suite=operatorframework    
community      name=community                                        (stage: alpha) Community Operator bundle validation      
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For example, you want to turn on the &lt;code&gt;operatorhub&lt;/code&gt; validator shown above so you can publish the &lt;code&gt;0.0.1&lt;/code&gt; operator
you recently created on &lt;a href=&#34;https://operatorhub.io/&#34;&gt;OperatorHub.io&lt;/a&gt;. To do so, you can modify your Makefile&amp;rsquo;s &lt;code&gt;bundle&lt;/code&gt; recipe
to validate any further changes you make to bundle UI metadata related to OperatorHub requirements:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;bundle&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:&lt;/span&gt; ...
  ...
  operator-sdk bundle validate ./bundle --select-optional &lt;span style=&#34;color:#000&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;operatorhub
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Also, see that you can test the bundle against the suite of test to ensure it against all criteria:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk bundle validate ./bundle --select-optional &lt;span style=&#34;color:#000&#34;&gt;suite&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;operatorframework 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The &lt;code&gt;OperatorHub.io&lt;/code&gt; validator in the &lt;code&gt;operatorframework&lt;/code&gt; optional suite allows you to validate that your manifests can work with a Kubernetes cluster of a particular version using the &lt;code&gt;k8s-version&lt;/code&gt; optional key value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk bundle validate ./bundle --select-optional &lt;span style=&#34;color:#000&#34;&gt;suite&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;operatorframework --optional-values&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;k8s-version&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;1.22
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Documentation on optional validators:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://olm.operatorframework.io/docs/tasks/creating-operator-bundle/#validating-your-bundle&#34;&gt;&lt;code&gt;operatorhub&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: (stage: alpha) The &lt;code&gt;Community&lt;/code&gt; validator allows you to validate your &lt;code&gt;bundle.Dockerfile&lt;/code&gt; configuration against its specific criteria using the &lt;code&gt;image-path&lt;/code&gt; optional key value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk bundle validate ./bundle --select-optional &lt;span style=&#34;color:#000&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;community --optional-values&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;image-path&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;bundle.Dockerfile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;package-manifests-format&#34;&gt;Package manifests format&lt;/h3&gt;
&lt;p&gt;A [package manifests][package-manifests] format consists of on-disk manifests (CSV, CRDs and other supported kinds)
and metadata that define an Operator at all versions of that Operator. Each version is contained in its own directory,
with a parent package manifest YAML file containing channel-to-version mappings, much like a bundle&amp;rsquo;s metadata.&lt;/p&gt;
&lt;p&gt;If your Operator is already formatted as a package manifests and you do not wish to migrate to the bundle format yet,
you should add the following to your &lt;code&gt;Makefile&lt;/code&gt; to make development easier:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Go-based Operator projects&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Options for &amp;#34;packagemanifests&amp;#34;.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;ifneq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;FROM_VERSION&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;undefined)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_FROM_VERSION&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --from-version&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;FROM_VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;ifneq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;CHANNEL&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;undefined)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_CHANNELS&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --channel&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;CHANNEL&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;ifeq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;IS_CHANNEL_DEFAULT&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;1)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_IS_DEFAULT_CHANNEL&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --default-channel
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_MAN_OPTS&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;?=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_FROM_VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_CHANNELS&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_IS_DEFAULT_CHANNEL&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Generate package manifests.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;packagemanifests&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;kustomize&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;manifests&lt;/span&gt;
  operator-sdk generate kustomize manifests -q
  &lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; config/manager &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;KUSTOMIZE&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; edit &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; image &lt;span style=&#34;color:#000&#34;&gt;controller&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;IMG&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;KUSTOMIZE&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; build config/manifests &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; operator-sdk generate packagemanifests -q --version &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_MAN_OPTS&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;For Helm/Ansible-based Operator projects&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Options for &amp;#34;packagemanifests&amp;#34;.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;ifneq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;FROM_VERSION&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;undefined)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_FROM_VERSION&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --from-version&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;FROM_VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;ifneq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;CHANNEL&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;undefined)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_CHANNELS&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --channel&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;CHANNEL&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;ifeq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;IS_CHANNEL_DEFAULT&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;1)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_IS_DEFAULT_CHANNEL&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --default-channel
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_MAN_OPTS&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;?=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_FROM_VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_CHANNELS&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_IS_DEFAULT_CHANNEL&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Generate package manifests.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;packagemanifests&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;kustomize&lt;/span&gt;
  operator-sdk generate kustomize manifests -q
  &lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; config/manager &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;KUSTOMIZE&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; edit &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; image &lt;span style=&#34;color:#000&#34;&gt;controller&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;IMG&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;KUSTOMIZE&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; build config/manifests &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; operator-sdk generate packagemanifests -q --version &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_MAN_OPTS&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By default &lt;code&gt;make packagemanifests&lt;/code&gt; will generate a CSV, a package manifest file, and copy CRDs in the package manifests format:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make packagemanifests IMG=example.com/memcached-operator:v0.0.1
$ tree ./packagemanifests
./packagemanifests
├── 0.0.1
│   ├── cache.my.domain_memcacheds.yaml
│   └── memcached-operator.clusterserviceversion.yaml
└── memcached-operator.package.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;update-your-operator&#34;&gt;Update your Operator&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s say you added a new API &lt;code&gt;App&lt;/code&gt; with group &lt;code&gt;app&lt;/code&gt; and version &lt;code&gt;v1alpha1&lt;/code&gt; to your Operator project,
and added a port to your manager Deployment in &lt;code&gt;config/manager/manager.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If using a bundle format, the current version of your CSV can be updated by running:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle IMG=example.com/memcached-operator:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If using a package manifests format, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make packagemanifests IMG=example.com/memcached-operator:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Running the command for either format will append your new CRD to &lt;code&gt;spec.customresourcedefinitions.owned&lt;/code&gt;,
replace the old data at &lt;code&gt;spec.install.spec.deployments&lt;/code&gt; with your updated Deployment,
and update your existing CSV manifest. The SDK will not overwrite &lt;a href=&#34;#csv-fields&#34;&gt;user-defined&lt;/a&gt;
fields like &lt;code&gt;spec.maintainers&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;upgrade-your-operator&#34;&gt;Upgrade your Operator&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s say you&amp;rsquo;re upgrading your Operator to version &lt;code&gt;v0.0.2&lt;/code&gt;, you&amp;rsquo;ve already updated the &lt;code&gt;VERSION&lt;/code&gt; variable
in your &lt;code&gt;Makefile&lt;/code&gt; to &lt;code&gt;0.0.2&lt;/code&gt;, and built a new operator image &lt;code&gt;example.com/memcached-operator:v0.0.2&lt;/code&gt;.
You also want to add a new channel &lt;code&gt;beta&lt;/code&gt;, and use it as the default channel.&lt;/p&gt;
&lt;p&gt;First, update &lt;code&gt;spec.replaces&lt;/code&gt; in your &lt;a href=&#34;#kustomize-files&#34;&gt;base CSV manifest&lt;/a&gt; to the &lt;em&gt;current&lt;/em&gt; CSV name.
In this case, the change would look like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;replaces&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached-operator.v0&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;.0.1&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, upgrade your bundle. If using a bundle format, a new version of your CSV can be created by running:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle CHANNELS=beta DEFAULT_CHANNEL=beta IMG=example.com/memcached-operator:v0.0.2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If using a package manifests format, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make packagemanifests FROM_VERSION=0.0.1 CHANNEL=beta IS_CHANNEL_DEFAULT=1 IMG=example.com/memcached-operator:v0.0.2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Running the command for either format will persist user-defined fields, and updates &lt;code&gt;spec.version&lt;/code&gt; and &lt;code&gt;metadata.name&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For &lt;code&gt;packagemanifests&lt;/code&gt; only&lt;/strong&gt; The command will also populate &lt;code&gt;spec.replaces&lt;/code&gt; with the old CSV version&amp;rsquo;s name.&lt;/p&gt;
&lt;h2 id=&#34;csv-fields&#34;&gt;CSV fields&lt;/h2&gt;
&lt;p&gt;Below are two lists of fields: the first is a list of all fields the SDK and OLM expect in a CSV, and the second are optional.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Go Operators only:&lt;/strong&gt; Several fields require user input (labeled &lt;em&gt;user&lt;/em&gt;) or a &lt;a href=&#34;/docs/building-operators/golang/references/markers&#34;&gt;CSV marker&lt;/a&gt;
(labeled &lt;em&gt;marker&lt;/em&gt;). This list may change as the SDK becomes better at generating CSV&amp;rsquo;s.
These markers are not available to Ansible or Helm project types.&lt;/p&gt;
&lt;p&gt;Required:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;metadata.name&lt;/code&gt; _(user*)_: a *unique* name for this CSV of the format &lt;code&gt;&amp;lt;project-name&amp;gt;.vX.Y.Z&lt;/code&gt;, ex. &lt;code&gt;app-operator.v0.0.1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.displayName&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a name to display for the Operator in Operator Hub.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.version&lt;/code&gt; _(user*)_: semantic version of the Operator, ex. &lt;code&gt;0.0.1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.installModes&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: what mode of &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/4197455/Documentation/design/building-your-csv.md#operator-metadata&#34;&gt;installation namespacing&lt;/a&gt; OLM should use.
Currently all but &lt;code&gt;MultiNamespace&lt;/code&gt; are supported by SDK Operators.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.customresourcedefinitions&lt;/code&gt;: any CRDs the Operator uses. Certain fields in elements of &lt;code&gt;owned&lt;/code&gt; will be filled by the SDK.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;owned&lt;/code&gt;: all CRDs the Operator deploys itself from it&amp;rsquo;s bundle.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt;: CRD&amp;rsquo;s &lt;code&gt;metadata.name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kind&lt;/code&gt;: CRD&amp;rsquo;s &lt;code&gt;spec.names.kind&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;version&lt;/code&gt;: CRD&amp;rsquo;s &lt;code&gt;spec.version&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;description&lt;/code&gt; &lt;em&gt;(marker)&lt;/em&gt; : description of the CRD.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;displayName&lt;/code&gt; &lt;em&gt;(marker)&lt;/em&gt; : display name of the CRD.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;resources&lt;/code&gt; &lt;em&gt;(marker)&lt;/em&gt; : any Kubernetes resources used by the CRD, ex. &lt;code&gt;Pod&lt;/code&gt;&#39;s and &lt;code&gt;ConfigMap&lt;/code&gt;&#39;s.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;specDescriptors&lt;/code&gt; &lt;em&gt;(marker)&lt;/em&gt; : UI hints for inputs and outputs of the Operator&amp;rsquo;s spec.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;statusDescriptors&lt;/code&gt; &lt;em&gt;(marker)&lt;/em&gt; : UI hints for inputs and outputs of the Operator&amp;rsquo;s status.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;actionDescriptors&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : UI hints for an Operator&amp;rsquo;s in-cluster actions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;required&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : all CRDs the Operator expects to be present in-cluster, if any.
All &lt;code&gt;required&lt;/code&gt; element fields must be populated manually.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Optional:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;spec.description&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a thorough description of the Operator&amp;rsquo;s functionality.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.keywords&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a list of keywords describing the Operator.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.maintainers&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a list of human or organizational entities maintaining the Operator, with a &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.provider&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : the Operator provider, with a &lt;code&gt;name&lt;/code&gt;; usually an organization.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.labels&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a list of &lt;code&gt;key:value&lt;/code&gt; pairs to be used by Operator internals.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;metadata.annotations.alm-examples&lt;/code&gt;: CR examples, in JSON string literal format, for your CRD&amp;rsquo;s. Ideally one per CRD.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;metadata.annotations.capabilities&lt;/code&gt;: level of Operator capability. See the &lt;a href=&#34;/docs/overview/operator-capabilities/&#34;&gt;Operator maturity model&lt;/a&gt;
for a list of valid values.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.replaces&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: the name of the CSV being replaced by this CSV.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.links&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a list of URL&amp;rsquo;s to websites, documentation, etc. pertaining to the Operator or application
being managed, each with a &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;url&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.selector&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : selectors by which the Operator can pair resources in a cluster.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.icon&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a base64-encoded icon unique to the Operator, set in a &lt;code&gt;base64data&lt;/code&gt; field with a &lt;code&gt;mediatype&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.maturity&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: the Operator&amp;rsquo;s maturity, ex. &lt;code&gt;alpha&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.minKubeVersion&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: the minimal Kubernetes version supported by the Operator, ex. &lt;code&gt;1.16.0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.webhookdefinitions&lt;/code&gt;: any webhooks the Operator uses.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.relatedImages&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: a list of image tags containing SHA digests &lt;a href=&#34;https://pkg.go.dev/github.com/operator-framework/api@v0.8.1/pkg/operators/v1alpha1#RelatedImage&#34;&gt;mapped to in-CSV names&lt;/a&gt;
that your Operator might require to perform their functions.
&lt;ul&gt;
&lt;li&gt;To get the correct tag for an image available in some remote registry, run &lt;code&gt;docker inspect --format=&#39;{{range $i, $d := .RepoDigests}}{{$d}}{{&amp;quot;\n&amp;quot;}}{{end}}&#39;&lt;/code&gt;
and choose the tag for the desired registry.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.skips&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: the names of one or more CSVs that should be skipped in a catalog&amp;rsquo;s upgrade graph.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;*&lt;/strong&gt; &lt;code&gt;metadata.name&lt;/code&gt; and &lt;code&gt;spec.version&lt;/code&gt; will only be automatically updated from the base CSV
when you set &lt;code&gt;--version&lt;/code&gt; when running &lt;code&gt;generate &amp;lt;bundle|packagemanifests&amp;gt;&lt;/code&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Information Flow for Operator SDK Ansible-based Operators</title>
      <link>/docs/building-operators/ansible/reference/information-flow-ansible-operator/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/information-flow-ansible-operator/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img src=&#34;/ao-flow.png&#34; alt=&#34;Ansible Operator Flow&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;controllerreconciler&#34;&gt;Controller/Reconciler&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Gets the primary resource based on NamespacedName this uses the cache from controller runtime.&lt;/li&gt;
&lt;li&gt;Determines if the resource is deleted based on the existence of a finalizer and a metadata.DeletionTimeStamp.
&lt;ul&gt;
&lt;li&gt;If deleted and not one of our finalizers we exit with no error.&lt;/li&gt;
&lt;li&gt;If finalizer is needed, but is not on the object, and is not deleted then add it and continue.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Marks the status of the CR as running if it is managing the status and continues&lt;/li&gt;
&lt;li&gt;Creates the proxy’s kubeconfig.&lt;/li&gt;
&lt;li&gt;Calls out Runner using the runner package.&lt;/li&gt;
&lt;li&gt;Watches for events to come back across the results channel.
&lt;ul&gt;
&lt;li&gt;Logs the events&lt;/li&gt;
&lt;li&gt;Keeps track of failure messages as well as the StatusEvent, which is the ending event that the Ansible sends to mark the playbook/role is completed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If a finalizer exists and the resource was deleted then remove the finalizer and update the object and continue.&lt;/li&gt;
&lt;li&gt;Update the status of the resource to mark that the run has completed&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;runner-package&#34;&gt;Runner Package&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Create the socket that ansible will communicate over&lt;/li&gt;
&lt;li&gt;Translate object.Spec -&amp;gt; ansible vars (camelCase -&amp;gt; camel_case) and adds them as parameters for the ansible-runner directory.&lt;/li&gt;
&lt;li&gt;Create the directory on disk for ansible runner. or update the files on disk if they already exist.&lt;/li&gt;
&lt;li&gt;Run the ansible runner command in a go routine, when this exits close the channel for the socket.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;the-proxy&#34;&gt;The Proxy&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Every request to the k8s api goes through the proxy.&lt;/li&gt;
&lt;li&gt;The owner reference is injected into the object that is being created in the same namespace as the CR.&lt;/li&gt;
&lt;li&gt;The operator-sdk annotations are injected into the object that is being created outside of namepsace of the CR.&lt;/li&gt;
&lt;li&gt;The proxy then adds dependent watches for the correct controller if we have not started watching the type already.&lt;/li&gt;
&lt;li&gt;On a GET, we attempt to use the informer cache to get the resource. This will also attempt to re-add dependent watches if we find a type with an owner reference.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ansible-runner&#34;&gt;Ansible Runner&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ansible is run and has its own process.&lt;/li&gt;
&lt;li&gt;Ansible-runner-http package allows runner to set us ansible events as ansible is being run. ansible runner uses the socket and the controller is watching the events as they come through the channel.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Logging</title>
      <link>/docs/building-operators/golang/references/logging/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/golang/references/logging/</guid>
      <description>
        
        
        &lt;h1 id=&#34;overview&#34;&gt;Overview&lt;/h1&gt;
&lt;p&gt;Operator SDK-generated operators use the &lt;a href=&#34;https://pkg.go.dev/github.com/go-logr/logr&#34;&gt;&lt;code&gt;logr&lt;/code&gt;&lt;/a&gt; interface to log. This log interface has several backends such as &lt;a href=&#34;https://pkg.go.dev/github.com/go-logr/zapr&#34;&gt;&lt;code&gt;zap&lt;/code&gt;&lt;/a&gt;, which the SDK uses in generated code by default. &lt;a href=&#34;https://pkg.go.dev/github.com/go-logr/logr#Logger&#34;&gt;&lt;code&gt;logr.Logger&lt;/code&gt;&lt;/a&gt; exposes structured logging methods that help create machine-readable logs and adding a wealth of information to log records.&lt;/p&gt;
&lt;h2 id=&#34;default-zap-logger&#34;&gt;Default zap logger&lt;/h2&gt;
&lt;p&gt;Operator SDK uses a &lt;code&gt;zap&lt;/code&gt;-based &lt;code&gt;logr&lt;/code&gt; backend when scaffolding new projects. To assist with configuring and using this logger, the SDK includes several helper functions.&lt;/p&gt;
&lt;p&gt;In the simple example below, we add the zap flagset to the operator&amp;rsquo;s command line flags with &lt;code&gt;BindFlags()&lt;/code&gt;, and then set the controller-runtime logger with &lt;code&gt;zap.Options{}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;By default, &lt;code&gt;zap.Options{}&lt;/code&gt; will return a logger that is ready for production use. It uses a JSON encoder, logs starting at the &lt;code&gt;info&lt;/code&gt; level. To customize the default behavior, users can use the zap flagset and specify flags on the command line. The zap flagset includes the following flags that can be used to configure the logger:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--zap-devel&lt;/code&gt;: Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn)
Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--zap-encoder&lt;/code&gt;: Zap log encoding (&amp;lsquo;json&amp;rsquo; or &amp;lsquo;console&amp;rsquo;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--zap-log-level&lt;/code&gt;: Zap Level to configure the verbosity of logging. Can be one of &amp;lsquo;debug&amp;rsquo;, &amp;lsquo;info&amp;rsquo;, &amp;lsquo;error&amp;rsquo;,
or any integer value &amp;gt; 0 which corresponds to custom debug levels of increasing verbosity&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--zap-stacktrace-level&lt;/code&gt;: Zap Level at and above which stacktraces are captured (one of &amp;lsquo;info&amp;rsquo; or &amp;lsquo;error&amp;rsquo;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Consult the controller-runtime &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/log/zap#Options.BindFlags&#34;&gt;godocs&lt;/a&gt; for more detailed flag information.&lt;/p&gt;
&lt;h3 id=&#34;a-simple-example&#34;&gt;A simple example&lt;/h3&gt;
&lt;p&gt;Operators set the logger for all operator logging in &lt;code&gt;main.go&lt;/code&gt;. To illustrate how this works, try out this simple example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;main&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
	&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/log/zap&amp;#34;&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;logf&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/log&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;globalLog&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;logf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;WithName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;global&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;main&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Add the zap logger flag set to the CLI. The flag set must
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// be added before calling flag.Parse().
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;zap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Options&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;BindFlags&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;flag&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;CommandLine&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;flag&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Parse&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt;

	&lt;span style=&#34;color:#000&#34;&gt;logger&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;zap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;New&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;zap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;UseFlagOptions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;))&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;logf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SetLogger&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;logger&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

	&lt;span style=&#34;color:#000&#34;&gt;scopedLog&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;logf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;WithName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;scoped&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

	&lt;span style=&#34;color:#000&#34;&gt;globalLog&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Printing at INFO level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;globalLog&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;V&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Printing at DEBUG level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;scopedLog&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Printing at INFO level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;scopedLog&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;V&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Printing at DEBUG level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;output-using-the-defaults&#34;&gt;Output using the defaults&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ go run main.go
INFO[0000] Running the operator locally in namespace default.
{&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1587741740.407766,&amp;quot;logger&amp;quot;:&amp;quot;global&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;Printing at INFO level&amp;quot;}
{&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1587741740.407855,&amp;quot;logger&amp;quot;:&amp;quot;scoped&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;Printing at INFO level&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;output-overriding-the-log-level-to-1-debug&#34;&gt;Output overriding the log level to 1 (debug)&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ go run main.go --zap-log-level=debug
INFO[0000] Running the operator locally in namespace default.
{&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1587741837.602911,&amp;quot;logger&amp;quot;:&amp;quot;global&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;Printing at INFO level&amp;quot;}
{&amp;quot;level&amp;quot;:&amp;quot;debug&amp;quot;,&amp;quot;ts&amp;quot;:1587741837.602964,&amp;quot;logger&amp;quot;:&amp;quot;global&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;Printing at DEBUG level&amp;quot;}
{&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1587741837.6029708,&amp;quot;logger&amp;quot;:&amp;quot;scoped&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;Printing at INFO level&amp;quot;}
{&amp;quot;level&amp;quot;:&amp;quot;debug&amp;quot;,&amp;quot;ts&amp;quot;:1587741837.602973,&amp;quot;logger&amp;quot;:&amp;quot;scoped&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;Printing at DEBUG level&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;custom-zap-logger&#34;&gt;Custom zap logger&lt;/h2&gt;
&lt;p&gt;In order to use a custom zap logger, &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime/tree/master/pkg/log/zap&#34;&gt;&lt;code&gt;zap&lt;/code&gt;&lt;/a&gt; from controller-runtime can be utilized to wrap it in a &lt;code&gt;logr&lt;/code&gt; implementation.&lt;/p&gt;
&lt;p&gt;Below is an example illustrating the use of &lt;a href=&#34;https://github.com/jsternberg/zap-logfmt&#34;&gt;&lt;code&gt;zap-logfmt&lt;/code&gt;&lt;/a&gt; in logging.&lt;/p&gt;
&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;p&gt;In your &lt;code&gt;main.go&lt;/code&gt; file, replace the current implementation for logs inside the &lt;code&gt;main&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Add the zap logger flag set to the CLI. The flag set must
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// be added before calling flag.Parse().
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;zap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Options&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;BindFlags&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;flag&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;CommandLine&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;flag&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Parse&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt;

	&lt;span style=&#34;color:#000&#34;&gt;logger&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;zap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;New&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;zap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;UseFlagOptions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;opts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;))&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;logf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SetLogger&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;logger&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
	&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;zaplogfmt&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;github.com/sykesm/zap-logfmt&amp;#34;&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;uzap&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;go.uber.org/zap&amp;#34;&lt;/span&gt;
	&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;go.uber.org/zap/zapcore&amp;#34;&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;logf&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/log&amp;#34;&lt;/span&gt;
	&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/log/zap&amp;#34;&lt;/span&gt;
	&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;configLog&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;uzap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NewProductionEncoderConfig&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;configLog&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;EncodeTime&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ts&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;time&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Time&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;encoder&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;zapcore&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PrimitiveArrayEncoder&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;encoder&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;AppendString&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;UTC&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;().&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Format&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;time&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;RFC3339Nano&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;))&lt;/span&gt;
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;logfmtEncoder&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;zaplogfmt&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NewEncoder&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;configLog&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Construct a new logr.logger.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#000&#34;&gt;logger&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;zap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;New&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;zap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;UseDevMode&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;zap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;WriteTo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;os&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Stdout&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;zap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Encoder&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;logfmtEncoder&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;))&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;logf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SetLogger&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;logger&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: For this example, you will need to add the module &lt;code&gt;&amp;quot;github.com/sykesm/zap-logfmt&amp;quot;&lt;/code&gt; to your project. Run &lt;code&gt;go get -u github.com/sykesm/zap-logfmt&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;output-using-custom-zap-logger&#34;&gt;Output using custom zap logger&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ go run main.go
ts=2020-04-30T20:35:59.551268Z level=info logger=global msg=&amp;quot;Printing at INFO level&amp;quot;
ts=2020-04-30T20:35:59.551314Z level=debug logger=global msg=&amp;quot;Printing at DEBUG level&amp;quot;
ts=2020-04-30T20:35:59.551318Z level=info logger=scoped msg=&amp;quot;Printing at INFO level&amp;quot;
ts=2020-04-30T20:35:59.55132Z level=debug logger=scoped msg=&amp;quot;Printing at DEBUG level&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By using &lt;code&gt;sigs.k8s.io/controller-runtime/pkg/log&lt;/code&gt;, your logger is propagated through &lt;code&gt;controller-runtime&lt;/code&gt;. Any logs produced by &lt;code&gt;controller-runtime&lt;/code&gt; code will be through your logger, and therefore have the same formatting and destination.&lt;/p&gt;
&lt;h3 id=&#34;setting-flags-when-running-locally&#34;&gt;Setting flags when running locally&lt;/h3&gt;
&lt;p&gt;When running locally with &lt;code&gt;make run ENABLE_WEBHOOKS=false&lt;/code&gt;, you can use the &lt;code&gt;ARGS&lt;/code&gt; var to pass additional flags to your operator, including the zap flags. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make run ARGS=&amp;quot;--zap-encoder=console&amp;quot; ENABLE_WEBHOOKS=false
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Make sure to have your &lt;code&gt;run&lt;/code&gt; target to take &lt;code&gt;ARGS&lt;/code&gt; as shown below in &lt;code&gt;Makefile&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-makefile&#34; data-lang=&#34;makefile&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Run against the configured Kubernetes cluster in ~/.kube/config
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;run&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;manifests&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;generate&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;fmt&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;vet&lt;/span&gt;
	go run ./main.go &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;ARGS&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;setting-flags-when-deploying-to-a-cluster&#34;&gt;Setting flags when deploying to a cluster&lt;/h3&gt;
&lt;p&gt;When deploying your operator to a cluster you can set additional flags using an &lt;code&gt;args&lt;/code&gt; array in your operator&amp;rsquo;s &lt;code&gt;container&lt;/code&gt; spec in the file &lt;code&gt;config/default/manager_metrics_patch.yaml&lt;/code&gt; For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;op&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;add&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;path&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;/spec/template/spec/containers/&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;/args/&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;--zap-log-level=debug&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; 
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;op&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;add&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;path&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;/spec/template/spec/containers/&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;/args/&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;--zap-encoder=console&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;creating-a-structured-log-statement&#34;&gt;Creating a structured log statement&lt;/h2&gt;
&lt;p&gt;There are two ways to create structured logs with &lt;code&gt;logr&lt;/code&gt;. You can create new loggers using &lt;code&gt;log.WithValues(keyValues)&lt;/code&gt; that include &lt;code&gt;keyValues&lt;/code&gt;, a list of key-value pair &lt;code&gt;interface{}&lt;/code&gt;&#39;s, in each log record. Alternatively you can include &lt;code&gt;keyValues&lt;/code&gt; directly in a log statement, as all &lt;code&gt;logr&lt;/code&gt; log statements take some message and &lt;code&gt;keyValues&lt;/code&gt;. The signature of &lt;code&gt;logr.Error()&lt;/code&gt; has an &lt;code&gt;error&lt;/code&gt;-type parameter, which can be &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;An example from &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/v1.2.0/testdata/go/memcached-operator/controllers/memcached_controller.go&#34;&gt;&lt;code&gt;memcached_controller.go&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Go&#34; data-lang=&#34;Go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;ctrllog&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/log&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;


&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// MemcachedReconciler reconciles a Memcached object
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Client&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Log&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;logr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Logger&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;runtime&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Scheme&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MemcachedReconciler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Reconcile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Request&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrllog&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;FromContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Fetch the Memcached instance
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cachev1alpha1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;errors&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;IsNotFound&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
			&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Request object not found, could have been deleted after reconcile request.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;			&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;			&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Return and don&amp;#39;t requeue
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;			&lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Memcached resource not found. Ignoring since object must be deleted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
			&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
		&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Error reading the object - requeue the request.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Failed to get Memcached&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
		&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Check if the deployment already exists, if not create a new one
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#000&#34;&gt;found&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Deployment&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{}&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;types&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NamespacedName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;found&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;errors&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;IsNotFound&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Define a new deployment
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;deploymentForMemcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;memcached&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Creating a new Deployment&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Deployment.Namespace&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Deployment.Name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Create&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
		&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
			&lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Failed to create new Deployment&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Deployment.Namespace&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Deployment.Name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
			&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
		&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Deployment created successfully - return and requeue
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Requeue&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Failed to get Deployment&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
		&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

	&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Log records will look like the following (from &lt;code&gt;log.Error()&lt;/code&gt; above):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2020-04-27T09:14:15.939-0400	ERROR	controllers.Memcached	Failed to create new Deployment	{&amp;quot;memcached&amp;quot;: &amp;quot;default/memcached-sample&amp;quot;, &amp;quot;Deployment.Namespace&amp;quot;: &amp;quot;default&amp;quot;, &amp;quot;Deployment.Name&amp;quot;: &amp;quot;memcached-sample&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;non-default-logging&#34;&gt;Non-default logging&lt;/h2&gt;
&lt;p&gt;If you do not want to use &lt;code&gt;logr&lt;/code&gt; as your logging tool, you can remove &lt;code&gt;logr&lt;/code&gt;-specific statements without issue from your operator&amp;rsquo;s code, including the &lt;code&gt;logr&lt;/code&gt; setup code in &lt;code&gt;main.go&lt;/code&gt;, and add your own. Note that removing &lt;code&gt;logr&lt;/code&gt; setup code will prevent &lt;code&gt;controller-runtime&lt;/code&gt; from logging.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Internal Operator Metrics</title>
      <link>/docs/building-operators/ansible/reference/internal_metrics/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/internal_metrics/</guid>
      <description>
        
        
        &lt;p&gt;The Ansible Operator comes with three internal metrics that provide an insight to the frequency and time of operator reconciliations. These metrics can be
scraped by a Prometheus instance or any other openmetrics system. To publish operator metrics and scrape them with an openmetrics system such as Prometheus, view
&lt;a href=&#34;https://book.kubebuilder.io/reference/metrics.html&#34;&gt;Kubebuilder documentation&lt;/a&gt; on publishing metrics.&lt;/p&gt;
&lt;p&gt;The default metrics recorded in Operator SDK are collected in a &lt;a href=&#34;https://prometheus.io/docs/practices/histograms/&#34;&gt;histogram&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The following three metrics are derived from the histogram:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ansible_operator_reconciles_bucket&lt;/code&gt; - Each bucket in the histogram counts the number of reconciliations that have a period (in seconds) less than or equal
to the upper limit of the bucket.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ansible_operator_reconciles_count&lt;/code&gt; - The total number of reconciliations that have occurred up to that instance of time while running an Ansible operator.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ansible_operator_reconciles_sum&lt;/code&gt; - The cumulative amount of time (in seconds) of all reconciliations that have occurred up to that instance of time while
running an Ansible operator.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These metrics can be queried in the Prometheus UI.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://user-images.githubusercontent.com/37827279/123332879-f0fb2900-d4f5-11eb-87ea-7afd04f35b1c.png&#34; alt=&#34;Screen Shot 2021-06-24 at 2 10 28 PM&#34;&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Proxy Friendly Operators</title>
      <link>/docs/building-operators/ansible/reference/proxy-vars/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/proxy-vars/</guid>
      <description>
        
        
        &lt;p&gt;Proxy-friendly Operators should inspect their environment for the
standard proxy variables (&lt;code&gt;HTTPS_PROXY&lt;/code&gt;, &lt;code&gt;HTTP_PROXY&lt;/code&gt;, and &lt;code&gt;NO_PROXY&lt;/code&gt;)
and pass the values to Operands.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;start&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;proxy-test&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;job&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kubernetes.core.k8s&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;definition&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;batch/v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Job&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;env-job&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ ansible_operator_meta.namespace }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;template&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;              &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;curl-example&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;registry.access.redhat.com/ubi8/ubi&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;8.8&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;curl&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;http://example.com/job-request&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;HTTP_PROXY&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;{{ lookup(&amp;#34;env&amp;#34;, &amp;#34;HTTP_PROXY&amp;#34;) | default(&amp;#34;&amp;#34;, True) }}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;http_proxy&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;{{ lookup(&amp;#34;env&amp;#34;, &amp;#34;HTTP_PROXY&amp;#34;) | default(&amp;#34;&amp;#34;, True) }}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;restartPolicy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Never&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;backoffLimit&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can set the environment variable on the Operator deployment. Using the memcached tutorial, edit config/manager/manager.yaml:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;- --leader-elect&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;- --leader-election-id=ansible-proxy-demo&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;controller&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;latest&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;     &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;HTTP_PROXY&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;       &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;http_proxy_test&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Proxy Friendly Operators</title>
      <link>/docs/building-operators/golang/references/proxy-vars/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/golang/references/proxy-vars/</guid>
      <description>
        
        
        &lt;p&gt;Proxy-friendly Operators should inspect their environment for the
standard proxy variables (&lt;code&gt;HTTPS_PROXY&lt;/code&gt;, &lt;code&gt;HTTP_PROXY&lt;/code&gt;, and &lt;code&gt;NO_PROXY&lt;/code&gt;)
and pass the values to Operands.&lt;/p&gt;
&lt;p&gt;Operator-lib provides a helper function &lt;code&gt;proxy.ReadProxyVarsFromEnv&lt;/code&gt;
that does this inspection, all you need to do is append the
results to the Operand environments.&lt;/p&gt;
&lt;p&gt;Using the memcached tutorial as an example, add the following to the
Reconcile loop in &lt;code&gt;controllers/memcached_controller.go&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
   &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;github.com/operator-framework/operator-lib/proxy&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;


&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;i&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;container&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Template&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Containers&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Template&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;i&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;].&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Env&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;append&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;container&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;proxy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ReadProxyVarsFromEnv&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can set the environment variable on the Operator deployment. Using the memcached tutorial, edit config/manager/manager.yaml:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;- --leader-elect&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;- --leader-election-id=go-proxy-demo&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;controller&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;latest&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;     &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;HTTP_PROXY&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;       &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;http_proxy_test&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Proxy Friendly Operators</title>
      <link>/docs/building-operators/helm/reference/proxy-vars/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/helm/reference/proxy-vars/</guid>
      <description>
        
        
        &lt;p&gt;Proxy-friendly Operators should inspect their environment for the
standard proxy variables (&lt;code&gt;HTTPS_PROXY&lt;/code&gt;, &lt;code&gt;HTTP_PROXY&lt;/code&gt;, and &lt;code&gt;NO_PROXY&lt;/code&gt;)
and pass the values to Operands.&lt;/p&gt;
&lt;p&gt;This can be accomplished by modifying the &lt;code&gt;watches.yaml&lt;/code&gt; to include the
overrides based on an environment variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;demo.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Nginx&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;chart&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;helm-charts/nginx&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;overrideValues&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;proxy.http&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;$HTTP_PROXY&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;#+kubebuilder:scaffold:watch&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note: This example assumes that &lt;code&gt;proxy.http&lt;/code&gt; is included in your chart&amp;rsquo;s
&lt;code&gt;Values.yaml&lt;/code&gt;. The nginx tutorial does not have this value, but you can
add to the &lt;code&gt;helmcharts/nginx/Values.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;proxy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;https&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;no_proxy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You will also need to make sure the chart template supports the usage of
these values. Using the nginx tutorial, edit
&lt;code&gt;helm-charts/nginx/templates/deployment.yaml&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                                                                                                                                                                                                                             
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;{{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;.Chart.Name&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;}}&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                                                                                                                                                                                                             
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                                                                                                                                                                                                                    
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;{{- toYaml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;.Values.securityContext&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;|&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;nindent&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;12&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;}}&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                                                                                                                                                                                
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                                                                                                                                         
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;imagePullPolicy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;{{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;.Values.image.pullPolicy&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;}}&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                                                                                                                                                                                     
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                                                                                                                                                                                                                                
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;http_proxy&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;                                                                                                                                                                                                                
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ .Values.proxy.http }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can set the environment variable on the Operator deployment. Using
the nginx tutorial, edit &lt;code&gt;config/manager/manager.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;- --leader-elect&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;- --leader-election-id=helm-proxy-demo&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;controller&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;latest&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;     &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;HTTP_PROXY&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;       &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;http_proxy_test&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Quickstart for Go-based Operators</title>
      <link>/docs/building-operators/golang/quickstart/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/golang/quickstart/</guid>
      <description>
        
        
        &lt;p&gt;This guide walks through an example of building a simple memcached-operator using tools and libraries provided by the Operator SDK.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Go through the &lt;a href=&#34;/docs/building-operators/golang/installation&#34;&gt;installation guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Make sure your user is authorized with &lt;code&gt;cluster-admin&lt;/code&gt; permissions.&lt;/li&gt;
&lt;li&gt;An accessible image registry for various operator images (ex. &lt;a href=&#34;https://hub.docker.com/signup&#34;&gt;hub.docker.com&lt;/a&gt;,
&lt;a href=&#34;https://quay.io/&#34;&gt;quay.io&lt;/a&gt;) and be logged in to your command line environment.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;example.com&lt;/code&gt; is used as the registry Docker Hub namespace in these examples.
Replace it with another value if using a different registry or namespace.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/olm-integration/cli-overview#private-bundle-and-catalog-image-registries&#34;&gt;Authentication and certificates&lt;/a&gt; if the registry is private or uses a custom CA.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;steps&#34;&gt;Steps&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Create a project directory for your project and initialize the project:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;mkdir memcached-operator
&lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; memcached-operator
operator-sdk init --domain example.com --repo github.com/example/memcached-operator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; If your local environment is Apple Silicon (&lt;code&gt;darwin/arm64&lt;/code&gt;) use the &lt;code&gt;go/v4&lt;/code&gt;
plugin which provides support for this platform by adding to the init subCommand the flag &lt;code&gt;--plugins=go/v4&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a simple Memcached API:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk create api --group cache --version v1alpha1 --kind Memcached --resource --controller
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Build and push your operator&amp;rsquo;s image:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make docker-build docker-push &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example.com/memcached-operator:v0.0.1&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;olm-deployment&#34;&gt;OLM deployment&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a href=&#34;/docs/olm-integration/tutorial-bundle/#enabling-olm&#34;&gt;OLM&lt;/a&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk olm install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Bundle your operator, then build and push the bundle image (defaults to &lt;code&gt;example.com/memcached-operator-bundle:v0.0.1&lt;/code&gt;):&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make bundle &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example.com/memcached-operator:v0.0.1&amp;#34;&lt;/span&gt;
make bundle-build bundle-push &lt;span style=&#34;color:#000&#34;&gt;BUNDLE_IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example.com/memcached-operator-bundle:v0.0.1&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Run your bundle. If your bundle image is hosted in a registry that is private and/or
has a custom CA, these &lt;a href=&#34;/docs/olm-integration/cli-overview#private-bundle-and-catalog-image-registries&#34;&gt;configuration steps&lt;/a&gt; must be complete.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk run bundle &amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Create a sample Memcached custom resource:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl apply -f config/samples/cache_v1alpha1_memcached.yaml
memcached.cache.example.com/memcached-sample created
&lt;/code&gt;&lt;/pre&gt;&lt;ol&gt;
&lt;li&gt;Uninstall the operator:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk cleanup memcached-operator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;direct-deployment&#34;&gt;Direct deployment&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Deploy your operator:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make deploy &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example.com/memcached-operator:v0.0.1&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Create a sample Memcached custom resource:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl apply -f config/samples/cache_v1alpha1_memcached.yaml
memcached.cache.example.com/memcached-sample created
&lt;/code&gt;&lt;/pre&gt;&lt;ol&gt;
&lt;li&gt;Uninstall the operator:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make undeploy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;run-locally-outside-the-cluster&#34;&gt;Run locally (outside the cluster)&lt;/h3&gt;
&lt;p&gt;This is recommended ONLY for development purposes&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Run the operator:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;make install run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;In a new terminal tab/window, create a sample Memcached custom resource:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ kubectl apply -f config/samples/cache_v1alpha1_memcached.yaml
memcached.cache.example.com/memcached-sample created
&lt;/code&gt;&lt;/pre&gt;&lt;ol&gt;
&lt;li&gt;Stop the operator by pressing &lt;code&gt;ctrl+c&lt;/code&gt; in the terminal tab or window the operator is running in&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Read the &lt;a href=&#34;/docs/building-operators/golang/tutorial/&#34;&gt;full tutorial&lt;/a&gt; for an in-depth walkthrough of building a Go operator.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Adding Owner References for Existing Resources</title>
      <link>/docs/building-operators/ansible/reference/retroactively-owned-resources/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/retroactively-owned-resources/</guid>
      <description>
        
        
        &lt;p&gt;Owner references are automatically injected &lt;code&gt;only during creation of resources&lt;/code&gt;. Enabling owner reference injection &lt;code&gt;will not update objects&lt;/code&gt;
created while &lt;a href=&#34;../advanced_options#owner-reference-injection&#34;&gt;owner reference injection is
disabled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This guide will demonstrate how to retroactively set owner references
for existing resources.&lt;/p&gt;
&lt;p&gt;A GET request to the owning resource will provide the necessary data to
construct an &lt;code&gt;ownerReference&lt;/code&gt; or an &lt;code&gt;annotation&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ kubectl get memcacheds.cache.example.com -o yaml&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example Response (Abbreviated):&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.example.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;example-memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;uid&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;2a94ff2b&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;-84e0&lt;/span&gt;-40ce-8b5e-2b7e4d2bc0e2&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;kubectl edit&lt;/code&gt; can be used to update the resources by hand. See below
for example &lt;code&gt;ownerReference&lt;/code&gt; and &lt;code&gt;annotations&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;for-objects-in-the-same-namespace-as-the-owner-cr&#34;&gt;For objects in the same namespace as the Owner (CR)&lt;/h2&gt;
&lt;p&gt;Dependent resources &lt;em&gt;within the same namespace as the owning CR&lt;/em&gt; are
tracked with the &lt;code&gt;ownerReference&lt;/code&gt; field.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ownerReference&lt;/code&gt; structure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;apiVersion: {group}/{version}&lt;/li&gt;
&lt;li&gt;kind: {kind}&lt;/li&gt;
&lt;li&gt;name: {metadata.name}&lt;/li&gt;
&lt;li&gt;uid: {metadata.uid}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example ownerReference:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;...(snip)&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ownerReferences&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.example.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;example-memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;uid&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ad834522-d9a5&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;-4841&lt;/span&gt;-beac-991ff3798c00&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;for-objects-which-are-not-in-the-same-namespace-as-the-owner-cr&#34;&gt;For objects which are NOT in the same namespace as the Owner (CR)&lt;/h2&gt;
&lt;p&gt;An &lt;code&gt;annotation&lt;/code&gt; is used instead of an &lt;code&gt;ownerReference&lt;/code&gt; if the dependent
resource is in a different namespace than the CR, or the dependent
resource is a cluster level resource.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;annotation&lt;/code&gt; structure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;operator-sdk/primary-resource: {metadata.namespace}/{metadata.name}&lt;/li&gt;
&lt;li&gt;operator-sdk/primary-resource-type: {kind}.{group}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: The &lt;code&gt;{group}&lt;/code&gt; can be found by splitting the &lt;code&gt;apiVersion&lt;/code&gt;
metadata of the CR, into &lt;code&gt;group&lt;/code&gt; and &lt;code&gt;version&lt;/code&gt;. As an example,
&lt;code&gt;apiVersion: cache.example.com/v1alpha1&lt;/code&gt; in the &lt;code&gt;config/samples&lt;/code&gt; directory
gives us the group &lt;code&gt;cache.example.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example Annotation:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;...(snip)&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;operator-sdk/primary-resource&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default/example-memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;operator-sdk/primary-resource-type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached.cache.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;migration-using-ansible-assets&#34;&gt;Migration using Ansible assets&lt;/h2&gt;
&lt;p&gt;If you have many resources to update, it may be easier to use the
following Ansible assets, which &lt;strong&gt;should be considered an example rather
than an officially supported workflow&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;To use these assets, create a &lt;code&gt;vars.yml&lt;/code&gt; as specified below and copy
&lt;code&gt;playbook.yml&lt;/code&gt; and &lt;code&gt;each_resource.yml&lt;/code&gt; into the same directory. Execute
the playbook with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ ansible-playbook -i localhost playbook.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;varsyml&#34;&gt;vars.yml&lt;/h3&gt;
&lt;p&gt;This file should be created by the user to configure the playbook, and
needs to contain:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;owning_resource
&lt;ul&gt;
&lt;li&gt;apiVersion&lt;/li&gt;
&lt;li&gt;kind&lt;/li&gt;
&lt;li&gt;name&lt;/li&gt;
&lt;li&gt;namespace&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;resources_to_own (list): For each resource, specify:
&lt;ul&gt;
&lt;li&gt;name&lt;/li&gt;
&lt;li&gt;namespace (if applicable)&lt;/li&gt;
&lt;li&gt;apiVersion&lt;/li&gt;
&lt;li&gt;kind&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;owning_resource&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.example.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;example-memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;resources_to_own&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;example-memcached-memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;apps/v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Deployment&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;example-memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Namespace&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;playbookyml&#34;&gt;playbook.yml&lt;/h3&gt;
&lt;p&gt;This file can be used as-is without user adjustments.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;hosts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;localhost&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;tasks&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Import&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;user&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;variables&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;include_vars&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;vars.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Retrieve&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;owning&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;resource&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kubernetes.core.k8s_info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;api_version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ owning_resource.apiVersion }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ owning_resource.kind }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ owning_resource.name }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ owning_resource.namespace }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;register&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;extra_owner_data&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Ensure&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;resources&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;are&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;owned&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;include_tasks&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;each_resource.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;loop&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ resources_to_own }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;vars&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;to_be_owned&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;{{ q(&amp;#34;kubernetes.core.k8s&amp;#34;,
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;          api_version=item.apiVersion,
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;          kind=item.kind,
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;          resource_name=item.name,
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;          namespace=item.namespace
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;        ).0 }}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;owner_reference&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ owning_resource.apiVersion }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ owning_resource.kind }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ owning_resource.name }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;uid&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ extra_owner_data.resources[0].metadata.uid }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;each_resourceyml&#34;&gt;&lt;code&gt;each_resource.yml&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This file can be used as-is without user adjustments.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Patch&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;resource&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;with&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;owner&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;reference&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;when&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- to_be_owned.metadata.namespace&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;is&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;defined&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- to_be_owned.metadata.namespace&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;==&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;owning_resource.namespace&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- (to_be_owned.metadata.ownerReferences&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;is&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;not&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;defined)&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;or&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;(owner_reference&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;not&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;in&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to_be_owned.metadata.ownerReferences)&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kubernetes.core.k8s&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;state&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;present&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;resource_definition&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ to_be_owned.apiVersion }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ to_be_owned.kind }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ to_be_owned.metadata.name }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ to_be_owned.metadata.namespace }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ownerReferences&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ (to_be_owned.metadata.ownerReferences | default([])) + [owner_reference] }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Patch&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;resource&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;with&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;owner&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;annotation&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;when&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to_be_owned.metadata.namespace&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;is&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;not&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;defined&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;or&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to_be_owned.metadata.namespace&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;!=&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;owning_resource.namespace&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kubernetes.core.k8s&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;state&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;present&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;resource_definition&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ to_be_owned.apiVersion }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ to_be_owned.kind }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ to_be_owned.metadata.name }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ to_be_owned.metadata.namespace | default(omit)}}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;operator-sdk/primary-resource&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ owning_resource.namespace }}/{{ owning_resource.name }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;operator-sdk/primary-resource-type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ owning_resource.kind }}.{{ owning_resource.apiVersion.split(&amp;#39;/&amp;#39;)[0] }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Ansible Based Operator Scaffolding</title>
      <link>/docs/building-operators/ansible/reference/scaffolding/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/scaffolding/</guid>
      <description>
        
        
        &lt;p&gt;A new Ansible operator project can be created using a command that looks like
the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;operator-sdk init --plugins ansible \
  --domain=my.domain \
  --group=apps --version=v1alpha1 --kind=AppService \
  --generate-playbook \
  --generate-role
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The new project directory has many generated folders and files. For further information check the &lt;a href=&#34;/docs/overview/project-layout&#34;&gt;Project Layout&lt;/a&gt; doc.&lt;/p&gt;
&lt;h2 id=&#34;the-deployment&#34;&gt;The Deployment&lt;/h2&gt;
&lt;p&gt;The default Deployment manifest generated for the operator can be found in the
&lt;code&gt;config/manager/manager.yaml&lt;/code&gt; file. By default, the Deployment is named as
&amp;lsquo;controller-manager&amp;rsquo;. It contains a single container named &amp;lsquo;manager&amp;rsquo;, and it
may pick up a sidecar patch from the &lt;code&gt;config/default&lt;/code&gt; directory. The
Deployment will create a single Pod.&lt;/p&gt;
&lt;p&gt;For the container in the Pod, there are a few things to note. The default
Deployment contains a placeholder for the container image to use, so you
cannot create a meaningful operator using the YAML file directly. To deploy
the operator, you will run &lt;code&gt;make deploy IMG=&amp;lt;IMG&amp;gt;&lt;/code&gt;. The image name and tag
are then patched using kustomize.&lt;/p&gt;
&lt;h3 id=&#34;the-volume-mount-path&#34;&gt;The Volume Mount Path&lt;/h3&gt;
&lt;p&gt;The default EmptyDir volume mounted at &lt;code&gt;/tmp/ansible-operator/runner&lt;/code&gt; is used
to serve the &lt;a href=&#34;https://ansible-runner.readthedocs.io/en/latest/intro.html#runner-input-directory-hierarchy&#34;&gt;input directory&lt;/a&gt; in ansible-runner&amp;rsquo;s terms.
The mount path can &lt;em&gt;NOT&lt;/em&gt; be changed to other paths, or else the Operator will
fail to communicate with ansible-runner.&lt;/p&gt;
&lt;h3 id=&#34;the-environment-variables&#34;&gt;The Environment Variables&lt;/h3&gt;
&lt;p&gt;You can customize the behavior of the Ansible operator by specifying the
environment variables for the container. Please refer to the
&lt;a href=&#34;https://docs.ansible.com/ansible/latest/reference_appendices/config.html#environment-variables&#34;&gt;Ansible Documentation&lt;/a&gt; for a list of environment variables that
can be used to tune the behavior of the Ansible engine.&lt;/p&gt;
&lt;p&gt;In addition to the Ansible environment variables, Operator SDK also support
some special environment variables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;WATCH_NAMESPACE&lt;/code&gt;: This is the namespace your operator will watch for resource
changes, i.e. resource create, update or delete operations. In the scaffolded
operator Deployment, this is set to the same namespace in which the
operator is deployed. This variable can be set to one of the following types
of values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&amp;lsquo;&#39;: An empty string means that the operator will watch all namespaces.
This is the default value if the &lt;code&gt;WATCH_NAMESPACE&lt;/code&gt; environment variable is
not set. It is especially useful for watching cluster-scoped resources.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;foo&lt;/code&gt;: The operator will watch the namespace named &lt;code&gt;foo&lt;/code&gt;.
This is the setting you will use if you are operating a namespaced resource
which is deployed into a specific namespace.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;foo,bar&lt;/code&gt;: The operator checks the value of the environment variable and
realizes that it is a comma-separated list. This means the operator will
watch for resources in each of the listed namespaces.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ANSIBLE_DEBUG_LOGS&lt;/code&gt;: A boolean value for toggling the Ansible output during
reconciliation. When set to True, the operator dumps the Ansible result into
its standard output.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ANSIBLE_ROLES_PATH&lt;/code&gt;: The parent path(s) for the Ansible roles. When there
are more than one path to set, you can use &amp;ldquo;:&amp;rdquo; to separate them. Given a
path &lt;code&gt;/opt/foo&lt;/code&gt; and a role name &lt;code&gt;bar&lt;/code&gt;, the Ansible operator will check if
the Ansible role can be found in either &lt;code&gt;/opt/foo/bar&lt;/code&gt; or
&lt;code&gt;/opt/foo/roles/bar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This value overrides the setting from the &lt;code&gt;ansible-roles-path&lt;/code&gt; flag.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ANSIBLE_COLLECTIONS_PATH&lt;/code&gt;: The base path for the Ansible collections which
defaults to &lt;code&gt;~/.ansible/collections&lt;/code&gt; or &lt;code&gt;/usr/share/ansible/collections&lt;/code&gt;
when &lt;code&gt;ANSIBLE_COLLECTIONS_PATH&lt;/code&gt; is not explicitly specified. When a fully
qualified collection name in the &lt;a href=&#34;/docs/building-operators/ansible/reference/watches/&#34;&gt;watches&lt;/a&gt; file, the Ansible
operator checks if the specified collection can found under the base path
that can be customized using this variable. Suppose you have
&lt;code&gt;ANSIBLE_COLLECTIONS_PATH&lt;/code&gt; set to &lt;code&gt;/foo&lt;/code&gt; and the fully qualified collection
name set to &lt;code&gt;example.com.bar&lt;/code&gt;, the Ansible operator searches for the roles
under &lt;code&gt;/foo/ansible_collections/example/com/roles/bar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This value takes precedence over the &lt;code&gt;--ansible-collections-path&lt;/code&gt; flag.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;MAX_CONCURRENT_RECONCILES_&amp;lt;kind&amp;gt;_&amp;lt;group&amp;gt;&lt;/code&gt;: This specifies the maximum number
of concurrent reconciliations for the operator. It defaults to the number of
CPUs. You can adjust this based on the cluster resources.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;WORKER_&amp;lt;kind&amp;gt;_&amp;lt;group&amp;gt;&lt;/code&gt;: &lt;strong&gt;Deprecated&lt;/strong&gt;. Use
&lt;code&gt;MAX_CONCURRENT_RECONCILES_&amp;lt;kind&amp;gt;_&amp;lt;group&amp;gt;&lt;/code&gt; instead.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ANSIBLE_VERBOSITY_&amp;lt;kind&amp;gt;_&amp;lt;group&amp;gt;&lt;/code&gt;: This is used to customize the verbosity
of the ansible-runner command. The default value is 2.
The value must be no less than  0 and no greater than 7.
This value takes precedence over the global &lt;code&gt;--ansible-verbosity&lt;/code&gt; flag,
and it can be overridden by the per-resource annotation named
&lt;code&gt;ansible.operator-sdk/verbosity&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Ansible Operator Watches</title>
      <link>/docs/building-operators/ansible/reference/watches/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/watches/</guid>
      <description>
        
        
        &lt;p&gt;The Watches file contains a list of mappings from custom resources, identified
by it&amp;rsquo;s Group, Version, and Kind, to an Ansible Role or Playbook. The Operator
expects this mapping file in a predefined location: &lt;code&gt;/opt/ansible/watches.yaml&lt;/code&gt;
These resources, as well as child resources (determined by owner references) will
be monitored for updates and cached.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;group&lt;/strong&gt;:  The group of the Custom Resource that you will be watching.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;version&lt;/strong&gt;:  The version of the Custom Resource that you will be watching.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kind&lt;/strong&gt;:  The kind of the Custom Resource that you will be watching.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;role&lt;/strong&gt; (default): Specifies a role to be executed. This field is mutually exclusive with the
&amp;ldquo;playbook&amp;rdquo; field. This field can be:
&lt;ul&gt;
&lt;li&gt;an absolute path to a role directory.&lt;/li&gt;
&lt;li&gt;a relative path within one of the directories specified by &lt;code&gt;ANSIBLE_ROLES_PATH&lt;/code&gt; environment variable or &lt;code&gt;ansible-roles-path&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;a relative path within the current working directory, which defaults to &lt;code&gt;/opt/ansible/roles&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;a fully qualified collection name of an installed Ansible collection. Ansible collections are installed to
&lt;code&gt;~/.ansible/collections&lt;/code&gt; or &lt;code&gt;/usr/share/ansible/collections&lt;/code&gt; by default. If they are installed elsewhere,
use the &lt;code&gt;ANSIBLE_COLLECTIONS_PATH&lt;/code&gt; environment variable or the &lt;code&gt;ansible-collections-path&lt;/code&gt; flag&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;playbook&lt;/strong&gt;: This is the playbook name that you have added to the
container. This playbook is expected to be simply a way to call roles. This
field is mutually exclusive with the &amp;ldquo;role&amp;rdquo; field. When running locally, the playbook is expected to be in the
current project directory.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vars&lt;/strong&gt;: This is an arbitrary map of key-value pairs. The contents will be
passed as &lt;code&gt;extra_vars&lt;/code&gt; to the playbook or role specified for this watch.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;reconcilePeriod&lt;/strong&gt; (optional): The maximum interval that the operator will wait before beginning another reconcile, even if no watched events are received. When an operator watches many resources, each reconcile can become expensive, and a low value here can actually reduce performance. Typically, this option should only be used in advanced use cases where &lt;code&gt;watchDependentResources&lt;/code&gt; is set to &lt;code&gt;False&lt;/code&gt;  and when is not possible to use the watch feature. E.g To manage external resources that don’t emit Kubernetes events. The format for the duration string is a sequence of decimal numbers, each with optional fraction and a unit suffix, such as &amp;ldquo;300ms&amp;rdquo;, &amp;ldquo;1.5h&amp;rdquo; or &amp;ldquo;2h45m&amp;rdquo;. Valid time units are &amp;ldquo;ns&amp;rdquo;, &amp;ldquo;us&amp;rdquo; (or &amp;ldquo;µs&amp;rdquo;), &amp;ldquo;ms&amp;rdquo;, &amp;ldquo;s&amp;rdquo;, &amp;ldquo;m&amp;rdquo;, &amp;ldquo;h&amp;rdquo;. Defaults to 10 hours.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;manageStatus&lt;/strong&gt; (optional): When true (default), the operator will manage
the status of the CR generically. Set to false, the status of the CR is
managed elsewhere, by the specified role/playbook or in a separate controller.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;blacklist&lt;/strong&gt;: A list of child resources (by GVK) that will not be watched or cached.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An example Watches file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Simple example mapping Foo to the Foo role&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;foo.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Foo&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Foo&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Simple example mapping Bar to a playbook&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;bar.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Bar&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# More complex example for our Baz kind&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Here we will disable requeuing and be managing the CR status in the playbook,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# and specify additional variables.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;baz.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Baz&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;baz.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;manageStatus&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;False&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;vars&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;foo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;bar&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# ConfigMaps owned by a Memcached CR will not be watched or cached.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;/opt/ansible/roles/memcached&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;blacklist&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ConfigMap&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Example usage with a role from an installed Ansible collection&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;bar.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Bar&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;myNamespace.myCollection.myRole&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Example filtering of resources with specific labels&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;bar.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Bar&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;selector&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;foo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;bar&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;matchExpressions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;- {&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;key: foo, operator: In, values&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;bar&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;}&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;- {&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;key: baz, operator: Exists, values&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;}&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The advanced features can be enabled by adding them to your watches file per GVK.
They can go below the &lt;code&gt;group&lt;/code&gt;, &lt;code&gt;version&lt;/code&gt;, &lt;code&gt;kind&lt;/code&gt; and &lt;code&gt;playbook&lt;/code&gt; or &lt;code&gt;role&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Some features can be overridden per resource via an annotation on that CR. The options that are overridable will have the annotation specified below.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Yaml Key&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Annotation for override&lt;/th&gt;
&lt;th&gt;default&lt;/th&gt;
&lt;th&gt;Documentation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reconcile Period&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reconcilePeriod&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;time between reconcile runs for a particular CR&lt;/td&gt;
&lt;td&gt;ansible.sdk.operatorframework.io/reconcile-period&lt;/td&gt;
&lt;td&gt;10h&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manage Status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;manageStatus&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allows the ansible operator to manage the conditions section of each resource&amp;rsquo;s status section.&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watching Dependent Resources&lt;/td&gt;
&lt;td&gt;&lt;code&gt;watchDependentResources&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allows the ansible operator to dynamically watch resources that are created by ansible&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;../dependent-watches&#34;&gt;dependent watches&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watching Cluster-Scoped Resources&lt;/td&gt;
&lt;td&gt;&lt;code&gt;watchClusterScopedResources&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allows the ansible operator to watch cluster-scoped resources that are created by ansible&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max Runner Artifacts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;maxRunnerArtifacts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Manages the number of &lt;a href=&#34;https://ansible-runner.readthedocs.io/en/latest/intro.html#runner-artifacts-directory-hierarchy&#34;&gt;artifact directories&lt;/a&gt; that ansible runner will keep in the operator container for each individual resource.&lt;/td&gt;
&lt;td&gt;ansible.sdk.operatorframework.io/max-runner-artifacts&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finalizer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;finalizer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets a finalizer on the CR and maps a deletion event to a playbook or role&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;../finalizers&#34;&gt;finalizers&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selector&lt;/td&gt;
&lt;td&gt;&lt;code&gt;selector&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Identifies a set of objects based on their labels&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;None Applied&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/&#34;&gt;Labels and Selectors&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automatic Case Conversion&lt;/td&gt;
&lt;td&gt;&lt;code&gt;snakeCaseParameters&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Determines whether to convert the CR spec from camelCase to snake_case before passing the contents to Ansible as extra_vars&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watching Annotations Changes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;watchAnnotationsChanges&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allows the ansible operator to trigger reconciliations on annotations changes on watched resources&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;example&#34;&gt;Example&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-YaML&#34; data-lang=&#34;YaML&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;AppService&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;maxRunnerArtifacts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;30&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;reconcilePeriod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;5s&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;manageStatus&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;False&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;watchDependentResources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;False&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;snakeCaseParameters&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;False&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;finalizer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com/finalizer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;vars&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;state&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;absent&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; By using the command &lt;code&gt;operator-sdk add api&lt;/code&gt; you are able to add additional CRDs to the project API, which can aid in designing your solution using concepts such as encapsulation, single responsibility principle, and cohesion, which could make the project easier to read, debug, and maintain. With this approach, you are able to customize and optimize the configurations more specifically per GVK via the &lt;code&gt;watches.yaml&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-YaML&#34; data-lang=&#34;YaML&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;AppService&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;maxRunnerArtifacts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;30&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;reconcilePeriod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;5s&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;manageStatus&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;False&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;watchDependentResources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;False&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;finalizer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com/finalizer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;vars&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;state&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;absent&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;app.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Database&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;playbook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;playbook.yml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;watchDependentResources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;True&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;manageStatus&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;True&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Adding Admission Webhooks to an Ansible-based Operator</title>
      <link>/docs/building-operators/ansible/reference/webhooks/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/building-operators/ansible/reference/webhooks/</guid>
      <description>
        
        
        &lt;p&gt;For general background on what admission webhooks are, why to use them, and how to build them,
please refer to the official Kubernetes documentation on &lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/&#34;&gt;Extensible Admission Controllers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This guide will assume that you understand the above content, and that you have an existing admission
webhook server. You will likely need to make a few modifications to the webhook server container.&lt;/p&gt;
&lt;p&gt;When integrating an admission webhook server into your Ansible-based Operator, we recommend that you
deploy it as a sidecar container alongside your operator. This allows you to make use of the proxy
server that the operator deploys, as well as the cache that backs it.&lt;/p&gt;
&lt;h2 id=&#34;ensuring-the-webhook-server-uses-the-caching-proxy&#34;&gt;Ensuring the webhook server uses the caching proxy&lt;/h2&gt;
&lt;p&gt;When an Ansible-based Operator runs, it creates a Kubernetes proxy server and serves it on
&lt;code&gt;http://localhost:8888&lt;/code&gt;. This proxy server does not require any authorization, so all you need to
do to make use of the proxy is ensure that your Kubernetes client is pointing at &lt;code&gt;http://localhost:8888&lt;/code&gt;
and that it does not attempt to verify SSL. If you use the default in-cluster configuration, you will
be hitting the real API server and will not get caching for free.&lt;/p&gt;
&lt;h2 id=&#34;deploying-the-webhook-server&#34;&gt;Deploying the webhook server&lt;/h2&gt;
&lt;p&gt;Create a new file called &lt;code&gt;config/default/manager_webhook_patch.yaml&lt;/code&gt; with the following content
(making sure to replace the image reference placeholder string):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# This patch injects a sidecar container which is an admission webhook for the&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# controller manager.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;apps/v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Deployment&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;controller-manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;system&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;template&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;webhook&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Replace this with the built image name&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;REPLACE_WEBHOOK_IMAGE&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;/etc/tls/&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;webhook-cert&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;volumes&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# This assumes there is a secret called webhook-cert containing TLS certificates&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Projects like cert-manager can create these certificates&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;webhook-cert&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;secret&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;secretName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;webhook-cert&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, update &lt;code&gt;config/default/kustomization.yaml&lt;/code&gt; to include this patch:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;patchesStrategicMerge&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- manager_webhook_patch.yaml&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Add this line&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, when deploying the operator with &lt;code&gt;make deploy&lt;/code&gt;, your webhook server will run alongside the
operator, but Kubernetes will not yet call the webhooks before resources can be created. In order
to let Kubernetes know about your webhooks, you must create specific API resources.&lt;/p&gt;
&lt;!--
   TODO(fabianvf,asmacdo) update these sections to direct the user
     to create files in the config directory and make use of kustomize.
     The Go plugin&#39;s webhook scaffolding might be a good reference.
--&gt;
&lt;h2 id=&#34;making-kubernetes-call-your-webhooks&#34;&gt;Making Kubernetes call your webhooks&lt;/h2&gt;
&lt;p&gt;In order to make your webhooks callable at all, first you must create a &lt;code&gt;Service&lt;/code&gt; that points at your
webhook server. Below is a sample service that creates a &lt;code&gt;Service&lt;/code&gt; named &lt;code&gt;my-operator-webhook&lt;/code&gt;, that will
send traffic on port &lt;code&gt;443&lt;/code&gt; to port &lt;code&gt;5000&lt;/code&gt; in a &lt;code&gt;Pod&lt;/code&gt; that matches the selector &lt;code&gt;name=my-operator&lt;/code&gt;. Modify these
values to match your environment.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Service&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;my-operator-webhook&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ports&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;webhook&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;port&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;443&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;protocol&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;TCP&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Change targetPort to match the port your server is listening on&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;targetPort&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;5000&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;selector&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Change this selector to match the labels on your operator pod&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;my-operator&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ClusterIP&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now that you have a &lt;code&gt;Service&lt;/code&gt; directing traffic to your webhook server, you will need to create
&lt;a href=&#34;https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/mutating-webhook-configuration-v1/&#34;&gt;&lt;code&gt;MutatingWebhookConfiguration&lt;/code&gt;&lt;/a&gt; or &lt;a href=&#34;https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/validating-webhook-configuration-v1/&#34;&gt;&lt;code&gt;ValidatingWebhookConfiguration&lt;/code&gt;&lt;/a&gt; objects (depending on what type of webhook you have deployed), which will tell Kubernetes
to send certain API requests through your webhooks before writing to etcd.&lt;/p&gt;
&lt;p&gt;Below are examples of both &lt;a href=&#34;https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/mutating-webhook-configuration-v1/&#34;&gt;&lt;code&gt;MutatingWebhookConfiguration&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/validating-webhook-configuration-v1/&#34;&gt;&lt;code&gt;ValidatingWebhookConfiguration&lt;/code&gt;&lt;/a&gt; objects,
which will tell Kubernetes to call the &lt;code&gt;my-operator-webhook&lt;/code&gt; service when &lt;code&gt;samples.example.com Example&lt;/code&gt; resources
are created. The mutating webhook is served on the &lt;code&gt;/mutating&lt;/code&gt; path in my example webhook server, and the validating webhook is served on &lt;code&gt;/validating&lt;/code&gt;. Update these values as needed to reflect your environment
and desired behavior. These objects are thoroughly documented in the official Kubernetes documentation on &lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/&#34;&gt;Extensible Admission Controllers&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;admissionregistration.k8s.io/v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;MutatingWebhookConfiguration&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;mutating.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;webhooks&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;mutating.example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;rules&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiGroups&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;samples.example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;operations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;CREATE&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;resources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;examples&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;scope&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;       &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Namespaced&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;clientConfig&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;service&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Replace this with the namespace your service is in&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;REPLACE_NAMESPACE&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;my-operator-webhook&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;path&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;/mutating&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;admissionReviewVersions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;sideEffects&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;None&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;---&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;admissionregistration.k8s.io/v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ValidatingWebhookConfiguration&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;validating.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;webhooks&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;validating.example.com&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;rules&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiGroups&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;samples.example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;operations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;CREATE&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;resources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;examples&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;scope&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;       &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Namespaced&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;clientConfig&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;service&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Replace this with the namespace your service is in&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;REPLACE_NAMESPACE&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;my-operator-webhook&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;path&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;/validating&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;admissionReviewVersions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;failurePolicy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Fail&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;sideEffects&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;None&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If these resources are configured properly you will now have an admissions webhook that can reject or mutate
incoming resources before they are written to the Kubernetes database.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;To deploy an existing admissions webhook to validate or mutate your Kubernetes resources alongside an
Ansible-based Operator, you must&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Configure your admissions webhook to use the proxy server running on &lt;code&gt;http://localhost:8888&lt;/code&gt; in the operator pod&lt;/li&gt;
&lt;li&gt;Add the webhook container to your operator deployment&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;Service&lt;/code&gt; pointing to your webhook&lt;/li&gt;
&lt;li&gt;Make sure your webhook is reachable via the &lt;code&gt;Service&lt;/code&gt; over &lt;code&gt;https&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create &lt;a href=&#34;https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/mutating-webhook-configuration-v1/&#34;&gt;&lt;code&gt;MutatingWebhookConfiguration&lt;/code&gt;&lt;/a&gt; or &lt;a href=&#34;https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/validating-webhook-configuration-v1/&#34;&gt;&lt;code&gt;ValidatingWebhookConfiguration&lt;/code&gt;&lt;/a&gt; mapping the resource you want to mutate/validate to the &lt;code&gt;Service&lt;/code&gt; you created&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Changelog</title>
      <link>/docs/contribution-guidelines/changelog/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/contribution-guidelines/changelog/</guid>
      <description>
        
        
        &lt;p&gt;The Operator SDK project tracks changes across releases by maintaining a live changelog. This changelog is compiled via fragments located in &lt;code&gt;changelog/fragments&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Contributors are asked to add these changelog fragments when creating pull requests by following this &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/changelog/fragments/00-template.yaml&#34;&gt;template&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The changlog fragments document the following information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Description of Changes&lt;/li&gt;
&lt;li&gt;Types of Changes
&lt;ul&gt;
&lt;li&gt;One of: addition, change, deprecation, removal, bugfix&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Migration Guide for Changes
&lt;ul&gt;
&lt;li&gt;These are required for breaking changes, and essential (but not required) for scaffolding-related changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Issue Lifecycle</title>
      <link>/docs/contribution-guidelines/issue-lifecycle/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/contribution-guidelines/issue-lifecycle/</guid>
      <description>
        
        
        &lt;p&gt;The Operator SDK project tracks bugs, feature requests, and questions
with &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/issues&#34;&gt;GitHub issues&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;triage&#34;&gt;Triage&lt;/h2&gt;
&lt;p&gt;Each week, there is a &lt;a href=&#34;https://github.com/operator-framework/community#operator-sdk-issue-triage&#34;&gt;triage meeting&lt;/a&gt; to review new
issues. Each issue that has been filed since the previous meeting is
discussed, GitHub labels are applied, and the issue is added to a
&lt;a href=&#34;https://github.com/operator-framework/operator-sdk/milestones&#34;&gt;Milestone&lt;/a&gt;. Additionally, anyone can request that a
previously triaged issue can be retriaged.&lt;/p&gt;
&lt;h2 id=&#34;grooming&#34;&gt;Grooming&lt;/h2&gt;
&lt;p&gt;Following a release, there is a &lt;a href=&#34;https://github.com/operator-framework/community#operator-sdk-grooming-meeting&#34;&gt;grooming meeting&lt;/a&gt; to
review issues that are desired in the next release. Issues are discussed
in the following order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Issues in the next release milestone&lt;/li&gt;
&lt;li&gt;Issues labeled as &lt;code&gt;priority/important-soon&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Issues in other milestones/backlog if specifically requested&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Opening Pull Requests</title>
      <link>/docs/contribution-guidelines/opening-pull-requests/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/contribution-guidelines/opening-pull-requests/</guid>
      <description>
        
        
        &lt;p&gt;Changes to Operator SDK are submitted via &lt;a href=&#34;https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests&#34;&gt;Github Pull Request (PR)&lt;/a&gt;
to the relevant repository. Most PRs will be to the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk&#34;&gt;main Operator SDK repo&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;pr-checklist&#34;&gt;PR Checklist&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Add &lt;a href=&#34;https://sdk.operatorframework.io/docs/contribution-guidelines/testing/&#34;&gt;tests&lt;/a&gt; for your change, and ensure they run and pass in CI.&lt;/li&gt;
&lt;li&gt;Add a &lt;a href=&#34;https://sdk.operatorframework.io/docs/contribution-guidelines/changelog/#m-docscontribution-guidelineschangelog&#34;&gt;changelog entry&lt;/a&gt; if necessary.&lt;/li&gt;
&lt;li&gt;Add relevant &lt;a href=&#34;https://sdk.operatorframework.io/docs/contribution-guidelines/documentation/&#34;&gt;documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Rebase your commits on master and squash them into a single commit.&lt;/li&gt;
&lt;li&gt;Write a concise commit message that references the issue number.&lt;/li&gt;
&lt;li&gt;Push your commit to your fork and &lt;a href=&#34;https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork&#34;&gt;open a pull request&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;review&#34;&gt;Review&lt;/h2&gt;
&lt;p&gt;Before a pull request can be merged, tests must pass in CI and it must be reviewed. A PR
must be approved by 2 reviewers, one of which must be at least at least a reviewer and one
of which must be at least an approver, per the &lt;a href=&#34;https://github.com/operator-framework/community/blob/master/contributor-ladder.md&#34;&gt;Operator Framework community guidelines&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please feel free to message the developers to get eyes on your PR, whether through @&amp;lsquo;ing on the PR itself,
the #operator-sdk-dev channel on Kubernetes slack, or by attending the Operator SDK &lt;a href=&#34;https://github.com/operator-framework/community#operator-sdk-issue-triage&#34;&gt;triage meeting&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Testing Operator Deployment with OLM</title>
      <link>/docs/olm-integration/testing-deployment/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/testing-deployment/</guid>
      <description>
        
        
        &lt;p&gt;This document discusses the behavior of &lt;code&gt;operator-sdk &amp;lt;run|cleanup&amp;gt;&lt;/code&gt; subcommands related to OLM deployment,
and assumes you are familiar with &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/&#34;&gt;OLM&lt;/a&gt;, related terminology,
and have read the SDK-OLM integration &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/proposals/sdk-integration-with-olm.md&#34;&gt;design proposal&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;caveats&#34;&gt;Caveats&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;run bundle&lt;/code&gt;, &lt;code&gt;run bundle-upgrade&lt;/code&gt;, &lt;code&gt;run packagemanifests&lt;/code&gt;, and &lt;code&gt;cleanup&lt;/code&gt; are intended to be used for testing purposes only,
since these commands create a transient image registry that should not be used in production.
Typically a registry is deployed separately and a set of catalog manifests are created in the cluster
to inform OLM of that registry and which Operator versions it can deploy and where to deploy the Operator.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;run bundle&lt;/code&gt; and &lt;code&gt;run packagemanifests&lt;/code&gt; can only deploy one Operator and one version of that Operator at a time,
and &lt;code&gt;run bundle-upgrade&lt;/code&gt; can only upgrade one Operator and one version of that Operator at a time,
hence their intended purpose being testing only.&lt;/li&gt;
&lt;li&gt;If testing a bundle or catalog whose image will be hosted in a registry that is private and/or
has a custom CA, these &lt;a href=&#34;/docs/olm-integration/cli-overview#private-bundle-and-catalog-image-registries&#34;&gt;configuration steps&lt;/a&gt; must be complete.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;operator-sdk-run-bundle-command-overview&#34;&gt;&lt;code&gt;operator-sdk run bundle&lt;/code&gt; command overview&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;operator-sdk run bundle&lt;/code&gt; assumes OLM is already installed and running on your
cluster. It also assumes that your Operator has a valid &lt;a href=&#34;https://github.com/operator-framework/operator-registry/tree/v1.15.3#manifest-format&#34;&gt;bundle&lt;/a&gt;.
See the [creating a bundle][creating-bundle] guide for more information. See the
&lt;a href=&#34;/docs/olm-integration/cli-overview&#34;&gt;CLI overview&lt;/a&gt; for commands to work with an OLM installation
and generate a bundle.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;operator-sdk run bundle &amp;lt;bundle-image&amp;gt; [--index-image=] [--kubeconfig=] [--namespace=] [--timeout=] [--install-mode=(AllNamespace|OwnNamespace|SingleNamespace=)]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s look at the configuration shared between &lt;code&gt;run bundle&lt;/code&gt;, &lt;code&gt;run packagemanifests&lt;/code&gt;, &lt;code&gt;run bundle-upgrade&lt;/code&gt; and &lt;code&gt;cleanup&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kubeconfig&lt;/strong&gt;: the local path to a kubeconfig. This uses well-defined default
loading rules to load the config if empty.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;namespace&lt;/strong&gt;: the cluster namespace in which Operator resources are created.
This namespace must already exist in the cluster. This is an optional field
which will default to the kubeconfig context if not provided.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;timeout&lt;/strong&gt;: a time string dictating the maximum time that &lt;code&gt;run&lt;/code&gt; can run. The
command will return an error if the timeout is exceeded.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s look at the anatomy of the &lt;code&gt;run bundle&lt;/code&gt; configuration model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;bundle-image&lt;/strong&gt;: specifies the Operator bundle image, this is a
required parameter. The bundle image must be pullable.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;index-image&lt;/strong&gt;: specifies an index image in which to inject the given bundle.
This is an optional field which will default to
&lt;code&gt;quay.io/operator-framework/opm:latest&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;install-mode&lt;/strong&gt;: specifies which supported &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/building-your-csv.md#operator-metadata&#34;&gt;&lt;code&gt;installMode&lt;/code&gt;&lt;/a&gt;
should be used to create an &lt;code&gt;OperatorGroup&lt;/code&gt; by configuring its
&lt;code&gt;spec.targetNamespaces&lt;/code&gt; field. The &lt;code&gt;InstallModeType&lt;/code&gt; string passed must be
marked as &amp;ldquo;supported&amp;rdquo; in the CSV being installed.
&lt;ul&gt;
&lt;li&gt;This option understands the following strings (assuming your CSV does as
well):
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AllNamespaces&lt;/code&gt;: the Operator will watch all namespaces (cluster-scoped
Operators). This is the default.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OwnNamespace&lt;/code&gt;: the Operator will watch its own namespace (from
&lt;strong&gt;namespace&lt;/strong&gt; or the kubeconfig default).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SingleNamespace=&amp;quot;my-ns&amp;quot;&lt;/code&gt;: the Operator will watch a namespace, not
necessarily its own.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This is an optional parameter, but if the CSV does not support
&lt;code&gt;AllNamespaces&lt;/code&gt; then this parameter becomes &lt;strong&gt;required&lt;/strong&gt; to instruct
&lt;code&gt;run bundle&lt;/code&gt; with the appropriate &lt;code&gt;InstallModeType&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;operator-sdk-run-packagemanifests-command-overview&#34;&gt;&lt;code&gt;operator-sdk run packagemanifests&lt;/code&gt; command overview&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;operator-sdk run packagemanifests&lt;/code&gt; assumes OLM is already installed and
running on your cluster, and that your Operator has a valid
&lt;a href=&#34;https://github.com/operator-framework/operator-registry/tree/v1.5.3#manifest-format&#34;&gt;package manifests format&lt;/a&gt;. See the
&lt;a href=&#34;/docs/olm-integration/cli-overview&#34;&gt;CLI overview&lt;/a&gt; for commands to work with an OLM installation
and generate a package manifests format.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;operator-sdk run packagemanifests &amp;lt;packagemanifests-root-dir&amp;gt; [--version=] [--kubeconfig=] [--namespace=] [--timeout=] [--install-mode=(AllNamespace|OwnNamespace|SingleNamespace=)]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s look at the configuration shared between &lt;code&gt;run bundle&lt;/code&gt;, &lt;code&gt;run packagemanifests&lt;/code&gt; and &lt;code&gt;cleanup&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kubeconfig&lt;/strong&gt;: the local path to a kubeconfig. This uses well-defined default
loading rules to load the config if empty.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;namespace&lt;/strong&gt;: the cluster namespace in which Operator resources are created.
This namespace must already exist in the cluster. This is an optional field
which will default to the kubeconfig context if not provided.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;timeout&lt;/strong&gt;: a time string dictating the maximum time that &lt;code&gt;run&lt;/code&gt; can run. The
command will return an error if the timeout is exceeded.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s look at the anatomy of the &lt;code&gt;run packagemanifests&lt;/code&gt; configuration model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;packagemanifests-root-dir&lt;/strong&gt;: a directory containing the Operator&amp;rsquo;s package
manifests, this is a required parameter.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;install-mode&lt;/strong&gt;: specifies which supported &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/building-your-csv.md#operator-metadata&#34;&gt;&lt;code&gt;installMode&lt;/code&gt;&lt;/a&gt;
should be used to create an &lt;code&gt;OperatorGroup&lt;/code&gt; by configuring its
&lt;code&gt;spec.targetNamespaces&lt;/code&gt; field. The &lt;code&gt;InstallModeType&lt;/code&gt; string passed must be
marked as &amp;ldquo;supported&amp;rdquo; in the CSV being installed.
&lt;ul&gt;
&lt;li&gt;This option understands the following strings (assuming your CSV does as
well):
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AllNamespaces&lt;/code&gt;: the Operator will watch all namespaces (cluster-scoped
Operators). This is the default.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OwnNamespace&lt;/code&gt;: the Operator will watch its own namespace (from
&lt;strong&gt;namespace&lt;/strong&gt; or the kubeconfig default).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SingleNamespace=&amp;quot;my-ns&amp;quot;&lt;/code&gt;: the Operator will watch a namespace, not
necessarily its own.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This is an optional parameter, but if the CSV does not support
&lt;code&gt;AllNamespaces&lt;/code&gt; then this parameter becomes &lt;strong&gt;required&lt;/strong&gt; to instruct
&lt;code&gt;run packagemanifests&lt;/code&gt; with the appropriate &lt;code&gt;InstallModeType&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;version&lt;/strong&gt;: the version of the Operator to deploy. It must be a semantic
version, ex. 0.0.1. This version must match the version of the CSV manifest
found in &lt;strong&gt;manifests-dir&lt;/strong&gt;, e.g. &lt;code&gt;packagemanifests/0.0.1&lt;/code&gt; in an Operator
SDK project.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;operator-sdk-run-bundle-upgrade-command-overview&#34;&gt;&lt;code&gt;operator-sdk run bundle-upgrade&lt;/code&gt; command overview&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;operator-sdk run bundle-upgrade&lt;/code&gt; assumes OLM is already installed and running on your
cluster and that the Operator has a valid &lt;a href=&#34;https://github.com/operator-framework/operator-registry/tree/v1.15.3#manifest-format&#34;&gt;bundle&lt;/a&gt;. It also assumes that
the previous version of the Operator was either deployed on the cluster using &lt;code&gt;run bundle&lt;/code&gt;
command or traditionally via OLM. Another assumption of this command is that the newer operator bundle
should not exist in the index image, if the previous version of the operator bundle was installed
traditionally using OLM. This will cause the registry pod to fail as the bundle is already added to the
index that provides package and csv. See the &lt;a href=&#34;/docs/olm-integration/cli-overview&#34;&gt;CLI overview&lt;/a&gt; for commands to work with
an OLM installation and generate a bundle.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;operator-sdk run bundle-upgrade &amp;lt;bundle-image&amp;gt; [--kubeconfig=] [--namespace=] [--timeout=] 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s look at the anatomy of the &lt;code&gt;run bundle-upgrade&lt;/code&gt; configuration model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;bundle-image&lt;/strong&gt;: specifies the Operator bundle image, this is a
required parameter. The bundle image must be pullable.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;operator-sdk-cleanup-command-overview&#34;&gt;&lt;code&gt;operator-sdk cleanup&lt;/code&gt; command overview&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;operator-sdk cleanup&lt;/code&gt; assumes an Operator was deployed using &lt;code&gt;run bundle&lt;/code&gt; or
&lt;code&gt;run packagemanifests&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;operator-sdk cleanup &amp;lt;operatorPackageName&amp;gt; [--delete-all=] [--delete-crds=] [--delete-operator-groups=] [--kubeconfig=] [--namespace=] [--timeout=]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s look at the configuration shared between &lt;code&gt;run bundle&lt;/code&gt;, &lt;code&gt;run packagemanifests&lt;/code&gt; and &lt;code&gt;cleanup&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kubeconfig&lt;/strong&gt;: the local path to a kubeconfig. This uses well-defined default
loading rules to load the config if empty.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;namespace&lt;/strong&gt;: the cluster namespace in which Operator resources are created.
This namespace must already exist in the cluster. This is an optional field
which will default to the kubeconfig context if not provided.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;timeout&lt;/strong&gt;: a time string dictating the maximum time that &lt;code&gt;run&lt;/code&gt; can run. The
command will return an error if the timeout is exceeded.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s look at the anatomy of the &lt;code&gt;cleanup&lt;/code&gt; configuration model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;operatorPackageName&lt;/strong&gt;: the Operator&amp;rsquo;s package name which you want to remove
from the cluster, e.g. memcached-operator. This is a required parameter.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;delete-all&lt;/strong&gt;: a boolean indicating to enable all the delete flags that are present. This is an optional
field which will default to true if not provided. If set to true, it will enable all the delete flags to be true. If set to false, it will enable specific delete flags.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;delete-crds&lt;/strong&gt;: a boolean indicating to delete all owned CRDs and CRs. This is an optional field
which will default to false if not provided. If set to true, owned CRDs and CRs
will be deleted.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;delete-operator-groups&lt;/strong&gt;: a boolean indicating to delete all operator groups. This is an optional field
which will default to false if not provided. If set to true, operator groups will be deleted.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
  </channel>
</rss>
