Bug 2002197

Summary: Pass down proxy env to operands failed for helm type operator
Product: OpenShift Container Platform Reporter: Fan Jia <jfan>
Component: Operator SDKAssignee: amacdona <austin>
Status: CLOSED ERRATA QA Contact: Fan Jia <jfan>
Severity: urgent Docs Contact:
Priority: urgent    
Version: 4.9CC: aos-bugs, jesusr, marobrie
Target Milestone: ---   
Target Release: 4.9.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-10-18 17:51:28 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Fan Jia 2021-09-08 08:39:04 UTC
Description of problem:
Pass down proxy env to operands failed for helm type operator as the description : https://github.com/operator-framework/enhancements/blob/master/enhancements/proxy-passdown.md 

Version-Release number of selected component (if applicable):
operator-sdk version: "v1.10.1-ocp", commit: "972fd59bb3a4cdb2e5102fc37fc3afa32f6c066f", kubernetes version: "v1.21", go version: "go1.16.5", GOOS: "linux", GOARCH: "amd64"

How reproducible:
always

Steps to Reproduce:
1. created a helm operator as https://docs.openshift.com/container-platform/4.8/operators/operator_sdk/helm/osdk-helm-tutorial.html and add the proxy to the watch file
$ cat watches.yaml 
# Use the 'create api' subcommand to add watches to this file.
- group: demo.example.com
  version: v1
  kind: Nginx
  chart: helm-charts/nginx
  overrideValues:
    httpsProxy: "http://proxy-user1:JYgU8qRZV4DY4PXJbxJK@ec2-3-144-97-198.us-east-2.compute.amazonaws.com:3128"
    httpProxy: "http://proxy-user1:JYgU8qRZV4DY4PXJbxJK@ec2-3-144-97-198.us-east-2.compute.amazonaws.com:3128"
    noProxy: "test.no-proxy.com"
#+kubebuilder:scaffold:watch

2. create the CR
$ cat config/samples/demo_v1_nginx.yaml 
apiVersion: demo.example.com/v1
kind: Nginx
metadata:
  name: nginx-sample
spec:
  # Default values copied from <project_dir>/helm-charts/nginx/values.yaml
  affinity: {}
  autoscaling:
    enabled: false
    maxReplicas: 100
    minReplicas: 1
    targetCPUUtilizationPercentage: 80
  fullnameOverride: ""
  image:
    pullPolicy: IfNotPresent
    repository: nginx
    tag: ""
  imagePullSecrets: []
  ingress:
    annotations: {}
    className: ""
    enabled: false
    hosts:
    - host: chart-example.local
      paths:
      - path: /
        pathType: ImplementationSpecific
    tls: []
  nameOverride: ""
  nodeSelector: {}
  podAnnotations: {}
  podSecurityContext: {}
  replicaCount: 2
  resources: {}
  securityContext: {}
  service:
    port: 8080
    type: ClusterIP
  serviceAccount:
    annotations: {}
    create: true
    name: ""
  tolerations: []


Actual results:

The deployment of nigix-sample yaml doesn't have the message about http/https/noproxy env
$oc get deployment nginx-sample -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
    meta.helm.sh/release-name: nginx-sample
    meta.helm.sh/release-namespace: nginx-system
  creationTimestamp: "2021-09-08T05:37:06Z"
  generation: 1
  labels:
    app.kubernetes.io/instance: nginx-sample
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: nginx
    app.kubernetes.io/version: 1.16.0
    helm.sh/chart: nginx-0.1.0
  name: nginx-sample
  namespace: nginx-system
  ownerReferences:
  - apiVersion: demo.example.com/v1
    blockOwnerDeletion: true
    controller: true
    kind: Nginx
    name: nginx-sample
    uid: 6e88e0d0-bb28-48e6-b75b-e38cc15f8431
  resourceVersion: "79564"
  uid: b1f83db8-bd45-477e-8ae1-c8148951b942
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/instance: nginx-sample
      app.kubernetes.io/name: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app.kubernetes.io/instance: nginx-sample
        app.kubernetes.io/name: nginx
    spec:
      containers:
      - image: nginx:1.16.0
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /
            port: http
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: nginx
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /
            port: http
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources: {}
        securityContext: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: nginx-sample
      serviceAccountName: nginx-sample
      terminationGracePeriodSeconds: 30


Expected results:
The http_proxy can be added to the deployment of nginx-sample. And the pods are created successfully.

Additional info:

Comment 1 amacdona@redhat.com 2021-09-13 11:40:57 UTC
This should work as you did it, except that the helm chart doesn't support these vars yet. 



Add the var in helmcharts/nginx/values.yaml    

```                                                                                                                                                                                                                                       
  proxy:                                                                                                                                                                                                                                      
    httpProxy: ""                                                                                                                                                                                                                                  
```


Use the var in the helmcharts/nginx/templates/deployment.yaml

