add synergy CLI

Change-Id: Ibd60ee3f448873e381126ff35a635e84971ab137
This commit is contained in:
Vincent Llorens 2016-05-30 14:03:38 +02:00 committed by Lisa Zangrando
parent 31d50774e7
commit a56f18470f
6 changed files with 1107 additions and 0 deletions

View File

@ -27,6 +27,12 @@ scripts =
synergy.managers =
timer = synergy.examples.timer_manager:TimerManager
synergy.commands =
list = synergy.client.command:LIST
status = synergy.client.command:STATUS
start = synergy.client.command:START
stop = synergy.client.command:STOP
[build_sphinx]
source-dir = doc/source
build-dir = doc/build

View File

258
synergy/client/command.py Normal file
View File

@ -0,0 +1,258 @@
import requests
__author__ = "Lisa Zangrando"
__email__ = "lisa.zangrando[AT]pd.infn.it"
__copyright__ = """Copyright (c) 2015 INFN - INDIGO-DataCloud
All Rights Reserved
Licensed under the Apache License, Version 2.0;
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."""
"""
class BaseCommand(object):
def __init__(self, name):
self.name = name
self.parameters = {}
self.results = {}
def getName(self):
return self.name
def getParameters(self):
return self.parameters
def addParameter(self, name, value):
self.parameters[name] = value
def getParameter(self, name):
return self.parameters.get(name, None)
def getResults(self):
return self.results
def addResult(self, name, value):
self.results[name] = value
def getResult(self, name):
return self.getResults().get(name, None)
def setResults(self, data):
self.results = data
class HTTPCommand(BaseCommand):
"""
class HTTPCommand(object):
def __init__(self, name):
self.name = name
def getName(self):
return self.name
# def __init__(self, name):
# super(HTTPCommand, self).__init__(name)
def configureParser(self, subparser):
raise NotImplementedError("not implemented!")
def log(self):
raise NotImplementedError("not implemented!")
def sendRequest(self, synergy_url, payload=None):
request = requests.get(synergy_url, params=payload)
if request.status_code != requests.codes.ok:
# print(request.reason)
# print(request.status_code)
request.raise_for_status()
self.results = request.json()
# self.setResults(request.json())
return request
def getResults(self):
return self.results
class LIST(HTTPCommand):
def __init__(self):
super(LIST, self).__init__("list")
def configureParser(self, subparser):
subparser.add_parser("list", add_help=True, help="list the managers")
def sendRequest(self, synergy_url, args=None):
super(LIST, self).sendRequest(synergy_url + "/synergy/list")
def log(self):
results = self.getResults()
max_project_id = max(len(max(results, key=len)), len("manager"))
separator_str = "-" * (max_project_id + 4) + "\n"
format_str = "| {0:%ss} |\n" % (max_project_id)
msg = separator_str
msg += format_str.format("manager")
msg += separator_str
for manager in results:
msg += format_str.format(manager)
msg += separator_str
print(msg)
class START(HTTPCommand):
def __init__(self):
super(START, self).__init__("start")
def configureParser(self, subparser):
parser = subparser.add_parser("start",
add_help=True,
help="start the managers")
parser.add_argument("manager", help="the manager to be started")
def sendRequest(self, synergy_url, args):
super(START, self).sendRequest(synergy_url + "/synergy/start",
{"manager": args.manager})
def log(self):
results = self.getResults()
max_manager = max(len(max(results.keys(), key=len)), len("manager"))
max_status = len("status")
max_msg = len("message")
for result in results.values():
max_status = max(len(str(result["status"])), max_status)
max_msg = max(len(str(result["message"])), max_msg)
separator_str = "-" * (max_manager + max_status + max_msg + 10) + "\n"
format_str = "| {0:%ss} | {1:%ss} | {2:%ss} |\n" % (max_manager,
max_status,
max_msg)
msg = separator_str
msg += format_str.format("manager", "status", "message")
msg += separator_str
for manager, values in results.items():
msg += format_str.format(manager,
values["status"],
values["message"])
msg += separator_str
print(msg)
class STOP(HTTPCommand):
def __init__(self):
super(STOP, self).__init__("stop")
def configureParser(self, subparser):
parser = subparser.add_parser("stop",
add_help=True,
help="stop the managers")
parser.add_argument("manager", help="the manager to be stopped")
def sendRequest(self, synergy_url, args):
super(STOP, self).sendRequest(synergy_url + "/synergy/stop",
{"manager": args.manager})
def log(self):
results = self.getResults()
max_manager = max(len(max(results.keys(), key=len)), len("manager"))
max_status = len("status")
max_msg = len("message")
for result in results.values():
max_status = max(len(str(result["status"])), max_status)
max_msg = max(len(str(result["message"])), max_msg)
separator_str = "-" * (max_manager + max_status + max_msg + 10) + "\n"
format_str = "| {0:%ss} | {1:%ss} | {2:%ss} |\n" % (max_manager,
max_status,
max_msg)
msg = separator_str
msg += format_str.format("manager", "status", "message")
msg += separator_str
for manager, values in results.items():
msg += format_str.format(manager,
values["status"],
values["message"])
msg += separator_str
print(msg)
class STATUS(HTTPCommand):
def __init__(self):
super(STATUS, self).__init__("status")
def configureParser(self, subparser):
parser = subparser.add_parser("status",
add_help=True,
help="retrieve the manager's status")
parser.add_argument("manager", nargs='*', help="the managers list")
def sendRequest(self, synergy_url, args):
super(STATUS, self).sendRequest(synergy_url + "/synergy/status",
{"manager": args.manager})
def log(self):
results = self.getResults()
max_project_id = max(len(max(results.keys(), key=len)), len("manager"))
max_value = max(len(max(results.values(), key=len)), len("status"))
separator_str = "-" * (max_project_id + max_value + 7) + "\n"
format_str = "| {0:%ss} | {1:%ss} |\n" % (max_project_id, max_value)
msg = separator_str
msg += format_str.format("manager", "status")
msg += separator_str
for manager, status in results.items():
msg += format_str.format(manager, status)
msg += separator_str
print(msg)
class EXECUTE(HTTPCommand):
def __init__(self, name):
super(EXECUTE, self).__init__(name)
def sendRequest(self, synergy_url, manager, command, args=None):
payload = {"manager": manager,
"command": command,
"args": args}
super(EXECUTE, self).sendRequest(synergy_url + "/synergy/execute",
payload)

