You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by me...@apache.org on 2020/02/28 00:46:49 UTC

[incubator-apisix] branch master updated: feature: support to load different config file by ENV `APISIX_PROFILE ` profile (#1147)

This is an automated email from the ASF dual-hosted git repository.

membphis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new b210a7b  feature: support to load different config file by ENV `APISIX_PROFILE ` profile (#1147)
b210a7b is described below

commit b210a7b866131b2f4df2d61c2c4fa99048b5074b
Author: qiujiayu <15...@qq.com>
AuthorDate: Fri Feb 28 08:46:42 2020 +0800

    feature: support to load different config file by ENV `APISIX_PROFILE ` profile (#1147)
---
 bin/apisix                       |  7 ++++++-
 doc/plugins/oauth.md             |  2 +-
 doc/profile-cn.md                | 42 ++++++++++++++++++++++++++++++++++++++
 lua/apisix/core/config_local.lua |  5 +++--
 lua/apisix/core/config_yaml.lua  | 11 +++++-----
 lua/apisix/core/profile.lua      | 34 +++++++++++++++++++++++++++++++
 lua/apisix/debug.lua             |  5 +++--
 t/APISIX.pm                      | 22 +++++++++++++++++---
 t/core/profile.t                 | 44 ++++++++++++++++++++++++++++++++++++++++
 9 files changed, 158 insertions(+), 14 deletions(-)

diff --git a/bin/apisix b/bin/apisix
index 5e68c3f..ff48af7 100755
--- a/bin/apisix
+++ b/bin/apisix
@@ -100,6 +100,8 @@ working_directory   /tmp/apisix_cores/;
 
 worker_shutdown_timeout 3;
 
+env APISIX_PROFILE;
+
 {% if stream_proxy then %}
 stream {
     lua_package_path  "$prefix/deps/share/lua/5.1/?.lua;/usr/share/lua/5.1/apisix/lua/?.lua;]=]
@@ -461,7 +463,10 @@ local function exec(command)
 end
 
 local function read_yaml_conf()
-    local ymal_conf, err = read_file(apisix_home .. "/conf/config.yaml")
+    local profile = require("apisix.core.profile")
+    profile.apisix_home = apisix_home .. "/"
+    local local_conf_path = profile:yaml_path("config")
+    local ymal_conf, err = read_file(local_conf_path)
     if not ymal_conf then
         return nil, err
     end
diff --git a/doc/plugins/oauth.md b/doc/plugins/oauth.md
index 4f98c1c..fb893b3 100644
--- a/doc/plugins/oauth.md
+++ b/doc/plugins/oauth.md
@@ -89,4 +89,4 @@ curl -i -X GET http://127.0.0.1:9080/get -H "Host: httpbin.org" -H "Authorizatio
 
 ## Troubleshooting
 
-Check/modify the DNS settings (`conf/config.yml) if APISIX cannot resolve/connect to the identity provider.
+Check/modify the DNS settings (`conf/config.yaml) if APISIX cannot resolve/connect to the identity provider.
diff --git a/doc/profile-cn.md b/doc/profile-cn.md
new file mode 100644
index 0000000..df9a214
--- /dev/null
+++ b/doc/profile-cn.md
@@ -0,0 +1,42 @@
+<!--
+#
+# 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 中对应的环境变量就是:`APISIX_PROFILE`。
+
+
+在没有设置`APISIX_PROFILE` 时,默认使用以下三个配置文件:
+
+* conf/config.yaml
+* conf/apisix.yaml
+* conf/debug.yaml
+
+如果设置了`APISIX_PROFILE`的值为`prod`,则使用以下三个配置文件:
+
+* conf/config-prod.yaml
+* conf/apisix-prod.yaml
+* conf/debug-prod.yaml
+
+通过这种方式虽然会增加配置文件的数量,但可以独立管理,再配置git等版本管理工具,还能更好实现版本管理。
diff --git a/lua/apisix/core/config_local.lua b/lua/apisix/core/config_local.lua
index a5d9d5e..bb32efc 100644
--- a/lua/apisix/core/config_local.lua
+++ b/lua/apisix/core/config_local.lua
@@ -15,11 +15,12 @@
 -- limitations under the License.
 --
 local log = require("apisix.core.log")
+local profile = require("apisix.core.profile")
 local yaml = require("tinyyaml")
-local ngx = ngx
 local io_open = io.open
 local type = type
-local local_conf_path = ngx.config.prefix() .. "conf/config.yaml"
+
+local local_conf_path = profile:yaml_path("config")
 local config_data
 
 
diff --git a/lua/apisix/core/config_yaml.lua b/lua/apisix/core/config_yaml.lua
index 6955a83..186ed01 100644
--- a/lua/apisix/core/config_yaml.lua
+++ b/lua/apisix/core/config_yaml.lua
@@ -21,6 +21,7 @@ local json         = require("apisix.core.json")
 local process      = require("ngx.process")
 local new_tab      = require("table.new")
 local check_schema = require("apisix.core.schema").check
+local profile      = require("apisix.core.profile")
 local lfs          = require("lfs")
 local exiting      = ngx.worker.exiting
 local insert_tab   = table.insert
@@ -36,7 +37,7 @@ local pcall        = pcall
 local io           = io
 local ngx          = ngx
 local re_find      = ngx.re.find
-local apisix_yaml_path  = ngx.config.prefix() .. "conf/apisix.yaml"
+local apisix_yaml_path = profile:yaml_path("apisix")
 local created_obj  = {}
 
 
@@ -100,7 +101,7 @@ local function read_apisix_yaml(pre_mtime)
 
     local apisix_yaml_new = yaml.parse(yaml_config)
     if not apisix_yaml_new then
-        log.error("failed to parse the content of file conf/apisix.yaml")
+        log.error("failed to parse the content of file " .. apisix_yaml_path)
         return
     end
 
@@ -116,7 +117,7 @@ local function sync_data(self)
 
     if not apisix_yaml_ctime then
         log.warn("wait for more time")
-        return nil, "failed to read local file conf/apisix.yaml"
+        return nil, "failed to read local file " .. apisix_yaml_path
     end
 
     if self.conf_version == apisix_yaml_ctime then
@@ -212,7 +213,7 @@ local function _automatic_fetch(premature, self)
         local ok, ok2, err = pcall(sync_data, self)
         if not ok then
             err = ok2
-            log.error("failed to fetch data from local file apisix.yaml: ",
+            log.error("failed to fetch data from local file " .. apisix_yaml_path .. ": ",
                       err, ", ", tostring(self))
             ngx_sleep(3)
             break
@@ -220,7 +221,7 @@ local function _automatic_fetch(premature, self)
         elseif not ok2 and err then
             if err ~= "timeout" and err ~= "Key not found"
                and self.last_err ~= err then
-                log.error("failed to fetch data from local file apisix.yaml: ",
+                log.error("failed to fetch data from local file " .. apisix_yaml_path .. ": ",
                           err, ", ", tostring(self))
             end
 
diff --git a/lua/apisix/core/profile.lua b/lua/apisix/core/profile.lua
new file mode 100644
index 0000000..339b7ea
--- /dev/null
+++ b/lua/apisix/core/profile.lua
@@ -0,0 +1,34 @@
+--
+-- 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.
+--
+
+local _M = {
+    version = 0.1,
+    profile = os.getenv("APISIX_PROFILE"),
+    apisix_home = (ngx and ngx.config.prefix()) or ""
+}
+
+
+function _M.yaml_path(self, file_name)
+    local file_path = self.apisix_home  .. "conf/" .. file_name
+    if self.profile then
+        file_path = file_path .. "-" .. self.profile
+    end
+    return file_path .. ".yaml"
+end
+
+
+return _M
diff --git a/lua/apisix/debug.lua b/lua/apisix/debug.lua
index 3156d1a..7f458fe 100644
--- a/lua/apisix/debug.lua
+++ b/lua/apisix/debug.lua
@@ -17,6 +17,7 @@
 local yaml         = require("tinyyaml")
 local log          = require("apisix.core.log")
 local json         = require("apisix.core.json")
+local profile      = require("apisix.core.profile")
 local process      = require("ngx.process")
 local lfs          = require("lfs")
 local io           = io
@@ -29,7 +30,7 @@ local setmetatable = setmetatable
 local pcall        = pcall
 local ipairs       = ipairs
 local unpack       = unpack
-local debug_yaml_path = ngx.config.prefix() .. "conf/debug.yaml"
+local debug_yaml_path = profile:yaml_path("debug")
 local debug_yaml
 local debug_yaml_ctime
 
@@ -85,7 +86,7 @@ local function read_debug_yaml()
 
     local debug_yaml_new = yaml.parse(yaml_config)
     if not debug_yaml_new then
-        log.error("failed to parse the content of file conf/debug.yaml")
+        log.error("failed to parse the content of file " .. debug_yaml_path)
         return
     end
 
diff --git a/t/APISIX.pm b/t/APISIX.pm
index f15b367..7e8755e 100644
--- a/t/APISIX.pm
+++ b/t/APISIX.pm
@@ -42,6 +42,21 @@ my $ssl_crt = read_file("conf/cert/apisix.crt");
 my $ssl_key = read_file("conf/cert/apisix.key");
 $yaml_config =~ s/node_listen: 9080/node_listen: 1984/;
 $yaml_config =~ s/enable_heartbeat: true/enable_heartbeat: false/;
+my $profile = $ENV{"APISIX_PROFILE"};
+
+
+my $apisix_file;
+my $debug_file;
+my $config_file;
+if ($profile) {
+    $apisix_file = "apisix-$profile.yaml";
+    $debug_file = "debug-$profile.yaml";
+    $config_file = "config-$profile.yaml";
+} else {
+    $apisix_file = "apisix.yaml";
+    $debug_file = "debug.yaml";
+    $config_file = "config.yaml";
+}
 
 
 add_block_preprocessor(sub {
@@ -51,6 +66,7 @@ add_block_preprocessor(sub {
     my $main_config = $block->main_config // <<_EOC_;
 worker_rlimit_core  500M;
 working_directory   $apisix_home;
+env APISIX_PROFILE;
 _EOC_
 
     $block->set_value("main_config", $main_config);
@@ -305,7 +321,7 @@ _EOC_
     my $user_apisix_yaml = $block->apisix_yaml // "";
     if ($user_apisix_yaml) {
         $user_apisix_yaml = <<_EOC_;
->>> ../conf/apisix.yaml
+>>> ../conf/$apisix_file
 $user_apisix_yaml
 _EOC_
     }
@@ -315,9 +331,9 @@ _EOC_
 
     my $user_files = $block->user_files;
     $user_files .= <<_EOC_;
->>> ../conf/debug.yaml
+>>> ../conf/$debug_file
 $user_debug_config
->>> ../conf/config.yaml
+>>> ../conf/$config_file
 $user_yaml_config
 >>> ../conf/cert/apisix.crt
 $ssl_crt
diff --git a/t/core/profile.t b/t/core/profile.t
new file mode 100644
index 0000000..12a1292
--- /dev/null
+++ b/t/core/profile.t
@@ -0,0 +1,44 @@
+#
+# 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.
+#
+BEGIN {
+    $ENV{APISIX_PROFILE} = "dev";
+}
+
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: set env "APISIX_PROFILE"
+--- config
+    location /t {
+        content_by_lua_block {
+            local profile = require("apisix.core.profile")
+            profile.apisix_home = "./test/"
+            local local_conf_path = profile:yaml_path("config")
+            ngx.say(local_conf_path)
+        }
+    }
+--- request
+GET /t
+--- response_body
+./test/conf/config-dev.yaml