diff --git a/apisix/runner/server/config.py b/apisix/runner/server/config.py index 0234168..e2b8012 100644 --- a/apisix/runner/server/config.py +++ b/apisix/runner/server/config.py @@ -27,6 +27,7 @@ def __init__(self): init socket config handler """ self.file = "/tmp/runner.sock" + self.owner = "nobody" @property def file(self): @@ -36,6 +37,14 @@ def file(self): """ return self._file + @property + def owner(self): + """ + get config owner for socket + :return: + """ + return self._owner + @file.setter def file(self, file: str) -> None: """ @@ -44,6 +53,15 @@ def file(self, file: str) -> None: :return: """ self._file = file.replace("unix:", "") + + @owner.setter + def owner(self, owner: str) -> None: + """ + set config owner for socket + :param owner: + :return: + """ + self._owner = owner class _ConfigLogging: @@ -128,6 +146,12 @@ def _loading_config(self, config_path: str, config_name: str): socket_file = self._get_env_config(socket.get("file")) if socket_file: self.socket.file = socket_file + # owner config + socket_owner = self._get_env_config(socket.get("owner")) + if socket_owner: + self.socket.owner = socket_owner + else: + self.socket.owner = "nobody" # logging config logger = configs.get("logging", {}) diff --git a/apisix/runner/server/server.py b/apisix/runner/server/server.py index eb7cd3a..61cfd11 100644 --- a/apisix/runner/server/server.py +++ b/apisix/runner/server/server.py @@ -18,6 +18,7 @@ import os import socket +from pwd import getpwnam from threading import Thread as NewThread from apisix.runner.server.handle import Handle as NewServerHandle from apisix.runner.server.protocol import Protocol as NewServerProtocol @@ -82,6 +83,8 @@ def __init__(self, config: NewServerConfig): os.remove(self.fd) self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.sock.bind(self.fd) + user = getpwnam(config.socket.owner) + os.chown(self.fd, user.pw_uid, user.pw_gid) self.sock.listen(1024) self.logger = NewServerLogger(config.logging.level) diff --git a/conf/config.yaml b/conf/config.yaml index 5e847ab..81bdf6b 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -17,6 +17,8 @@ socket: file: $env.APISIX_LISTEN_ADDRESS # Environment variable or absolute path + # owner: somebody # optional Environment variable or user name + logging: level: warn # error warn info debug diff --git a/docs/en/latest/getting-started.md b/docs/en/latest/getting-started.md index 43f1671..b983a66 100644 --- a/docs/en/latest/getting-started.md +++ b/docs/en/latest/getting-started.md @@ -22,13 +22,13 @@ title: Getting started --> ## Overview + This document explains how to use Python Runner ## Prerequisites -* Python 3.7+ -* APISIX 2.7.0+ - +- Python 3.7+ +- APISIX 2.7.0+ ## Installation @@ -46,12 +46,14 @@ $ make install > Development Mode #### Run APISIX Python Runner + ```bash $ cd /path/to/apisix-python-plugin-runner $ make dev ``` #### Modify APISIX configuration file + ```bash $ vim /path/to/apisix/conf/config.yaml apisix: @@ -66,6 +68,7 @@ ext-plugin: > Production Mode #### Modify APISIX configuration file + ```bash $ vim /path/to/apisix/conf/config.yaml apisix: @@ -83,12 +86,14 @@ ext-plugin: $ vim /path/to/apisix-python-plugin-runner/conf/config.yaml socket: file: $env.APISIX_LISTEN_ADDRESS # Environment variable or absolute path + owner: $env.SOCKET_OWNER # optional Environment variable or user name. Default: 'nobody' (default user for Apisix runners) logging: level: debug # error warn info debug ``` ### Start or Restart APISIX + ```bash $ cd /path/to/apisix # Start or Restart @@ -96,6 +101,7 @@ $ ./bin/apisix [ start | restart ] ``` ### Configure APISIX Routing Rule + ```bash $ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { @@ -116,8 +122,8 @@ $ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f }' ``` - # Testing + ```bash $ curl http://127.0.0.1:9080/get -i HTTP/1.1 200 OK diff --git a/tests/conf/config.yaml b/tests/conf/config.yaml new file mode 100644 index 0000000..2e13aa3 --- /dev/null +++ b/tests/conf/config.yaml @@ -0,0 +1,23 @@ +# +# 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. +# + +socket: + file: $env.APISIX_LISTEN_ADDRESS # Environment variable or absolute path + + +logging: + level: warn # error warn info debug diff --git a/tests/conf/config_with_owner.yaml b/tests/conf/config_with_owner.yaml new file mode 100644 index 0000000..f7b8f74 --- /dev/null +++ b/tests/conf/config_with_owner.yaml @@ -0,0 +1,24 @@ +# +# 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. +# + +socket: + file: $env.APISIX_LISTEN_ADDRESS # Environment variable or absolute path + owner: somebody # optional Environment variable or user name + + +logging: + level: warn # error warn info debug diff --git a/tests/runner/server/test_config.py b/tests/runner/server/test_config.py index 5c95fcc..cb1ddc1 100644 --- a/tests/runner/server/test_config.py +++ b/tests/runner/server/test_config.py @@ -38,9 +38,11 @@ def test_config_default(): config.socket.file = "/test/runner.sock" assert config.socket.file == "/test/runner.sock" + assert config.socket.owner == "nobody" + def test_config_custom(): - config = NewServerConfig("%s" % os.path.abspath(os.path.join(os.getcwd())), "config.yaml") + config = NewServerConfig("%s" % os.path.abspath(os.path.join(os.getcwd(), "tests")), "config_with_owner.yaml") config.logging.level = "NOTSET" assert config.logging.level == logging.NOTSET @@ -56,3 +58,5 @@ def test_config_custom(): config.socket.file = "/test/runner.sock" assert config.socket.file == "/test/runner.sock" + + assert config.socket.owner == "somebody" diff --git a/tests/runner/server/test_server.py b/tests/runner/server/test_server.py index 8d407be..697dcbf 100644 --- a/tests/runner/server/test_server.py +++ b/tests/runner/server/test_server.py @@ -15,17 +15,22 @@ # limitations under the License. # +import os +from pwd import struct_passwd import socket import logging +from unittest.mock import patch from apisix.runner.server.server import Server as RunnerServer from apisix.runner.server.server import RPCRequest as RunnerRPCRequest from apisix.runner.server.logger import Logger as RunnerServerLogger from apisix.runner.server.config import Config as RunnerConfig - -def test_server(capsys): - config = RunnerConfig() +@patch('pwd.getpwnam', return_value=struct_passwd({"pw_name":"nobody", "pw_passwd":"x", "pw_uid":65534, "pw_gid":65534, "pw_gecos":"nobody", "pw_dir":"/", "pw_shell":"/sbin/nologin"})) +@patch('os.chown') +def test_server(mock_chown,mock_getpwnam,capsys): + config = RunnerConfig("%s" % os.path.abspath(os.path.join(os.getcwd(),"tests")), "config.yaml") server = RunnerServer(config) + mock_chown.assert_called_with("/tmp/runner.sock",65534,65534) del server captured = capsys.readouterr() assert captured.out.find("listening on unix") != -1