You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by GitBox <gi...@apache.org> on 2021/11/10 19:30:21 UTC

[GitHub] [apisix] bisakhmondal opened a new pull request #5479: feat: azure serverless functions plugin support

bisakhmondal opened a new pull request #5479:
URL: https://github.com/apache/apisix/pull/5479


   ### What this PR does / why we need it:
   <!--- Why is this change required? What problem does it solve? -->
   <!--- If it fixes an open issue, please link to the issue here. -->
   
   TODO: docs, tests, code rearrangement for aws lambda
   
   
   ### Pre-submission checklist:
   
   <!--
   Please follow the requirements:
   1. Use Draft if the PR is not ready to be reviewed
   2. Test is required for the feat/fix PR, unless you have a good reason
   3. Doc is required for the feat PR
   4. Use a new commit to resolve review instead of `push -f`
   5. Use "request review" to notify the reviewer once you have resolved the review
   -->
   
   
   * [x] Did you explain what problem does this PR solve? Or what new features have been added?
   * [ ] Have you added corresponding test cases?
   * [ ] Have you modified the corresponding document?
   * [x] Is this PR backward compatible? **If it is not backward compatible, please discuss on the [mailing list](https://github.com/apache/apisix/tree/master#community) first**
   


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] membphis commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
membphis commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r751935568



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,137 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local plugin = require("apisix.plugin")
+local ngx  = ngx
+local plugin_name = "azure-functions"
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 100, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local metadata_schema = {
+    type = "object",
+    properties = {
+        master_apikey = {type = "string", default = ""},
+        master_clientid = {type = "string", default = ""}
+    }
+}
+
+local _M = {
+    version = 0.1,
+    priority = -1900,
+    name = plugin_name,
+    schema = schema,
+    metadata_schema = metadata_schema
+}
+
+function _M.check_schema(conf, schema_type)
+    if schema_type == core.schema.TYPE_METADATA then
+        return core.schema.check(metadata_schema, conf)
+    end
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, err = core.request.get_body()
+
+    if err then
+        core.log.error("error while reading request body: " .. err)

Review comment:
       bad style, it should be `core.log.error("error while reading request body: ", err)`




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750978154



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,113 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, err = core.request.get_body()
+
+    if err then
+        core.log.error("error while reading request body: " .. err)
+        return 400
+    end
+
+    -- set authorization headers if not already set by the client
+    -- we are following not to overwrite the authz keys
+    if not headers["x-functions-key"] and
+            not headers["x-functions-clientid"] then
+        if conf.authorization then
+            headers["x-functions-key"] = conf.authorization.apikey or ""
+            headers["x-functions-clientid"] = conf.authorization.clientid or ""
+        else
+            headers["x-functions-key"] = getenv(env_key.API)
+            headers["x-functions-clientid"] = getenv(env_key.CLIENT_ID)
+        end
+    end
+
+    local params = {
+        method = ngx.req.get_method(),
+        body = req_body,
+        query = uri_args,
+        headers = headers,

Review comment:
       Do we need to remove the host header? Otherwise, the host of APISIX will be used. 




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] tokers commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
tokers commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r751131626



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()

Review comment:
       Agree, but it's better to add some hints in the document. @bisakhmondal @spacewander 




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750892372



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()

Review comment:
       thanks for pointing it out @tokers! 
   @spacewander even if it reads the content from a file, it reads everything in one go
   https://github.com/apache/apisix/blob/2c12b3695302f580a1498333aaafb68da26a3096/apisix/core/request.lua#L172-L181
   
   I think we should use chunked transfer encoding here to proxy the request with a large body size. WDYT?
   




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r751960482



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,137 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local plugin = require("apisix.plugin")
+local ngx  = ngx
+local plugin_name = "azure-functions"
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 100, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local metadata_schema = {
+    type = "object",
+    properties = {
+        master_apikey = {type = "string", default = ""},
+        master_clientid = {type = "string", default = ""}
+    }
+}
+
+local _M = {
+    version = 0.1,
+    priority = -1900,
+    name = plugin_name,
+    schema = schema,
+    metadata_schema = metadata_schema
+}
+
+function _M.check_schema(conf, schema_type)
+    if schema_type == core.schema.TYPE_METADATA then
+        return core.schema.check(metadata_schema, conf)
+    end
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, err = core.request.get_body()
+
+    if err then
+        core.log.error("error while reading request body: " .. err)

