zar3bski opened a new issue, #7920:
URL: https://github.com/apache/apisix/issues/7920

   ### Current Behavior
   
   I can't use a [python 
plugin](https://github.com/apache/apisix-python-plugin-runner) as a 
`ext-plugin-post-req`.  When I deactivate the plugin,the request reaches the 
upstream service. 
   Here are the processes in the container
   ```
   ps 
   PID   USER     TIME  COMMAND
       1 root      0:00 {openresty} nginx: master process 
/usr/local/openresty/bin/openresty -p /usr/local/apisix -g daemon off;
      46 nobody    0:00 {openresty} nginx: worker process
      .....
      75 nobody    0:00 {openresty} nginx: worker process
      76 nobody    0:00 {openresty} nginx: worker process
      77 nobody    0:00 {openresty} nginx: worker process
      78 nobody    0:00 {openresty} nginx: cache manager process
      80 root      0:00 {openresty} nginx: privileged agent process
      81 root      0:00 python3 /usr/share/extras/py-apisix/py-runner start
   ```
   
   It seems that both apisix and my plugin run as root so they should be able 
to communicate through `/usr/local/apisix/conf/apisix-1.sock`:
   
   ```
   ls -la /usr/local/apisix/conf/apisix-1.sock
   srwxr-xr-x    1 root     root             0 Sep 14 13:17 
/usr/local/apisix/conf/apisix-1.sock
   ```
   
   I just can't make sense of this behavior
   
   ### Expected Behavior
   
   Requests should reach the upstream service enriched with the headers defined 
in the plugin module
   
   **apisix-python-plugin-runner/apisix/plugins/rewrite.py**
   ```python
       def filter(self, conf: Any, request: Request, response: Response):
           """
           The plugin executes the main function
           :param conf:
               plugin configuration after parsing
           :param request:
               request parameters and information
           :param response:
               response parameters and information
           :return:
           """
   
           # print plugin configuration
           print(conf)
   
           # Fetch request nginx variable `host`
           host = request.get_var("host")
           print(host)
   
           # Fetch request body
           body = request.get_body()
           print(body)
   
           # Rewrite request headers
           request.set_header("X-Resp-A6-Runner", "Python")
   
           # Rewrite request args
           request.set_arg("a6_runner", "Python")
   
           # Rewrite request path
           request.set_uri("/a6/python/runner")
   ```
   
   ### Error Logs
   
   ```
   2022/09/14 13:47:01 [crit] 47#47: *795708 connect() to 
unix:/usr/local/apisix/conf/apisix-1.sock failed (13: Permission denied), 
client: 192.168.1.139, server: _, request: "GET /mock/ HTTP/1.1", host: 
"localhost:32674"
   2022/09/14 13:47:01 [error] 47#47: *795708 [lua] init.lua:726: phase_func(): 
failed to connect to the unix socket unix:/usr/local/apisix/conf/apisix-1.sock: 
permission denied, client: 192.168.1.139, server: _, request: "GET /mock/ 
HTTP/1.1", host: "localhost:32674"
   2022/09/14 13:47:01 [warn] 47#47: *795708 [lua] plugin.lua:759: 
run_plugin(): ext-plugin-post-req exits with http status code 503, client: 
192.168.1.139, server: _, request: "GET /mock/ HTTP/1.1", host: 
"localhost:32674"
   ```
   
   ### Steps to Reproduce
   
   1. Deploy the chart with the following values.yaml
   
   ```yaml
   #
   # Licensed to the Apache Software Foundation (ASF) under one or more
   # contributor license agreements.  See the NOTICE file distributed with
   # this work for additional information regarding copyright ownership.
   # The ASF licenses this file to You under the Apache License, Version 2.0
   # (the "License"); you may not use this file except in compliance with
   # the License.  You may obtain a copy of the License at
   #
   #     http://www.apache.org/licenses/LICENSE-2.0
   #
   # Unless required by applicable law or agreed to in writing, software
   # distributed under the License is distributed on an "AS IS" BASIS,
   # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   # See the License for the specific language governing permissions and
   # limitations under the License.
   
   apisix:
     # Enable or disable Apache APISIX itself
     # Set it to false and ingress-controller.enabled=true will deploy only 
ingress-controller
     enabled: true
   
     admin_key:
       - name: admin
         key: edd1c9f034335f136f87ad84b625c8f1  # using fixed API token has 
security risk, please update it when you deploy to production environment
         role: admin
   
     # Enable nginx IPv6 resolver
     enableIPv6: true
   
     # Use Pod metadata.uid as the APISIX id.
     setIDFromPodUID: false
   
     customLuaSharedDicts: []
       # - name: foo
       #   size: 10k
       # - name: bar
       #   size: 1m
     luaModuleHook:
       enabled: false
       # extend lua_package_path to load third party code
       luaPath: ""
       # the hook module which will be used to inject third party code into 
APISIX
       # use the lua require style like: "module.say_hello"
       hookPoint: ""
       # configmap that stores the codes
       configMapRef:
         name: ""
         # mounts decides how to mount the codes to the container.
         mounts:
           - key: ""
             path: ""
   
     enableCustomizedConfig: false
     customizedConfig: {}
   
     image:
       repository: apisix/apisix #apache/apisix
       pullPolicy: Always
       # Overrides the image tag whose default is the chart appVersion.
       tag: 2.13.3-alpine
       
     # Use a `DaemonSet` or `Deployment`
     kind: Deployment
     # kind is DaemonSet, replicaCount not become effective
     replicaCount: 1
   
     podAnnotations: {}
     podSecurityContext: {}
       # fsGroup: 2000
     securityContext: {}
       # capabilities:
       #   drop:
       #   - ALL
       # readOnlyRootFilesystem: true
       # runAsNonRoot: true
       # runAsUser: 1000
   
     # See https://kubernetes.io/docs/tasks/run-application/configure-pdb/ for 
more details
     podDisruptionBudget:
       enabled: false
       minAvailable: 90%
       maxUnavailable: 1
   
     resources: {}
       # We usually recommend not to specify default resources and to leave 
this as a conscious
       # choice for the user. This also increases chances charts run on 
environments with little
       # resources, such as Minikube. If you do want to specify resources, 
uncomment the following
       # lines, adjust them as necessary, and remove the curly braces after 
'resources:'.
       # limits:
       #   cpu: 100m
       #   memory: 128Mi
       # requests:
       #   cpu: 100m
       #   memory: 128Mi
     hostNetwork: false
   
     nodeSelector: {}
     tolerations: []
     affinity: {}
     # If true, it will sets the anti-affinity of the Pod.
     podAntiAffinity:
       enabled: false
   
     # timezone is the timezone where apisix uses.
     # For example: "UTC" or "Asia/Shanghai"
     # This value will be set on apisix container's environment variable TZ.
     # You may need to set the timezone to be consistent with your local time 
zone,
     # otherwise the apisix's logs may used to retrieve event maybe in wrong 
timezone.
     timezone: ""
   
     # extraEnvVars An array to add extra env vars
     # e.g:
     # extraEnvVars:
     #   - name: FOO
     #     value: "bar"
     #   - name: FOO2
     #     valueFrom:
     #       secretKeyRef:
     #         name: SECRET_NAME
     #         key: KEY
     extraEnvVars: []
   
   nameOverride: ""
   fullnameOverride: ""
   
   gateway:
     type: NodePort
     # If you want to keep the client source IP, you can set this to Local.
     # ref: 
https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip
     externalTrafficPolicy: Cluster
     # type: LoadBalancer
     # annotations:
     #   service.beta.kubernetes.io/aws-load-balancer-type: nlb
     externalIPs: []
     http:
       enabled: true
       servicePort: 80
       containerPort: 9080
     tls:
       enabled: false
       servicePort: 443
       containerPort: 9443
       existingCASecret: ""
       certCAFilename: ""
       http2:
         enabled: true
       sslProtocols: "TLSv1.2 TLSv1.3"
     # L4 proxy (TCP/UDP)
     stream:
       enabled: false
       only: false
       tcp: []
       udp: []
     ingress:
       enabled: false
       annotations: {}
         # kubernetes.io/ingress.class: nginx
         # kubernetes.io/tls-acme: "true"
       hosts:
         - host: apisix.local
           paths: []
       tls: []
     #  - secretName: apisix-tls
     #    hosts:
     #      - chart-example.local
   
   admin:
     # Enable Admin API
     enabled: true
     # admin service type
     type: ClusterIP
     # loadBalancerIP: a.b.c.d
     # loadBalancerSourceRanges:
     #   - "143.231.0.0/16"
     externalIPs: []
     #
     port: 9180
     servicePort: 9180
     # Admin API support CORS response headers
     cors: true
     # Admin API credentials
     credentials:
       admin: edd1c9f034335f136f87ad84b625c8f1
       viewer: 4054f7cf07e344346cd3f287985e76a2
   
     allow:
       # The ip range for allowing access to Apache APISIX
       ipList:
         - 127.0.0.1/24
   
   nginx:
     workerRlimitNofile: "20480"
     workerConnections: "10620"
     workerProcesses: auto
     enableCPUAffinity: true
   
   # APISIX plugins to be enabled
   plugins:
     - api-breaker
     - authz-keycloak
     - basic-auth
     - batch-requests
     - consumer-restriction
     - cors
     - echo
     - fault-injection
     - grpc-transcode
     - hmac-auth
     - http-logger
     - ip-restriction
     - ua-restriction
     - jwt-auth
   #  - kafka-logger
     - key-auth
     - limit-conn
     - limit-count
     - limit-req
     - node-status
     - openid-connect
     - authz-casbin
     - prometheus
     - proxy-cache
     - proxy-mirror
     - proxy-rewrite
     - redirect
     - referer-restriction
     - request-id
     - request-validation
     - response-rewrite
     - serverless-post-function
     - serverless-pre-function
     - sls-logger
     - syslog
     - tcp-logger
     - udp-logger
     - uri-blocker
     - wolf-rbac
     - zipkin
     - traffic-split
     - gzip
     - real-ip
     - ext-plugin-pre-req
     - ext-plugin-post-req
   stream_plugins:
     - mqtt-proxy
     - ip-restriction
     - limit-conn
   
   pluginAttrs:  {}
   
   extPlugin:
     enabled: true
     cmd: ["python3","/usr/share/extras/py-apisix/py-runner", "start"]
   
   # customPlugins allows you to mount your own HTTP plugins.
   customPlugins:
     enabled: false
     # the lua_path that tells APISIX where it can find plugins,
     # note the last ';' is required.
     luaPath: "/opts/custom_plugins/?.lua"
     plugins:
       # plugin name.
       - name: ""
         # plugin attrs
         attrs: {}
         # plugin codes can be saved inside configmap object.
         configMap:
           # name of configmap.
           name: ""
           # since keys in configmap is flat, mountPath allows to define the 
mount
           # path, so that plugin codes can be mounted hierarchically.
           mounts:
             - key: ""
               path: ""
             - key: ""
               path: ""
   
   updateStrategy: {}
     # type: RollingUpdate
   
   extraVolumes: 
     - name: apisix-lib
       hostPath:
         path: 
/home/zar3bski/Documents/Code/octaave/test_files/apisix-python-plugin-runner/apisix
     - name: apisix-bin
       hostPath:
         path: 
/home/zar3bski/Documents/Code/octaave/test_files/apisix-python-plugin-runner/bin
     - name: apisix-conf
       hostPath:
         path: 
/home/zar3bski/Documents/Code/octaave/test_files/apisix-python-plugin-runner/conf
   
   extraVolumeMounts:
     - name: apisix-lib
       mountPath: /usr/lib/python3.9/site-packages/apisix
       readOnly: true
     - name: apisix-bin
       mountPath: /usr/share/extras/py-apisix
       readOnly: true
     - name: apisix-conf
       mountPath: /usr/share/extras/conf
       readOnly: true
   
   discovery:
     enabled: false
     registry:
       # Integration service discovery registry. E.g eureka\dns\nacos\consul_kv
       # reference:
       # 
https://apisix.apache.org/docs/apisix/discovery#configuration-for-eureka
       # 
https://apisix.apache.org/docs/apisix/discovery/dns#service-discovery-via-dns
       # 
https://apisix.apache.org/docs/apisix/discovery/consul_kv#configuration-for-consul-kv
       # 
https://apisix.apache.org/docs/apisix/discovery/nacos#configuration-for-nacos
       #
       # an eureka example:
       # eureka:
       #   host:
       #     - "http://${username}:${password}@${eureka_host1}:${eureka_port1}";
       #     - "http://${username}:${password}@${eureka_host2}:${eureka_port2}";
       #   prefix: "/eureka/"
       #   fetch_interval: 30
       #   weight: 100
       #   timeout:
       #     connect: 2000
       #     send: 2000
       #     read: 5000
   
   # access log and error log configuration
   logs:
     enableAccessLog: true
     accessLog: "/dev/stdout"
     accessLogFormat: '$remote_addr - $remote_user [$time_local] $http_host 
\"$request\" $status $body_bytes_sent $request_time \"$http_referer\" 
\"$http_user_agent\" $upstream_addr $upstream_status $upstream_response_time 
\"$upstream_scheme://$upstream_host$upstream_uri\"'
     accessLogFormatEscape: default
     errorLog: "/dev/stderr"
     errorLogLevel: "warn"
   
   dns:
     resolvers:
       - 127.0.0.1
       - 172.20.0.10
       - 114.114.114.114
       - 223.5.5.5
       - 1.1.1.1
       - 8.8.8.8
     validity: 30
     timeout: 5
   
   initContainer:
     image: busybox
     tag: 1.28
   
   autoscaling:
     enabled: false
     minReplicas: 1
     maxReplicas: 100
     targetCPUUtilizationPercentage: 80
     targetMemoryUtilizationPercentage: 80
   
   # Custom configuration snippet.
   configurationSnippet:
     main: |
     httpStart: |
     httpEnd: |
     httpSrv: |
     httpAdmin: |
     stream: |
   # Observability configuration.
   # ref: https://apisix.apache.org/docs/apisix/plugins/prometheus/
   serviceMonitor:
     enabled: false
     # namespace where the serviceMonitor is deployed, by default, it is the 
same as the namespace of the apisix
     namespace: ""
     # name of the serviceMonitor, by default, it is the same as the apisix 
fullname
     name: ""
     # interval at which metrics should be scraped
     interval: 15sfalse
     metricPrefix: apisix_
     # container port where the metrics are exposed
     containerPort: 9091
     # @param serviceMonitor.labels ServiceMonitor extra labels
     labels: {}
     # @param serviceMonitor.annotations ServiceMonitor annotations
     annotations: {}
   
   # etcd configuration
   # use the FQDN address or the IP of the etcd
   etcd:
     # install etcd(v3) by default, set false if do not want to install 
etcd(v3) together
     enabled: true
     host:
       # host or ip e.g. http://172.20.128.89:2379
       - http://etcd.host:2379
     prefix: "/apisix"
     timeout: 30
   
     # if etcd.enabled is true, set more values of bitnami/etcd helm chart
     auth:
       rbac:
         # No authentication by default
         create: false
         user: ""
         password: ""
       tls:
         enabled: false
         existingSecret: ""
         certFilename: ""
         certKeyFilename: ""
         verify: true
         sni: ""
   
     service:
       port: 2379
   
     replicaCount: 3
   
   dashboard:
     enabled: true
     replicaCount: 1
   
     image:
       repository: apache/apisix-dashboard
       pullPolicy: IfNotPresent
       # Overrides the image tag whose default is the chart appVersion.
       tag: 2.13-alpine
   
     imagePullSecrets: []
     nameOverride: ""
     fullnameOverride: ""
   
     serviceAccount:
       # Specifies whether a service account should be created
       create: true
       # Annotations to add to the service account
       annotations: {}
       # The name of the service account to use.
       # If not set and create is true, a name is generated using the fullname 
template
       name: ""
   
     podAnnotations: {}
   
     podSecurityContext: {}
       # fsGroup: 2000
   
     securityContext: {}
       # capabilities:
       #   drop:
       #   - ALL
       # readOnlyRootFilesystem: true
       # runAsNonRoot: true
       # runAsUser: 1000
   
     config:
       conf:
         listen:
           host: 0.0.0.0
           port: 9000
         etcd:
           # Supports defining multiple etcd host addresses for an etcd cluster
           endpoints:
             - apisix-etcd:2379
           # apisix configurations prefix
           prefix: "/apisix"
           # Etcd basic auth info
           username: ~
           password: ~
         log:
           errorLog:
             level: warn
             filePath: /dev/stderr
           accessLog:
             filePath: /dev/stdout
   
       authentication:
         secret: secret
         expireTime: 3600
         users:
           - username: admin
             password: admin
   
     service:
       type: ClusterIP
       port: 80
   
       ingress:
         enabled: false
         # Kubernetes 1.18+ support ingressClassName attribute
         className: ""
         annotations: {}
           # kubernetes.io/ingress.class: nginx
           # kubernetes.io/tls-acme: "true"
         # domain access apisix example:
         # hosts:
         # - host: apisix-dashboard.local
         #    paths:
         #     - /*
         hosts:
           - host: apisix-dashboard.local
             paths: []
         tls: []
         #  - secretName: chart-example-tls
         #    hosts:
         #      - chart-example.local
   
       resources: {}
         # We usually recommend not to specify default resources and to leave 
this as a conscious
         # choice for the user. This also increases chances charts run on 
environments with little
         # resources, such as Minikube. If you do want to specify resources, 
uncomment the following
         # lines, adjust them as necessary, and remove the curly braces after 
'resources:'.
         # limits:
         #   cpu: 100m
         #   memory: 128Mi
         # requests:
         #   cpu: 100m
         #   memory: 128Mi
   
       autoscaling:
         enabled: false
         minReplicas: 1
         maxReplicas: 100
         targetCPUUtilizationPercentage: 80
         # targetMemoryUtilizationPercentage: 80
   
       nodeSelector: {}
   
       tolerations: []
   
       affinity: {}
     
   ingress-controller:
     enabled: false
   ```
   
   2. create a route
   
   ```json
   {
     "uri": "/mock/*",
     "name": "mock",
     "methods": [
       "GET",
       "POST",
       "PUT",
       "DELETE",
       "PATCH",
       "HEAD",
       "OPTIONS",
       "CONNECT",
       "TRACE"
     ],
     "plugins": {
       "ext-plugin-post-req": {
         "conf": [
           {
             "name": "rewrite",
             "value": "{\"enable\":\"feature\"}"
           }
         ],
         "disable": false
       },
       "ext-plugin-pre-req": {
         "disable": true
       }
     },
     "upstream": {
       "nodes": [
         {
           "host": "172.17.0.1",
           "port": 8081,
           "weight": 1
         }
       ],
       "timeout": {
         "connect": 6,
         "send": 6,
         "read": 6
       },
       "type": "roundrobin",
       "scheme": "http",
       "pass_host": "pass",
       "keepalive_pool": {
         "idle_timeout": 60,
         "requests": 1000,
         "size": 320
       }
     },
     "status": 1
   }
   ```
   
   3. query the route `curl http://localhost:${mapped port of apisix 
gateway}/mock/`
   
   ### Environment
   
   - APISIX version (run `apisix version`): 2.13.3
   - Operating system (run `uname -a`): Linux apisix-6878f46cb5-hps57 
5.15.0-47-generic #51-Ubuntu SMP Thu Aug 11 07:51:15 UTC 2022 x86_64 Linux  
(????? The image is supposed to be Alpine based)
   - OpenResty / Nginx version (run `openresty -V` or `nginx -V`): 1.21.4.1
   - Plugin runner version, for issues related to plugin runners: python plugin 
v 0.2.0
   - LuaRocks version, for installation issues (run `luarocks --version`):
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to