Config Web manager.
WSGI application with a gunicorn running script. For reading and writing the JSON config file. E.g. with run with: python -m manager.server -b 127.0.0.1:9000 Get config with: curl --header "Accept: application/json" http://127.0.0.1:9000/config Get one setting with: curl --header "Accept: application/json" http://127.0.0.1:9000/your_setting Set config with: curl -H "Content-Type: application/json" -X POST -d 'your_json_config' \ --header "Accept: application/json" http://127.0.0.1:9000/config Set setting with: curl -H "Content-Type: application/json" -X POST -d '{"your_setting": value}' \ --header "Accept: application/json" http://127.0.0.1:9000/your_setting
This commit is contained in:
parent
9a6edf0020
commit
f6092a18bd
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Copyright (C) 2016 Entr'ouvert
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
E.g. with run with:
|
||||
python -m manager.server -b 127.0.0.1:9000
|
||||
|
||||
Get config with:
|
||||
curl --header "Accept: application/json" http://127.0.0.1:9000/config
|
||||
|
||||
Get one setting with:
|
||||
curl --header "Accept: application/json" http://127.0.0.1:9000/your_setting
|
||||
|
||||
Set config with:
|
||||
curl -H "Content-Type: application/json" -X POST -d 'your_json_config' \
|
||||
--header "Accept: application/json" http://127.0.0.1:9000/config
|
||||
|
||||
Set setting with:
|
||||
curl -H "Content-Type: application/json" -X POST -d '{"your_setting": value}' \
|
||||
--header "Accept: application/json" http://127.0.0.1:9000/your_setting
|
||||
'''
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
from gunicorn.app.wsgiapp import WSGIApplication
|
||||
|
||||
|
||||
class WSGIApplication(WSGIApplication):
|
||||
|
||||
def init(self, parser, opts, args):
|
||||
self.cfg.set("default_proc_name", "manager.wsgi:application")
|
||||
self.app_uri = "manager.wsgi:application"
|
||||
|
||||
sys.path.insert(0, os.getcwd())
|
||||
|
||||
|
||||
def main():
|
||||
WSGIApplication("%prog [OPTIONS]").run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,110 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Copyright (C) 2016 Entr'ouvert
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
'''
|
||||
|
||||
|
||||
import json
|
||||
|
||||
from config import Config
|
||||
|
||||
|
||||
class Manager:
|
||||
|
||||
def check_authz(self):
|
||||
return True
|
||||
|
||||
def root(self):
|
||||
data = {"Info": "Manager of RFID readers hosts."}
|
||||
return self.response(data)
|
||||
|
||||
def config(self):
|
||||
if self.environ['REQUEST_METHOD'] == 'POST':
|
||||
body_length = 0
|
||||
try:
|
||||
body_length = int(self.environ.get('CONTENT_LENGTH', 0))
|
||||
except ValueError:
|
||||
return self.not_found()
|
||||
json_data = self.environ['wsgi.input'].read(body_length)
|
||||
if json_data:
|
||||
data = None
|
||||
try:
|
||||
data = json.loads(json_data)
|
||||
except ValueError:
|
||||
return self.not_found()
|
||||
self.conf.set_config(data)
|
||||
data = self.conf.get_config()
|
||||
return self.response(data)
|
||||
|
||||
def setting(self, name):
|
||||
if self.environ['REQUEST_METHOD'] == 'POST':
|
||||
body_length = 0
|
||||
try:
|
||||
body_length = int(self.environ.get('CONTENT_LENGTH', 0))
|
||||
except ValueError:
|
||||
return self.not_found()
|
||||
json_data = self.environ['wsgi.input'].read(body_length)
|
||||
if json_data:
|
||||
data = None
|
||||
try:
|
||||
data = json.loads(json_data)
|
||||
except ValueError:
|
||||
return self.not_found()
|
||||
if len(data) != 1 or name not in data:
|
||||
return self.not_found()
|
||||
self.conf.set_setting(name, data[name])
|
||||
data = {name: self.conf.get_setting(name)}
|
||||
return self.response(data)
|
||||
|
||||
def not_found(self):
|
||||
data = {"Info": "Not found"}
|
||||
status = '404 NOT FOUND'
|
||||
return self.json_response(status, data)
|
||||
|
||||
def forbidden(self):
|
||||
data = {"Info": "Forbidden"}
|
||||
status = '403 FORBIDDEN'
|
||||
return self.json_response(status, data)
|
||||
|
||||
def response(self, data):
|
||||
status = '200 OK'
|
||||
return self.json_response(status, data)
|
||||
|
||||
def json_response(self, status, data):
|
||||
response_headers = [('Content-type', 'application/json')]
|
||||
self.start_response(status, response_headers)
|
||||
return [json.dumps(data)]
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
self.start_response = start_response
|
||||
self.environ = environ
|
||||
self.conf = Config()
|
||||
path_info = environ['PATH_INFO']
|
||||
if not self.check_authz():
|
||||
return self.forbidden()
|
||||
if path_info == '/':
|
||||
return self.root()
|
||||
if path_info == '/config':
|
||||
return self.config()
|
||||
else:
|
||||
data = self.conf.get_config()
|
||||
if path_info[1:] in data:
|
||||
return self.setting(path_info[1:])
|
||||
return self.not_found()
|
||||
|
||||
|
||||
application = Manager()
|
Reference in New Issue