Kong/kong-python-pdk

Configuration schema - unable to configure properly

mpromny opened this issue · 12 comments

Hi,

I’m struggling with configuration schema in custom python plugin. Maybe you know, what i am doing wrong. All suggestions are welcome.

Please find below the details:

Plugin configuration:

#!/usr/bin/python3
import kong_pdk.pdk.kong as kong

Schema = (
    {"message": {"type": "string"},"var1": {"type": "string"}}
)

class Plugin(object):

    def __init__(self, config):
        self.config = config

    def access(self, kong: kong):
        message = "defaultMsg"
        if 'message' in self.config:
            message = self.config['message']


        variable_1 = "defaultVariable"
        if 'var1' in self.config:
            variable_1 = self.config['var1']

        kong.log.err("Message set in config: ", str(message))
        kong.log.err("Variable set in config: ", str(variable_1))


if __name__ == "__main__":
    from kong_pdk.cli import start_dedicated_server
    start_dedicated_server("py-hello", Plugin, version, priority)

Kong configuration:

apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
  name: py-hello
  annotations:
    kubernetes.io/ingress.class: kong
  labels:
    global: "true"
  config:
    message: "myMessage"
    var1: "myVariable"
plugin: py-hello

Unfortunately, it doesn’t work.

Thank you in advance,
Mateusz

Hi @mpromny you will need to activate the python plugin server in kong configuration. Please see
https://docs.konghq.com/gateway-oss/2.5.x/external-plugins/#example-configuration-2 as reference.
In k8s, kong config are passed as env variable for the pod.

Hi @fffonion,

Maybe I was slightly inaccurate in the description of my issue.

  • plugin has been deployed and it's working
  • it has been started as microservice (each plugin as separated server)

Issue:

  • I cannot correctly configure(activate) plugin in kong to set message field (neither declarative nor db-less config works)

DB-Less approach:

      - name: py-hello
        config:
          message: "testConfigSet"
or
      - name: py-hello
        config:
          message: 
            - "testConfigSet"

Error:

2021/08/04 18:08:26 [error] 1#0: init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:512: error parsing declarative config file /kong_dbless/kong.yml:
in 'plugins':
- in entry 2 of 'plugins':
in 'config':
in 'message': unknown field
stack traceback:
[C]: in function 'error'
/usr/local/share/lua/5.1/kong/init.lua:512: in function 'init'
init_by_lua:3: in main chunk

When I remove config part from plugin configuration in kong:

        config:
          message: "testConfigSet"

plugin is working and I can log that message has been set inside plugin:

DEBG - [23:36:31] rpc: #12 return: {'Data': {'Method': 'kong.log.err', 'Args': ('#####################', 'hello')}, 'EventId': 1}, context: ngx.timer

handled by:
        message = "hello"
        if 'message' in self.config:
            message = self.config['message']
        kong.log.err("#####################", message) 

Additional information:

  • from plugin I don't have access to the environment variables:
os.environ

returns

"environ({'SHLVL': '1', 'PWD': '/'})",)}

Additional question:
Do you know whether python server is deployed/started in virtual environment?

Hi @mpromny , this is a known issue that recently got fixed. It will be released with kong-python-pdk 0.2.7. As a workaround,
you could also use the shared server mode instead of embededded server (use kong-pythion-pluginserver instead of running py-hello directly).

@fffonion
Thank you again for your prompt response and quick fix.

@mpromny @fffonion Were you able to figure out how to expose environment variables inside the plugin. I am using pdk version 0.24 and also using python plugin server but still the plugin is not able to read the env variables set from outside

Hi @abhisheksharma2805 ,
Please note that you are using outdated version of the plugin (currently, 0.27 is the latest version)

Going back to the the main question.
Instead of environment variables we used config which allows to replace env variable and pass data as configuration variables.

So answering your question. We are using config feature to pass variables to the plugin.

Kind Regards,
Mateusz

@mpromny I understand that passing variables as config parameters will work. I might end up doing this way only. But still I wanted to understand why I can't use env variable inside the plugin
What if I want to update the PYTHONPATH (add some external library path) from outside

@abhisheksharma2805
In our case we are using embedded server (each plugin as separated server) so the situation may be slightly different. We have accepted the fact that plugin doesn't have access to the env variables.

What if I want to update the PYTHONPATH (add some external library path) from outside

I can only tell you how we approached to that. We modify python already at the level of building docker image (add "pip install" to the Kong Dockerfile). Plugins have access to those libraries and this is a solution that suits us. This approach should also work for you, especially that you are using one server for all your plugins.

@mpromny Thanks for clarifying.
I created a setup.py file for my package and installed it like python setup.py install (python will add the package in its path). This way there is no need to add library path in PYTHONPATH. This is done for now.
But I still think in future releases there should be a way to read env variables inside the plugin

Generally speaking as Kong starts the plugin server in a seperate process, I would say stripping all envrionment variables is a good practice for security since you don't have idea on certain environment variable would behave in other places.
Instead of passing environment variable down to the child process, maybe a PDK function to get environment from
Kong will be saner, just my 5 cents 😃 .

Closing for inactivity, please re-open if necessary ; )

A mechanism to get environment variables either through the Kong PDK or as a setting in the Kong configuration to expose certain environment variables to the PDK would be really great!

My usecase is having sensitive variables in the configuration. If I'm able to encrypt them as explained in #45 all I would need is an encryption key, environment variable seems like the right place for that.

Unless there is some sort of unique non-changing key within Kong that could be used for encryption already?