You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

template.lua 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. --[[
  2. Copyright (c) 2019, Vsevolod Stakhov <vsevolod@highsecure.ru>
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ]]--
  13. local argparse = require "argparse"
  14. -- Define command line options
  15. local parser = argparse()
  16. :name "rspamadm template"
  17. :description "Apply jinja templates for strings/files"
  18. :help_description_margin(30)
  19. parser:argument "file"
  20. :description "File to process"
  21. :argname "<file>"
  22. :args "*"
  23. parser:flag "-n --no-vars"
  24. :description "Don't add Rspamd internal variables"
  25. parser:option "-e --env"
  26. :description "Load additional environment vars from specific file (name=value)"
  27. :argname "<filename>"
  28. :count "*"
  29. parser:option "-l --lua-env"
  30. :description "Load additional environment vars from specific file (lua source)"
  31. :argname "<filename>"
  32. :count "*"
  33. parser:mutex(
  34. parser:option "-s --suffix"
  35. :description "Store files with the new suffix"
  36. :argname "<suffix>",
  37. parser:flag "-i --inplace"
  38. :description "Replace input file(s)"
  39. )
  40. local lua_util = require "lua_util"
  41. local function set_env(opts, env)
  42. if opts.env then
  43. for _,fname in ipairs(opts.env) do
  44. for kv in assert(io.open(fname)):lines() do
  45. if not kv:match('%s*#.*') then
  46. local k,v = kv:match('([^=%s]+)%s*=%s*(.+)')
  47. if k and v then
  48. env[k] = v
  49. else
  50. io.write(string.format('invalid env line in %s: %s\n', fname, kv))
  51. end
  52. end
  53. end
  54. end
  55. end
  56. if opts.lua_env then
  57. for _,fname in ipairs(opts.env) do
  58. local ret,res_or_err = pcall(loadfile(fname))
  59. if not ret then
  60. io.write(string.format('cannot load %s: %s\n', fname, res_or_err))
  61. else
  62. if type(res_or_err) == 'table' then
  63. for k,v in pairs(res_or_err) do
  64. env[k] = lua_util.deepcopy(v)
  65. end
  66. else
  67. io.write(string.format('cannot load %s: not a table\n', fname))
  68. end
  69. end
  70. end
  71. end
  72. end
  73. local function read_file(file)
  74. local content
  75. if file == '-' then
  76. content = io.read("*all")
  77. else
  78. local f = assert(io.open(file, "rb"))
  79. content = f:read("*all")
  80. f:close()
  81. end
  82. return content
  83. end
  84. local function handler(args)
  85. local opts = parser:parse(args)
  86. local env = {}
  87. set_env(opts, env)
  88. if not opts.file or #opts.file == 0 then opts.file = {'-'} end
  89. for _,fname in ipairs(opts.file) do
  90. local content = read_file(fname)
  91. local res = lua_util.jinja_template(content, env, opts.no_vars)
  92. if opts.inplace then
  93. local nfile = string.format('%s.new', fname)
  94. local out = assert(io.open(nfile, 'w'))
  95. out:write(content)
  96. out:close()
  97. os.rename(nfile, fname)
  98. elseif opts.suffix then
  99. local nfile = string.format('%s.%s', opts.suffix)
  100. local out = assert(io.open(nfile, 'w'))
  101. out:write(content)
  102. out:close()
  103. else
  104. io.write(res)
  105. end
  106. end
  107. end
  108. return {
  109. handler = handler,
  110. description = parser._description,
  111. name = 'template'
  112. }