<commit_before>// Module included in the following assemblies:
//
// * operators/operator_sdk/osdk-generating-csvs.adoc

:_content-type: PROCEDURE
[id="olm-enabling-operator-for-restricted-network_{context}"]
= Enabling your Operator for restricted network environments

As an Operator author, your Operator must meet additional requirements to run properly in a restricted network, or disconnected, environment.

.Operator requirements for supporting disconnected mode

* In the cluster service version (CSV) of your Operator:
** List any _related images_, or other container images that your Operator might require to perform their functions.
** Reference all specified images by a digest (SHA) and not by a tag.
* All dependencies of your Operator must also support running in a disconnected mode.
* Your Operator must not require any off-cluster resources.
// TODO: Include more info w/ better steps on how to do this:
//* You must understand the {product-title} proxy configuration.

For the CSV requirements, you can make the following changes as the Operator author.

.Prerequisites

* An Operator project with a CSV.

.Procedure

. Use SHA references to related images in two places in the CSV for your Operator:

.. Update `spec.relatedImages`:
+
[source,yaml]
----
...
spec:
  relatedImages: <1>
    - name: etcd-operator <2>
      image: quay.io/etcd-operator/operator@sha256:d134a9865524c29fcf75bbc4469013bc38d8a15cb5f41acfddb6b9e492f556e4 <3>
    - name: etcd-image
      image: quay.io/etcd-operator/etcd@sha256:13348c15263bd8838ec1d5fc4550ede9860fcbb0f843e48cbccec07810eebb68
...
----
<1> Create a `relatedImages` section and set the list of related images.
<2> Specify a unique identifier for the image.
<3> Specify each image by a digest (SHA), not by an image tag.

.. Update the `env` section in the deployment when declaring environment variables that inject the image that the Operator should use:
+
[source,yaml]
----
spec:
  install:
    spec:
      deployments:
      - name: etcd-operator-v3.1.1
        spec:
          replicas: 1
          selector:
            matchLabels:
              name: etcd-operator
          strategy:
            type: Recreate
          template:
            metadata:
              labels:
                name: etcd-operator
            spec:
              containers:
              - args:
                - /opt/etcd/bin/etcd_operator_run.sh
                env:
                - name: WATCH_NAMESPACE
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.annotations['olm.targetNamespaces']
                - name: ETCD_OPERATOR_DEFAULT_ETCD_IMAGE <1>
                  value: quay.io/etcd-operator/etcd@sha256:13348c15263bd8838ec1d5fc4550ede9860fcbb0f843e48cbccec07810eebb68 <2>
                - name: ETCD_LOG_LEVEL
                  value: INFO
                image: quay.io/etcd-operator/operator@sha256:d134a9865524c29fcf75bbc4469013bc38d8a15cb5f41acfddb6b9e492f556e4 <3>
                imagePullPolicy: IfNotPresent
                livenessProbe:
                  httpGet:
                    path: /healthy
                    port: 8080
                  initialDelaySeconds: 10
                  periodSeconds: 30
                name: etcd-operator
                readinessProbe:
                  httpGet:
                    path: /ready
                    port: 8080
                  initialDelaySeconds: 10
                  periodSeconds: 30
                resources: {}
              serviceAccountName: etcd-operator
    strategy: deployment
----
+
--
<1> Inject the images referenced by the Operator by using environment variables.
<2> Specify each image by a digest (SHA), not by an image tag.
<3> Also reference the Operator container image by a digest (SHA), not by an image tag.
--
+
[NOTE]
====
When configuring probes, the `timeoutSeconds` value must be lower than the `periodSeconds` value. The `timeoutSeconds` default value is `1`. The `periodSeconds` default value is `10`.
====

. Add the `disconnected` annotation, which indicates that the Operator works in a disconnected environment:
+
[source,yaml]
----
metadata:
  annotations:
    operators.openshift.io/infrastructure-features: '["disconnected"]'
----
+
Operators can be filtered in OperatorHub by this infrastructure feature.
<commit_msg>OSDOCS-2932: OSDK-1760: digest bundle for disconnected environments<commit_after>// Module included in the following assemblies:
//
// * operators/operator_sdk/osdk-generating-csvs.adoc

:_content-type: PROCEDURE
[id="olm-enabling-operator-for-restricted-network_{context}"]
= Enabling your Operator for restricted network environments

As an Operator author, your Operator must meet additional requirements to run properly in a restricted network, or disconnected, environment.

.Operator requirements for supporting disconnected mode

* Replace hard-coded image references with environment variables.
* In the cluster service version (CSV) of your Operator:
** List any _related images_, or other container images that your Operator might require to perform their functions.
** Reference all specified images by a digest (SHA) and not by a tag.
* All dependencies of your Operator must also support running in a disconnected mode.
* Your Operator must not require any off-cluster resources.
// TODO: Include more info w/ better steps on how to do this:
//* You must understand the {product-title} proxy configuration.