View File

@ -0,0 +1,589 @@
import json
import os.path
import requests
from datetime import datetime
__author__ = "Lisa Zangrando"
__email__ = "lisa.zangrando[AT]pd.infn.it"
__copyright__ = """Copyright (c) 2015 INFN - INDIGO-DataCloud
All Rights Reserved
Licensed under the Apache License, Version 2.0;
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."""
class Trust(object):
def __init__(self, data):
data = data["trust"]
self.id = data["id"]
self.impersonations = data["impersonation"]
self.roles_links = data["roles_links"]
self.trustor_user_id = data["trustor_user_id"]
self.trustee_user_id = data["trustee_user_id"]
self.links = data["links"]
self.roles = data["roles"]
self.remaining_uses = data["remaining_uses"]
self.expires_at = None
if data["expires_at"] is not None:
self.expires_at = datetime.strptime(data["expires_at"],
"%Y-%m-%dT%H:%M:%S.%fZ")
self.project_id = data["project_id"]
def getId(self):
return self.id
def isImpersonations(self):
return self.impersonations
def getRolesLinks(self):
return self.roles_links
def getTrustorUserId(self):
return self.trustor_user_id
def getTrusteeUserId(self):
return self.trustee_user_id
def getlinks(self):
return self.links
def getProjectId(self):
return self.project_id
def getRoles(self):
return self.roles
def getRemainingUses(self):
return self.remaining_uses
def getExpiration(self):
return self.expires_at
def isExpired(self):
if self.getExpiration() is None:
return False
return self.getExpiration() < datetime.utcnow()
class Token(object):
def __init__(self, token, data):
self.id = token
data = data["token"]
self.roles = data["roles"]
self.catalog = data["catalog"]
self.issued_at = datetime.strptime(data["issued_at"],
"%Y-%m-%dT%H:%M:%S.%fZ")
self.expires_at = datetime.strptime(data["expires_at"],
"%Y-%m-%dT%H:%M:%S.%fZ")
self.project = data["project"]
self.user = data["user"]
self.extras = data["extras"]
def getCatalog(self, service_name=None, interface="public"):
if service_name:
for service in self.catalog:
if service["name"] == service_name:
for endpoint in service["endpoints"]:
if endpoint["interface"] == interface:
return endpoint
return None
else:
return self.catalog
def getExpiration(self):
return self.expires_at
def getId(self):
return self.id
def getExtras(self):
return self.extras
def getProject(self):
return self.project
def getRoles(self):
return self.roles
def getUser(self):
return self.user
def isAdmin(self):
if not self.roles:
return False
for role in self.roles:
if role["name"] == "admin":
return True
return False
def issuedAt(self):
return self.issued_at
def isExpired(self):
return self.getExpiration() < datetime.utcnow()
def save(self, filename):
# save to file
with open(filename, 'w') as f:
token = {}
token["catalog"] = self.catalog
token["extras"] = self.extras
token["user"] = self.user
token["project"] = self.project
token["roles"] = self.roles
token["roles"] = self.roles
token["issued_at"] = self.issued_at.isoformat()
token["expires_at"] = self.expires_at.isoformat()
data = {"id": self.id, "token": token}
json.dump(data, f)
@classmethod
def load(cls, filename):
if not os.path.isfile(".auth_token"):
return None
# load from file:
with open(filename, 'r') as f:
try:
data = json.load(f)
return Token(data["id"], data)
# if the file is empty the ValueError will be thrown
except ValueError as ex:
raise ex
def isotime(self, at=None, subsecond=False):
"""Stringify time in ISO 8601 format."""
if not at:
at = datetime.utcnow()
if not subsecond:
st = at.strftime('%Y-%m-%dT%H:%M:%S')
else:
st = at.strftime('%Y-%m-%dT%H:%M:%S.%f')
if at.tzinfo:
tz = at.tzinfo.tzname(None)
else:
tz = 'UTC'
st += ('Z' if tz == 'UTC' else tz)
return st
"""The trustor or grantor of a trust is the person who creates the trust.
The trustor is the one who contributes property to the trust.
The trustee is the person who manages the trust, and is usually appointed
by the trustor. The trustor is also often the trustee in living trusts.
"""
def trust(self, trustee_user, expires_at=None,
project_id=None, roles=None, impersonation=True):
if self.isExpired():
raise Exception("token expired!")
headers = {"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "python-novaclient",
"X-Auth-Token": self.getId()}
if roles is None:
roles = self.getRoles()
if project_id is None:
project_id = self.getProject().get("id")
data = {}
data["trust"] = {"impersonation": impersonation,
"project_id": project_id,
"roles": roles,
"trustee_user_id": trustee_user,
"trustor_user_id": self.getUser().get("id")}
if expires_at is not None:
data["trust"]["expires_at"] = self.isotime(expires_at, True)
endpoint = self.getCatalog(service_name="keystone")
if not endpoint:
raise Exception("keystone endpoint not found!")
if "v2.0" in endpoint["url"]:
endpoint["url"] = endpoint["url"].replace("v2.0", "v3")
response = requests.post(url=endpoint["url"] + "/OS-TRUST/trusts",
headers=headers,
data=json.dumps(data))
if response.status_code != requests.codes.ok:
response.raise_for_status()
if not response.text:
raise Exception("trust token failed!")
return Trust(response.json())
class KeystoneClient(object):
def __init__(self, auth_url, username, password, project_id=None,
project_name=None, timeout=None,
default_trust_expiration=None):
self.auth_url = auth_url
self.username = username
self.password = password
self.project_id = project_id
self.project_name = project_name
self.timeout = timeout
self.token = None
if default_trust_expiration:
self.default_trust_expiration = default_trust_expiration
else:
self.default_trust_expiration = 24
def authenticate(self):
if self.token is not None:
if self.token.isExpired():
try:
self.deleteToken(self.token.getId())
except requests.exceptions.HTTPError:
pass
else:
return
headers = {"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "python-novaclient"}
identity = {"methods": ["password"],
"password": {"user": {"name": self.username,
"domain": {"id": "default"},
"password": self.password}}}
data = {"auth": {}}
data["auth"]["identity"] = identity
if self.project_name:
data["auth"]["scope"] = {"project": {"name": self.project_name,
"domain": {"id": "default"}}}
if self.project_id:
data["auth"]["scope"] = {"project": {"id": self.project_id,
"domain": {"id": "default"}}}
response = requests.post(url=self.auth_url + "/auth/tokens",
headers=headers,
data=json.dumps(data),
timeout=self.timeout)
if response.status_code != requests.codes.ok:
response.raise_for_status()
if not response.text:
raise Exception("authentication failed!")
# print(response.__dict__)
token_subject = response.headers["X-Subject-Token"]
token_data = response.json()
self.token = Token(token_subject, token_data)
def getUser(self, id):
try:
response = self.getResource("users/%s" % id, "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the user info (id=%r): %s"
% (id, response["error"]["message"]))
if response:
response = response["user"]
return response
def getUsers(self):
try:
response = self.getResource("users", "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the users list: %s"
% response["error"]["message"])
if response:
response = response["users"]
return response
def getUserProjects(self, id):
try:
response = self.getResource("users/%s/projects" % id, "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the users's projects "
"(id=%r): %s" % (id, response["error"]["message"]))
if response:
response = response["projects"]
return response
def getUserRoles(self, user_id, project_id):
try:
response = self.getResource("/projects/%s/users/%s/roles"
% (project_id, user_id), "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the user's roles (usrId=%r, "
"prjId=%r): %s" % (user_id,
project_id,
response["error"]["message"]))
if response:
response = response["roles"]
return response
def getProject(self, id):
try:
response = self.getResource("/projects/%s" % id, "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the project (id=%r, "
% (id, response["error"]["message"]))
if response:
response = response["project"]
return response
def getProjects(self):
try:
response = self.getResource("/projects", "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the projects list: %s"
% response["error"]["message"])
if response:
response = response["projects"]
return response
def getRole(self, id):
try:
response = self.getResource("/roles/%s" % id, "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the role info (id=%r): %s"
% (id, response["error"]["message"]))
if response:
response = response["role"]
return response
def getRoles(self):
try:
response = self.getResource("/roles", "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the roles list: %s"
% response["error"]["message"])
if response:
response = response["roles"]
return response
def getToken(self):
self.authenticate()
return self.token
def deleteToken(self, id):
if self.token is None:
return
headers = {"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "python-novaclient",
"X-Auth-Project-Id": self.token.getProject()["name"],
"X-Auth-Token": self.token.getId(),
"X-Subject-Token": id}
response = requests.delete(url=self.auth_url + "/auth/tokens",
headers=headers,
timeout=self.timeout)
self.token = None
if response.status_code != requests.codes.ok:
response.raise_for_status()
def validateToken(self, id):
self.authenticate()
headers = {"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "python-novaclient",
"X-Auth-Project-Id": self.token.getProject()["name"],
"X-Auth-Token": self.token.getId(),
"X-Subject-Token": id}
response = requests.get(url=self.auth_url + "/auth/tokens",
headers=headers,
timeout=self.timeout)
if response.status_code != requests.codes.ok:
response.raise_for_status()
if not response.text:
raise Exception("token not found!")
token_subject = response.headers["X-Subject-Token"]
token_data = response.json()
return Token(token_subject, token_data)
def getEndpoint(self, id=None, service_id=None):
if id:
try:
response = self.getResource("/endpoints/%s" % id, "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the endpoint (id=%r): %s"
% (id, response["error"]["message"]))
if response:
response = response["endpoint"]
return response
elif service_id:
try:
endpoints = self.getEndpoints()
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the endpoints list"
"(serviceId=%r): %s"
% response["error"]["message"])
if endpoints:
for endpoint in endpoints:
if endpoint["service_id"] == service_id:
return endpoint
return None
def getEndpoints(self):
try:
response = self.getResource("/endpoints", "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the endpoints list: %s"
% response["error"]["message"])
if response:
response = response["endpoints"]
return response
def getService(self, id=None, name=None):
if id:
try:
response = self.getResource("/services/%s" % id, "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the service info (id=%r)"
": %s" % (id, response["error"]["message"]))
if response:
response = response["service"]
return response
elif name:
services = self.getServices()
if services:
for service in services:
if service["name"] == name:
return service
return None
def getServices(self):
try:
response = self.getResource("/services", "GET")
except requests.exceptions.HTTPError as ex:
response = ex.response.json()
raise Exception("error on retrieving the services list: %s"
% response["error"]["message"])
if response:
response = response["services"]
return response
def getResource(self, resource, method, data=None):
self.authenticate()
url = self.auth_url + "/" + resource
headers = {"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "python-novaclient",
"X-Auth-Project-Id": self.token.getProject()["name"],
"X-Auth-Token": self.token.getId()}
if method == "GET":
response = requests.get(url,
headers=headers,
params=data,
timeout=self.timeout)
elif method == "POST":
response = requests.post(url,
headers=headers,
data=json.dumps(data),
timeout=self.timeout)
elif method == "PUT":
response = requests.put(url,
headers=headers,
data=json.dumps(data),
timeout=self.timeout)
elif method == "HEAD":
response = requests.head(url,
headers=headers,
data=json.dumps(data),
timeout=self.timeout)
elif method == "DELETE":
response = requests.delete(url,
headers=headers,
data=json.dumps(data),
timeout=self.timeout)
else:
raise Exception("wrong HTTP method: %s" % method)
if response.status_code != requests.codes.ok:
response.raise_for_status()
if response.text:
return response.json()
else:
return None