Review comment:
       Ack. Thanks for pointing it out! 




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750964510



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()
+
+
+    -- set authorization headers
+    if conf.authorization then
+        headers["x-functions-key"] = conf.authorization.apikey or ""
+        headers["x-functions-clientid"] = conf.authorization.clientid or ""
+    else
+        headers["x-functions-key"] = getenv(env_key.API)

Review comment:
       I change my mind. Maybe it could be easier to pass this argument via plugin metadata.




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750883106



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()

Review comment:
       I just realize it uses `core.request.get_body`, which will read data from file if need. BTW, we should check the err returned by this function.




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750892804



##########
File path: t/plugin/azure-functions.t
##########
@@ -0,0 +1,226 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+no_shuffle();
+
+add_block_preprocessor(sub {
+    my ($block) = @_;
+
+    if (!defined $block->additional_http_config) {

Review comment:
       Gotcha




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750816376



##########
File path: t/plugin/azure-functions.t
##########
@@ -0,0 +1,226 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+no_shuffle();
+
+add_block_preprocessor(sub {
+    my ($block) = @_;
+
+    if (!defined $block->additional_http_config) {

Review comment:
       We can use `http_config` to inject HTTP config, see https://github.com/apache/apisix/blob/master/t/discovery/consul_kv.t
   
   And I suggest you put `azure-demo` as https://github.com/apache/apisix/blob/2c12b3695302f580a1498333aaafb68da26a3096/t/lib/server.lua#L33
   
   There is no need to introduce a new server.

##########
File path: conf/config-default.yaml
##########
@@ -340,6 +340,7 @@ plugins:                          # plugin list (sorted by priority)
   - response-rewrite               # priority: 899
   #- dubbo-proxy                   # priority: 507
   - grpc-transcode                 # priority: 506
+  - azure-functions                # priority: 505

Review comment:
       Better to put it ahead of serverless-post-function

##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()
+
+
+    -- set authorization headers
+    if conf.authorization then
+        headers["x-functions-key"] = conf.authorization.apikey or ""
+        headers["x-functions-clientid"] = conf.authorization.clientid or ""
+    else
+        headers["x-functions-key"] = getenv(env_key.API)
+        headers["x-functions-clientid"] = getenv(env_key.CLIENT_ID)
+    end
+
+    local params = {
+        method = ngx.req.get_method(),
+        body = req_body,
+        query = uri_args,
+        headers = headers,
+        keepalive = conf.keepalive,
+        ssl_verify = conf.ssl_verify
+    }
+
+    -- Keepalive options
+    if conf.keepalive then
+        params.keepalive_timeout = conf.keepalive_timeout
+        params.keepalive_pool = conf.keepalive_pool
+    end
+
+    local httpc = http.new()
+    httpc:set_timeout(conf.timeout)
+
+    local res, err = httpc:request_uri(conf.function_uri, params)
+
+    if not res or err then
+        return core.response.exit(500, "failed to process azure function, err: " .. err)

Review comment:
       ```suggestion
           core.log.error("failed to process azure function, err: " .. err)
           return 503
   ```
   I think it will be safer not to return an internal error to the client.




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#issuecomment-972649578


   @bzp2010 
   I think we can use the product name directly (azure-functions in this case). It is easier to be searched.


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750916100



##########
File path: t/plugin/azure-functions.t
##########
@@ -0,0 +1,226 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+no_shuffle();
+
+add_block_preprocessor(sub {
+    my ($block) = @_;
+
+    if (!defined $block->additional_http_config) {

Review comment:
       Done, Is it okay now?
   




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r751805107



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,137 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local plugin = require("apisix.plugin")
+local ngx  = ngx
+local plugin_name = "azure-functions"
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 100, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local metadata_schema = {
+    type = "object",
+    properties = {
+        master_apikey = {type = "string", default = ""},
+        master_clientid = {type = "string", default = ""}
+    }
+}
+
+local _M = {
+    version = 0.1,
+    priority = -1900,
+    name = plugin_name,
+    schema = schema,
+    metadata_schema = metadata_schema
+}
+
+function _M.check_schema(conf, schema_type)
+    if schema_type == core.schema.TYPE_METADATA then
+        return core.schema.check(metadata_schema, conf)
+    end
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, err = core.request.get_body()
+
+    if err then
+        core.log.error("error while reading request body: " .. err)
+        return 400
+    end
+
+    -- set authorization headers if not already set by the client
+    -- we are following not to overwrite the authz keys
+    if not headers["x-functions-key"] and
+            not headers["x-functions-clientid"] then
+        if conf.authorization then
+            headers["x-functions-key"] = conf.authorization.apikey
+            headers["x-functions-clientid"] = conf.authorization.clientid
+        else
+            -- If neither api keys are set with the client request nor inside the plugin attributes
+            -- plugin will fallback to the master key (if any) present inside the metadata.
+            local metadata = plugin.plugin_metadata(plugin_name)
+            if metadata then
+                headers["x-functions-key"] = metadata.value.master_apikey
+                headers["x-functions-clientid"] = metadata.value.master_clientid
+            end
+        end
+    end
+
+    headers["Host"],  headers["host"] = nil, nil

Review comment:
       ```suggestion
       headers["host"] = nil
   ```
   is enough.
   
   The fetched header is in lowercase.

##########
File path: t/plugin/azure-functions.t
##########
@@ -0,0 +1,372 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+no_shuffle();
+
+add_block_preprocessor(sub {
+    my ($block) = @_;
+
+    my $inside_lua_block = $block->inside_lua_block // "";
+    chomp($inside_lua_block);
+    my $http_config = $block->http_config // <<_EOC_;
+
+    server {
+        listen 8765;
+
+        location /httptrigger {
+            content_by_lua_block {
+                ngx.req.read_body()
+                local msg = "faas invoked"
+                ngx.header['Content-Length'] = #msg + 1
+                ngx.header['X-Extra-Header'] = "MUST"
+                ngx.header['Connection'] = "Keep-Alive"
+                ngx.say(msg)
+            }
+        }
+
+        location /azure-demo {
+            content_by_lua_block {
+                $inside_lua_block
+            }
+        }
+    }
+_EOC_
+
+    $block->set_value("http_config", $http_config);
+
+    if (!$block->request) {
+        $block->set_value("request", "GET /t");
+    }
+    if (!$block->no_error_log && !$block->error_log) {
+        $block->set_value("no_error_log", "[error]\n[alert]");
+    }
+});
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: sanity
+--- config
+    location /t {
+        content_by_lua_block {
+            local plugin = require("apisix.plugins.azure-functions")
+            local conf = {
+                function_uri = "http://some-url.com"
+            }
+            local ok, err = plugin.check_schema(conf)
+            if not ok then
+                ngx.say(err)
+            end
+            ngx.say("done")
+        }
+    }
+--- response_body
+done
+
+
+
+=== TEST 2: function_uri missing
+--- config
+    location /t {
+        content_by_lua_block {
+            local plugin = require("apisix.plugins.azure-functions")
+            local ok, err = plugin.check_schema({})
+            if not ok then
+                ngx.say(err)
+            else
+                ngx.say("done")
+            end
+        }
+    }
+--- response_body
+property "function_uri" is required
+
+
+
+=== TEST 3: create route with azure-function plugin enabled
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+
+            local code, body = t('/apisix/admin/routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "plugins": {
+                            "azure-functions": {
+                                "function_uri": "http://localhost:8765/httptrigger"
+                            }
+                        },
+                        "upstream": {
+                            "nodes": {
+                                "127.0.0.1:1982": 1
+                            },
+                            "type": "roundrobin"
+                        },
+                        "uri": "/azure"
+                }]],
+                [[{
+                    "node": {
+                        "value": {
+                            "plugins": {
+                                "azure-functions": {
+                                    "keepalive": true,
+                                    "timeout": 3000,
+                                    "ssl_verify": true,
+                                    "keepalive_timeout": 60000,
+                                    "keepalive_pool": 5,
+                                    "function_uri": "http://localhost:8765/httptrigger"
+                                }
+                            },
+                            "upstream": {
+                                "nodes": {
+                                    "127.0.0.1:1982": 1
+                                },
+                                "type": "roundrobin"
+                            },
+                            "uri": "/azure"
+                        },
+                        "key": "/apisix/routes/1"
+                    },
+                    "action": "set"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say("fail")
+                return
+            end
+
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 4: Test plugin endpoint
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local core = require("apisix.core")
+
+            local code, _, body, headers = t("/azure", "GET")
+             if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            -- headers proxied 2 times -- one by plugin, another by this test case
+            core.response.set_header(headers)
+            ngx.print(body)
+        }
+    }
+--- response_body
+faas invoked
+--- response_headers
+Content-Length: 13
+X-Extra-Header: MUST
+
+
+
+=== TEST 5: http2 check response body and headers
+--- http2
+--- exec
+curl -XGET --http2 --http2-prior-knowledge localhost:1984/azure

Review comment:
       We can use regular `--- request` to send http2 request, see
   https://github.com/openresty/test-nginx/blob/9d5a20f884d67974f9eafeed5a1540cd32945fb2/lib/Test/Nginx/Socket.pm#L2310




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] membphis merged pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
membphis merged pull request #5479:
URL: https://github.com/apache/apisix/pull/5479


   


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750917519



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()

Review comment:
       I think normally people don't need to submit big data to azure functions. We can keep this function unchanged for now.




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r751275491



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()
+
+
+    -- set authorization headers
+    if conf.authorization then
+        headers["x-functions-key"] = conf.authorization.apikey or ""
+        headers["x-functions-clientid"] = conf.authorization.clientid or ""
+    else
+        headers["x-functions-key"] = getenv(env_key.API)

Review comment:
       Removed env vars and added metadata as a fallback option




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r751909344



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,137 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local plugin = require("apisix.plugin")
+local ngx  = ngx
+local plugin_name = "azure-functions"
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 100, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local metadata_schema = {
+    type = "object",
+    properties = {
+        master_apikey = {type = "string", default = ""},
+        master_clientid = {type = "string", default = ""}
+    }
+}
+
+local _M = {
+    version = 0.1,
+    priority = -1900,
+    name = plugin_name,
+    schema = schema,
+    metadata_schema = metadata_schema
+}
+
+function _M.check_schema(conf, schema_type)
+    if schema_type == core.schema.TYPE_METADATA then
+        return core.schema.check(metadata_schema, conf)
+    end
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, err = core.request.get_body()
+
+    if err then
+        core.log.error("error while reading request body: " .. err)
+        return 400
+    end
+
+    -- set authorization headers if not already set by the client
+    -- we are following not to overwrite the authz keys
+    if not headers["x-functions-key"] and
+            not headers["x-functions-clientid"] then
+        if conf.authorization then
+            headers["x-functions-key"] = conf.authorization.apikey
+            headers["x-functions-clientid"] = conf.authorization.clientid
+        else
+            -- If neither api keys are set with the client request nor inside the plugin attributes
+            -- plugin will fallback to the master key (if any) present inside the metadata.
+            local metadata = plugin.plugin_metadata(plugin_name)
+            if metadata then
+                headers["x-functions-key"] = metadata.value.master_apikey
+                headers["x-functions-clientid"] = metadata.value.master_clientid
+            end
+        end
+    end
+
+    headers["Host"],  headers["host"] = nil, nil

Review comment:
       Cool




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bzp2010 commented on pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bzp2010 commented on pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#issuecomment-972631204


   I have a question, should we standardize the naming of all serverless plugins? such as `xxx-function` or `xxx-serverless` 🤔


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750883709



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()
+
+
+    -- set authorization headers
+    if conf.authorization then
+        headers["x-functions-key"] = conf.authorization.apikey or ""
+        headers["x-functions-clientid"] = conf.authorization.clientid or ""
+    else
+        headers["x-functions-key"] = getenv(env_key.API)

Review comment:
       We need to expose the AZURE_FUNCTIONS_APIKEY via `env AZURE_FUNCTIONS_APIKEY`, if this plugin is enabled. Nginx will hide all environment variables by default.




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r751922165



##########
File path: t/plugin/azure-functions.t
##########
@@ -0,0 +1,372 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+no_shuffle();
+
+add_block_preprocessor(sub {
+    my ($block) = @_;
+
+    my $inside_lua_block = $block->inside_lua_block // "";
+    chomp($inside_lua_block);
+    my $http_config = $block->http_config // <<_EOC_;
+
+    server {
+        listen 8765;
+
+        location /httptrigger {
+            content_by_lua_block {
+                ngx.req.read_body()
+                local msg = "faas invoked"
+                ngx.header['Content-Length'] = #msg + 1
+                ngx.header['X-Extra-Header'] = "MUST"
+                ngx.header['Connection'] = "Keep-Alive"
+                ngx.say(msg)
+            }
+        }
+
+        location /azure-demo {
+            content_by_lua_block {
+                $inside_lua_block
+            }
+        }
+    }
+_EOC_
+
+    $block->set_value("http_config", $http_config);
+
+    if (!$block->request) {
+        $block->set_value("request", "GET /t");
+    }
+    if (!$block->no_error_log && !$block->error_log) {
+        $block->set_value("no_error_log", "[error]\n[alert]");
+    }
+});
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: sanity
+--- config
+    location /t {
+        content_by_lua_block {
+            local plugin = require("apisix.plugins.azure-functions")
+            local conf = {
+                function_uri = "http://some-url.com"
+            }
+            local ok, err = plugin.check_schema(conf)
+            if not ok then
+                ngx.say(err)
+            end
+            ngx.say("done")
+        }
+    }
+--- response_body
+done
+
+
+
+=== TEST 2: function_uri missing
+--- config
+    location /t {
+        content_by_lua_block {
+            local plugin = require("apisix.plugins.azure-functions")
+            local ok, err = plugin.check_schema({})
+            if not ok then
+                ngx.say(err)
+            else
+                ngx.say("done")
+            end
+        }
+    }
+--- response_body
+property "function_uri" is required
+
+
+
+=== TEST 3: create route with azure-function plugin enabled
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+
+            local code, body = t('/apisix/admin/routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "plugins": {
+                            "azure-functions": {
+                                "function_uri": "http://localhost:8765/httptrigger"
+                            }
+                        },
+                        "upstream": {
+                            "nodes": {
+                                "127.0.0.1:1982": 1
+                            },
+                            "type": "roundrobin"
+                        },
+                        "uri": "/azure"
+                }]],
+                [[{
+                    "node": {
+                        "value": {
+                            "plugins": {
+                                "azure-functions": {
+                                    "keepalive": true,
+                                    "timeout": 3000,
+                                    "ssl_verify": true,
+                                    "keepalive_timeout": 60000,
+                                    "keepalive_pool": 5,
+                                    "function_uri": "http://localhost:8765/httptrigger"
+                                }
+                            },
+                            "upstream": {
+                                "nodes": {
+                                    "127.0.0.1:1982": 1
+                                },
+                                "type": "roundrobin"
+                            },
+                            "uri": "/azure"
+                        },
+                        "key": "/apisix/routes/1"
+                    },
+                    "action": "set"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say("fail")
+                return
+            end
+
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 4: Test plugin endpoint
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local core = require("apisix.core")
+
+            local code, _, body, headers = t("/azure", "GET")
+             if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            -- headers proxied 2 times -- one by plugin, another by this test case
+            core.response.set_header(headers)
+            ngx.print(body)
+        }
+    }
+--- response_body
+faas invoked
+--- response_headers
+Content-Length: 13
+X-Extra-Header: MUST
+
+
+
+=== TEST 5: http2 check response body and headers
+--- http2
+--- exec
+curl -XGET --http2 --http2-prior-knowledge localhost:1984/azure

Review comment:
       Nice, it is. Updated




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r751273433



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,113 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, err = core.request.get_body()
+
+    if err then
+        core.log.error("error while reading request body: " .. err)
+        return 400
+    end
+
+    -- set authorization headers if not already set by the client
+    -- we are following not to overwrite the authz keys
+    if not headers["x-functions-key"] and
+            not headers["x-functions-clientid"] then
+        if conf.authorization then
+            headers["x-functions-key"] = conf.authorization.apikey or ""
+            headers["x-functions-clientid"] = conf.authorization.clientid or ""
+        else
+            headers["x-functions-key"] = getenv(env_key.API)
+            headers["x-functions-clientid"] = getenv(env_key.CLIENT_ID)
+        end
+    end
+
+    local params = {
+        method = ngx.req.get_method(),
+        body = req_body,
+        query = uri_args,
+        headers = headers,

Review comment:
       Done, It was the root of many problem.




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750896111



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()
+
+
+    -- set authorization headers
+    if conf.authorization then
+        headers["x-functions-key"] = conf.authorization.apikey or ""
+        headers["x-functions-clientid"] = conf.authorization.clientid or ""
+    else
+        headers["x-functions-key"] = getenv(env_key.API)

Review comment:
       You mean like this `env AZURE_FUNCTIONS_APIKEY="key" make run`?
   Or you are suggesting to update something?
   




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] tokers commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
tokers commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750814360



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()

Review comment:
       What if the request body are large and we cannot load it into memory totally?




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750966548



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()
+
+
+    -- set authorization headers
+    if conf.authorization then
+        headers["x-functions-key"] = conf.authorization.apikey or ""
+        headers["x-functions-clientid"] = conf.authorization.clientid or ""
+    else
+        headers["x-functions-key"] = getenv(env_key.API)

Review comment:
       Metadata won't be a great fit, IMHO. There might be multiple instances of plugins linked to different routes and we can't force users to use the same key they put into the metadata schema(must be the master key, instead of function-specific keys). This clearly violates principle of Least Access Privileges, isn't it?
   




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750823488



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()

Review comment:
       The body will be missing when it is larger than client_body_buffer_size (8k by default)
   We can read the body by ourselves via ngx.req.socket? See https://github.com/openresty/lua-resty-upload/blob/master/lib/resty/upload.lua
   
   We can do it in the next PR.




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750887123



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()
+
+
+    -- set authorization headers
+    if conf.authorization then
+        headers["x-functions-key"] = conf.authorization.apikey or ""
+        headers["x-functions-clientid"] = conf.authorization.clientid or ""
+    else
+        headers["x-functions-key"] = getenv(env_key.API)
+        headers["x-functions-clientid"] = getenv(env_key.CLIENT_ID)
+    end
+
+    local params = {
+        method = ngx.req.get_method(),
+        body = req_body,
+        query = uri_args,
+        headers = headers,
+        keepalive = conf.keepalive,
+        ssl_verify = conf.ssl_verify
+    }
+
+    -- Keepalive options
+    if conf.keepalive then
+        params.keepalive_timeout = conf.keepalive_timeout
+        params.keepalive_pool = conf.keepalive_pool
+    end
+
+    local httpc = http.new()
+    httpc:set_timeout(conf.timeout)
+
+    local res, err = httpc:request_uri(conf.function_uri, params)
+
+    if not res or err then
+        return core.response.exit(500, "failed to process azure function, err: " .. err)

Review comment:
       Ack




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750918991



##########
File path: apisix/plugins/azure-functions.lua
##########
@@ -0,0 +1,104 @@
+--
+-- 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 core = require("apisix.core")
+local http = require("resty.http")
+local ngx  = ngx
+local getenv = os.getenv
+local plugin_name = "azure-functions"
+
+local env_key = {
+    API = "AZURE_FUNCTIONS_APIKEY",
+    CLIENT_ID = "AZURE_FUNCTIONS_CLIENTID"
+}
+
+local schema = {
+    type = "object",
+    properties = {
+        function_uri = {type = "string"},
+        authorization = {
+            type = "object",
+            properties = {
+                apikey = {type = "string"},
+                clientid = {type = "string"}
+            }
+        },
+        timeout = {type = "integer", minimum = 1000, default = 3000},
+        ssl_verify = {type = "boolean", default = true},
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5}
+    },
+    required = {"function_uri"}
+}
+
+local _M = {
+    version = 0.1,
+    priority = 505,
+    name = plugin_name,
+    schema = schema,
+}
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+function _M.access(conf, ctx)
+    local uri_args = core.request.get_uri_args(ctx)
+    local headers = core.request.headers(ctx) or {}
+    local req_body, _ = core.request.get_body()
+
+
+    -- set authorization headers
+    if conf.authorization then
+        headers["x-functions-key"] = conf.authorization.apikey or ""
+        headers["x-functions-clientid"] = conf.authorization.clientid or ""
+    else
+        headers["x-functions-key"] = getenv(env_key.API)

Review comment:
       Like https://github.com/apache/apisix/blob/2c12b3695302f580a1498333aaafb68da26a3096/apisix/cli/ngx_tpl.lua#L52, but only when this plugin is enabled:
   https://github.com/apache/apisix/blob/2c12b3695302f580a1498333aaafb68da26a3096/apisix/cli/ngx_tpl.lua#L209




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] bisakhmondal commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
bisakhmondal commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750915952



##########
File path: conf/config-default.yaml
##########
@@ -340,6 +340,7 @@ plugins:                          # plugin list (sorted by priority)
   - response-rewrite               # priority: 899
   #- dubbo-proxy                   # priority: 507
   - grpc-transcode                 # priority: 506
+  - azure-functions                # priority: 505

Review comment:
       What should be the priority value, negative?




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix] spacewander commented on a change in pull request #5479: feat(plugin): azure serverless functions

Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #5479:
URL: https://github.com/apache/apisix/pull/5479#discussion_r750961796



##########
File path: conf/config-default.yaml
##########
@@ -340,6 +340,7 @@ plugins:                          # plugin list (sorted by priority)
   - response-rewrite               # priority: 899
   #- dubbo-proxy                   # priority: 507
   - grpc-transcode                 # priority: 506
+  - azure-functions                # priority: 505

Review comment:
       priority: -1900?




-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org