```
      containers:                                                                                                                                                                                                                             
        - name: {{ .Chart.Name }}                                                                                                                                                                                                             
          securityContext:                                                                                                                                                                                                                    
            {{- toYaml .Values.securityContext | nindent 12 }}                                                                                                                                                                                
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"                                                                                                                                         
          imagePullPolicy: {{ .Values.image.pullPolicy }}                                                                                                                                                                                     
          env:                                                                                                                                                                                                                                
            - name: http_proxy                                                                                                                                                                                                                
              value: "{{ .Values.httpProxy }}"                                                                                                                                                                                               
          ports:                                                                                                                                                                                                                              
            - name: http                                                                                                                                                                                                                      
              containerPort: 80                                                                                                                                                                                                               
              protocol: TCP                                                                                                                                                                                                                   
          livenessProbe:                                                                                                                                                                                                                      
            httpGet:                                                                                                                                                                                                                          
              path: /                                                                                                                                                                                                                         
              port: http                                                                                                                                                                                                                      
          readinessProbe:                                                                                                                                                                                                                     
            httpGet:                                                                                                                                                                                                                          
              path: /                                                                                                                                                                                                                         
              port: http          
```

Comment 2 amacdona@redhat.com 2021-09-13 14:39:01 UTC
You will also need to add the value to a template. 

Edit helm-charts/ginx/templates/deployment.yaml

```
      containers:                                                                                                                                                                                                                             
        - name: {{ .Chart.Name }}                                                                                                                                                                                                             
          securityContext:                                                                                                                                                                                                                    
            {{- toYaml .Values.securityContext | nindent 12 }}                                                                                                                                                                                
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"                                                                                                                                         
          imagePullPolicy: {{ .Values.image.pullPolicy }}                                                                                                                                                                                     
          env:                                                                                                                                                                                                                                
            - name: http_proxy                                                                                                                                                                                                                
              value: "{{ .Values.proxy.http }}"  
```

Comment 3 amacdona@redhat.com 2021-09-13 16:53:28 UTC
You can also have a look at the docs PR to verify this https://github.com/operator-framework/operator-sdk/pull/5204

Comment 4 amacdona@redhat.com 2021-09-13 17:01:40 UTC
Demo repo https://github.com/asmacdo/helm-proxy-demo

Comment 5 Fan Jia 2021-09-14 02:32:52 UTC
verified.

test env:
1. operator-sdk version: "v1.10.1-ocp", commit: "972fd59bb3a4cdb2e5102fc37fc3afa32f6c066f", kubernetes version: "v1.21", go version: "go1.16.5", GOOS: "linux", GOARCH: "amd64"

2. cv:4.9.0-0.nightly-2021-09-10-170926

3. add the http_proxy message to the helm operator
1) watches.yaml
- group: demo.example.com
  version: v1alpha1
  kind: Nginx
  chart: helm-charts/nginx
  overrideValues:
    proxy.http: $HTTP_PROXY

2)helmcharts/nginx/Values.yaml
proxy:
  http: ""
  https: ""
  no_proxy: ""
3)helm-charts/nginx/templates/deployment.yaml
containers:                                                                                                                                                                                                                             
  - name: {{ .Chart.Name }}                                                                                                                                                                                                             
    securityContext:                                                                                                                                                                                                                    
      {{- toYaml .Values.securityContext | nindent 12 }}                                                                                                                                                                                
    image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"                                                                                                                                         
    imagePullPolicy: {{ .Values.image.pullPolicy }}                                                                                                                                                                                     
    env:                                                                                                                                                                                                                                
      - name: http_proxy                                                                                                                                                                                                                
        value: "{{ .Values.proxy.http }}"  
4)config/manager/manager.yaml
containers:
 - args:
   - --leader-elect
   - --leader-election-id=helm-proxy-demo
   image: controller:latest
   name: manager
   env:
     - name: "HTTP_PROXY"
       value: $CLUSTER_HTTP_PROXY
5)Makefile
deploy: kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
	cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
	$(KUSTOMIZE) build config/default | CLUSTER_HTTP_PROXY=$(shell kubectl get proxies.config.openshift.io cluster  -o json | jq '.spec.httpProxy') envsubst | kubectl apply -f -


test result:
CR created success and env is passed to operand
1)$ oc create -f config/samples/helmdemo_v1_nginx.yaml -n nginx-system
nginx.helmdemo.example.com/nginx-sample created

2)$oc get deployment nginx-sample -o=jsonpath={.spec.template.spec.containers[0].env}
[{"name":"http_proxy","value":"http://proxy-user1:JYgU8qRZV4DY4PXxxxxK@ec2-18-188-xxxxxx.us-xxxx-2.compute.amazonaws.com:3128"}]

Comment 8 errata-xmlrpc 2021-10-18 17:51:28 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (Moderate: OpenShift Container Platform 4.9.0 bug fix and security update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2021:3759