204
synergy/client/shell.py Normal file
View File

@ -0,0 +1,204 @@
import os
import os.path
import requests
import sys
from argparse import ArgumentParser
from pkg_resources import iter_entry_points
from synergy.client import keystone_v3
__author__ = "Lisa Zangrando"
__email__ = "lisa.zangrando[AT]pd.infn.it"
__copyright__ = """Copyright (c) 2015 INFN - INDIGO-DataCloud
All Rights Reserved
Licensed under the Apache License, Version 2.0;
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."""
COMMANDS_ENTRY_POINT = "synergy.commands" # used to discover Synergy commands
def main():
try:
parser = ArgumentParser(prog="synergy",
epilog="Command-line interface to the"
" OpenStack Synergy API.")
# Global arguments
parser.add_argument("--version", action="version", version="v1.0")
parser.add_argument("--debug",
default=False,
action="store_true",
help="print debugging output")
parser.add_argument("--os-username",
metavar="<auth-user-name>",
default=os.environ.get("OS_USERNAME"),
help="defaults to env[OS_USERNAME]")
parser.add_argument("--os-password",
metavar="<auth-password>",
default=os.environ.get("OS_PASSWORD"),
help="defaults to env[OS_PASSWORD]")
parser.add_argument("--os-project-name",
metavar="<auth-project-name>",
default=os.environ.get("OS_PROJECT_NAME"),
help="defaults to env[OS_PROJECT_NAME]")
parser.add_argument("--os-project-id",
metavar="<auth-project-id>",
default=os.environ.get("OS_PROJECT_ID"),
help="defaults to env[OS_PROJECT_ID]")
parser.add_argument("--os-auth-token",
metavar="<auth-token>",
default=os.environ.get("OS_AUTH_TOKEN", None),
help="defaults to env[OS_AUTH_TOKEN]")
parser.add_argument('--os-auth-token-cache',
default=os.environ.get("OS_AUTH_TOKEN_CACHE",
False),
action='store_true',
help="Use the auth token cache. Defaults to False "
"if env[OS_AUTH_TOKEN_CACHE] is not set")
parser.add_argument("--os-auth-url",
metavar="<auth-url>",
default=os.environ.get("OS_AUTH_URL"),
help="defaults to env[OS_AUTH_URL]")
parser.add_argument("--os-auth-system",
metavar="<auth-system>",
default=os.environ.get("OS_AUTH_SYSTEM"),
help="defaults to env[OS_AUTH_SYSTEM]")
parser.add_argument("--bypass-url",
metavar="<bypass-url>",
dest="bypass_url",
help="use this API endpoint instead of the "
"Service Catalog")
parser.add_argument("--os-cacert",
metavar="<ca-certificate>",
default=os.environ.get("OS_CACERT", None),
help="Specify a CA bundle file to use in verifying"
" a TLS (https) server certificate. Defaults "
"to env[OS_CACERT]")
"""
parser.add_argument("--insecure",
default=os.environ.get("INSECURE", False),
action="store_true",
help="explicitly allow Synergy's client to perform"
" \"insecure\" SSL (https) requests. The "
"server's certificate will not be verified "
"against any certificate authorities. This "
"option should be used with caution.")
"""
subparser = parser.add_subparsers(help="commands", dest="command_name")
commands = {}
for entry in iter_entry_points(COMMANDS_ENTRY_POINT):
command_class = entry.load()
command = command_class()
# command = command_class(*args, **kwargs)
command.configureParser(subparser)
commands[entry.name] = command
args = parser.parse_args(sys.argv[1:])
# print("args %s" % args)
os_username = args.os_username
os_password = args.os_password
os_project_name = args.os_project_name
# os_project_id = args.os_project_id
os_auth_token = args.os_auth_token
os_auth_token_cache = args.os_auth_token_cache
os_auth_url = args.os_auth_url
# os_auth_system = args.os_auth_system
# insecure = args.insecure
bypass_url = args.bypass_url
# cacert = args.os_cacert
command_name = args.command_name
if not os_username:
raise Exception("'os-username' not defined!")
if not os_password:
raise Exception("'os-password' not defined!")
if not os_project_name:
raise Exception("'os-project-name' not defined!")
if not os_auth_url:
raise Exception("'os-auth-url' not defined!")
client = keystone_v3.KeystoneClient(auth_url=os_auth_url,
username=os_username,
password=os_password,
project_name=os_project_name)
"""
client.authenticate()
token = client.getToken()
print("os_auth_token=%s" % os_auth_token)
print("os_auth_token_cache=%s" % os_auth_token_cache)
"""
token = None
if os_auth_token:
token = os_auth_token
elif os_auth_token_cache:
token = keystone_v3.Token.load(".auth_token")
# print("token is expired? %s" % token.isExpired())
if token is None or token.isExpired():
client.authenticate()
token = client.getToken()
token.save(".auth_token")
else:
client.authenticate()
token = client.getToken()
synergy_url = None
if bypass_url:
synergy_url = bypass_url
else:
synergy_service = client.getService(name="synergy")
synergy_endpoint = client.getEndpoint(
service_id=synergy_service["id"])
synergy_url = synergy_endpoint["url"]
if command_name not in commands:
print("command %r not found!" % command_name)
commands[command_name].sendRequest(synergy_url, args)
commands[command_name].log()
except KeyboardInterrupt as e:
print("Shutting down synergyclient")
sys.exit(1)
except requests.exceptions.HTTPError as e:
print("HTTPError: %s" % e.response._content)
sys.exit(1)
except Exception as e:
print("ERROR: %s" % e)
sys.exit(1)
if __name__ == "__main__":
main()