.Prerequisites

* An Operator project with a CSV. The following procedure uses the Memcached Operator as an example for Go-, Ansible-, and Helm-based projects.

.Procedure

. Set an environment variable for the additional image references used by the Operator in the `config/manager/manager.yaml` file:
+
.Example `config/manager/manager.yaml` file
[%collapsible]
====
[source,yaml]
----
...
spec:
  ...
    spec:
      ...
      containers:
      - command:
        - /manager
        ...
        env:
        - name: <related_image_environment_variable> <.>
          value: "<related_image_reference_with_tag>" <.>
----
<.> Define the environment variable, such as `RELATED_IMAGE_MEMCACHED`.
<.> Set the related image reference and tag, such as `docker.io/memcached:1.4.36-alpine`.
====

. Replace hard-coded image references with environment variables in the relevant file for your Operator project type:

* For Go-based Operator projects, add the environment variable to the `controllers/memcached_controller.go` file as shown in the following example:
+
.Example `controllers/memcached_controller.go` file
[%collapsible]
====
[source,diff]
----
  // deploymentForMemcached returns a memcached Deployment object

...

	Spec: corev1.PodSpec{
        	Containers: []corev1.Container{{
-			Image:   "memcached:1.4.36-alpine", <.>
+			Image:   os.Getenv("<related_image_environment_variable>"), <.>
			Name:    "memcached",
			Command: []string{"memcached", "-m=64", "-o", "modern", "-v"},
			Ports: []corev1.ContainerPort{{

...
----
<.> Delete the image reference and tag.
<.> Use the `os.Getenv` function to call the `<related_image_environment_variable>`.

[NOTE]
=====
The `os.Getenv` function returns an empty string if a variable is not set. Set the `<related_image_environment_variable>` before changing the file.
=====
====

* For Ansible-based Operator projects, add the environment variable to the `roles/memcached/tasks/main.yml` file as shown in the following example:
+
.Example `roles/memcached/tasks/main.yml` file
[%collapsible]
====
[source,diff]
----
spec:
  containers:
  - name: memcached
    command:
    - memcached
    - -m=64
    - -o
    - modern
    - -v
-   image: "docker.io/memcached:1.4.36-alpine" <.>
+   image: "{{ lookup('env', '<related_image_environment_variable>') }}" <.>
    ports:
      - containerPort: 11211

...
----
<.> Delete the image reference and tag.
<.> Use the `lookup` function to call the `<related_image_environment_variable>`.
====

* For Helm-based Operator projects, add the environment variable to the `helm-charts/memchached/values.yaml` file as shown in the following example:
+
.`helm-charts/memchached/values.yaml` diff
[%collapsible]
====
[source,diff]
----
  ## Memcached image and tag
  ## ref: https://hub.docker.com/r/library/memcached/tags/
  ##
- image: memcached:1.5.20 <.>
+ image: "{{ lookup('env', '<related_image_environment_variable>') }}" <.>

...
----
<.> Delete the image reference and tag.
<.> Use the `lookup` function to call the `<related_image_environment_variable>`.
====

. Add the `BUNDLE_GEN_FLAGS` variable definition to your `Makefile` with the following changes:
+
.Example `Makefile`
[source,diff]
----
   BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS)

   # USE_IMAGE_DIGESTS defines if images are resolved via tags or digests
   # You can enable this value if you would like to use SHA Based Digests
   # To enable set flag to true
   USE_IMAGE_DIGESTS ?= false
   ifeq ($(USE_IMAGE_DIGESTS), true)
         BUNDLE_GEN_FLAGS += --use-image-digests
   endif

...

-  $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) <.>
+  $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle $(BUNDLE_GEN_FLAGS) <.>

...
----
<.> Delete this line in the `Makefile`.
<.> Replace the line above with this line.

. To update your Operator image to use a digest (SHA) and not a tag, run the `make bundle` command and set `USE_IMAGE_DIGESTS` to `true` :
+
[source,terminal]
----
$ make bundle USE_IMAGE_DIGESTS=true
----

. Add the `disconnected` annotation, which indicates that the Operator works in a disconnected environment:
+
[source,yaml]
----
metadata:
  annotations:
    operators.openshift.io/infrastructure-features: '["disconnected"]'
----
+
Operators can be filtered in OperatorHub by this infrastructure feature.

{'fraction_non_alphanumeric': 0.10346920198240113, 'fraction_numerical': 0.02356629918074239, 'mean_word_length': 3.0507988529291272, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 44, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1457178', 'n_tokens_mistral': 3089, 'n_tokens_neox': 2838, 'n_words': 956}