1 # Copyright (c) 2021 Intel and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """Nginx Configuration File Generator library.
17 from resources.libraries.python.ssh import exec_cmd_no_error
18 from resources.libraries.python.topology import NodeType
19 from resources.libraries.python.NginxUtil import NginxUtil
21 __all__ = [u"NginxConfigGenerator"]
24 class NginxConfigGenerator:
25 """NGINX Configuration File Generator."""
28 """Initialize library."""
29 # VPP Node to apply configuration on
31 # NGINX Startup config location
32 self._nginx_path = u"/usr/local/nginx/"
33 # Serialized NGinx Configuration
34 self._nginx_config = u""
36 self._nodeconfig = dict()
38 def set_node(self, node):
41 :param node: Node to store configuration on.
43 :raises RuntimeError: If Node type is not DUT.
45 if node[u"type"] != NodeType.DUT:
47 u"Startup config can only be applied to DUTnode."
51 def set_nginx_path(self, packages_dir, nginx_version):
52 """Set NGINX Conf Name.
54 :param packages_dir: NGINX install path.
55 :param nginx_version: Test NGINX version.
56 :type packages_dir: str
57 :type nginx_version: str
58 :raises RuntimeError: If Node type is not DUT.
61 self._nginx_path = f"{packages_dir}/nginx-{nginx_version}"
63 def add_http_server_listen(self, value):
64 """Add Http Server listen port configuration."""
65 path = [u"http", u"server", u"listen"]
66 self.add_config_item(self._nodeconfig, value, path)
68 def add_http_server_root(self, value=u"html"):
69 """Add Http Server root configuration."""
70 path = [u"http", u"server", u"root"]
71 self.add_config_item(self._nodeconfig, value, path)
73 def add_http_server_index(self, value=u"index.html index.htm"):
74 """Add Http Server index configuration."""
75 path = [u"http", u"server", u"index"]
76 self.add_config_item(self._nodeconfig, value, path)
78 def add_config_item(self, config, value, path):
79 """Add NGINX configuration item.
81 :param config: Startup configuration of node.
82 :param value: Value to insert.
83 :param path: Path where to insert item.
89 config[path[0]] = value
91 if path[0] not in config:
92 config[path[0]] = dict()
93 elif isinstance(config[path[0]], str):
94 config[path[0]] = dict() if config[path[0]] == u"" \
95 else {config[path[0]]: u""}
96 self.add_config_item(config[path[0]], value, path[1:])
98 def dump_config(self, obj, level=-1):
99 """Dump the startup configuration in NGINX config format.
101 :param obj: Python Object to print.
102 :param level: Nested level for indentation.
109 self._nginx_config += f"{level * indent}{{\n"
110 if isinstance(obj, dict):
111 for key, val in obj.items():
112 if hasattr(val, u"__iter__") and not isinstance(val, str):
113 self._nginx_config += f"{(level + 1) * indent}{key}\n"
114 self.dump_config(val, level + 1)
116 self._nginx_config += f"{(level + 1) * indent}" \
120 self._nginx_config += f"{(level + 1) * indent}{val};\n"
122 self._nginx_config += f"{level * indent}}}\n"
124 def write_config(self, filename=None):
125 """Generate and write NGINX startup configuration to file.
127 :param filename: NGINX configuration file name.
131 filename = f"{self._nginx_path}/conf/nginx.conf"
132 self.dump_config(self._nodeconfig)
133 cmd = f"echo \"{self._nginx_config}\" | sudo tee {filename}"
135 self._node, cmd, message=u"Writing config file failed!"
138 def add_http_server_location(self, size):
139 """Add Http Server location configuration.
141 :param size: File size.
147 files = f"{int(size / 1024)}KB.json"
149 files = f"{size}B.json"
151 size_str = size * u"x"
152 value = "200 '%s'" % size_str
153 path = [u"http", u"server", f"location /{key}", u"return"]
154 self.add_config_item(self._nodeconfig, value, path)
156 def add_http_access_log(self, value=u"off"):
157 """Add Http access_log configuration."""
158 path = [u"http", u"access_log"]
159 self.add_config_item(self._nodeconfig, value, path)
161 def add_http_include(self, value=u"mime.types"):
162 """Add Http include configuration."""
163 path = [u"http", u"include"]
164 self.add_config_item(self._nodeconfig, value, path)
166 def add_http_default_type(self, value=u"application/octet-stream"):
167 """Add Http default_type configuration."""
168 path = [u"http", u"default_type"]
169 self.add_config_item(self._nodeconfig, value, path)
171 def add_http_sendfile(self, value=u"on"):
172 """Add Http sendfile configuration."""
173 path = [u"http", u"sendfile"]
174 self.add_config_item(self._nodeconfig, value, path)
176 def add_http_keepalive_timeout(self, value):
177 """Add Http keepalive alive timeout configuration."""
178 path = [u"http", u"keepalive_timeout"]
179 self.add_config_item(self._nodeconfig, value, path)
181 def add_http_keepalive_requests(self, value):
182 """Add Http keepalive alive requests configuration."""
183 path = [u"http", u"keepalive_requests"]
184 self.add_config_item(self._nodeconfig, value, path)
186 def add_events_use(self, value=u"epoll"):
187 """Add Events use configuration."""
188 path = [u"events", u"use"]
189 self.add_config_item(self._nodeconfig, value, path)
191 def add_events_worker_connections(self, value=10240):
192 """Add Events worker connections configuration."""
193 path = [u"events", u"worker_connections"]
194 self.add_config_item(self._nodeconfig, value, path)
196 def add_events_accept_mutex(self, value=u"off"):
197 """Add Events accept mutex configuration."""
198 path = [u"events", u"accept_mutex"]
199 self.add_config_item(self._nodeconfig, value, path)
201 def add_events_multi_accept(self, value=u"off"):
202 """Add Events multi accept configuration."""
203 path = [u"events", u"multi_accept"]
204 self.add_config_item(self._nodeconfig, value, path)
206 def add_worker_rlimit_nofile(self, value=10240):
207 """Add Events worker rlimit nofile configuration."""
208 path = [u"worker_rlimit_nofile"]
209 self.add_config_item(self._nodeconfig, value, path)
211 def add_master_process(self, value=u"on"):
212 """Add master process configuration."""
213 path = [u"master_process"]
214 self.add_config_item(self._nodeconfig, value, path)
216 def add_daemon(self, value=u"off"):
217 """Add daemon configuration."""
219 self.add_config_item(self._nodeconfig, value, path)
221 def add_worker_processes(self, value, smt_used):
222 """Add worker processes configuration."""
223 # nginx workers : vpp used phy workers = 2:1
228 path = [u"worker_processes"]
229 self.add_config_item(self._nodeconfig, value, path)
231 def apply_config(self, filename=None, verify_nginx=True):
232 """Generate and write NGINX configuration to file and
233 verify configuration.
235 :param filename: NGINX configuration file name.
236 :param verify_nginx: Verify NGINX configuration.
238 :type verify_nginx: bool
240 self.write_config(filename=filename)
242 app_path = f"{self._nginx_path}/sbin/nginx"
244 NginxUtil.nginx_config_verify(self._node, app_path)