View File

@ -240,6 +240,56 @@ class Synergy(service.Service):
manager_name = None
command = None
query = environ.get("QUERY_STRING", None)
if query:
parameters = parse_qs(query)
LOG.info(parameters)
if "manager" in parameters:
manager_name = escape(parameters['manager'][0])
if "command" in parameters:
command = escape(parameters['command'][0])
if "args" in parameters:
manager_args = escape(parameters['args'][0])
manager_args = manager_args.replace("'", "\"")
manager_args = json.loads(manager_args)
else:
manager_args = {}
if not query or not manager_name or not command:
start_response("404 NOT FOUND", [("Content-Type", "text/plain")])
return ["wrong command"]
if manager_name in self.managers:
manager = self.managers[manager_name]
try:
result = manager.execute(command=command, **manager_args)
if not isinstance(result, dict):
try:
result = result.toDict()
except Exception:
result = result.__dict__
LOG.info("command result %s" % result)
start_response("200 OK", [("Content-Type", "text/html")])
return ["%s" % json.dumps(result)]
except Exception as ex:
LOG.info("executeCommand error: %s" % ex)
start_response("404 NOT FOUND",
[("Content-Type", "text/plain")])
return ["error: %s" % ex]
else:
start_response("404 NOT FOUND", [("Content-Type", "text/plain")])
return ["manager %r not found!" % manager_name]
def executeCommand2(self, environ, start_response):
manager_name = None
command = None
synergySerializer = serializer.SynergySerializer()
query = environ.get("QUERY_STRING", None)
# LOG.info("QUERY_STRING %s" % query)