summaryrefslogtreecommitdiffstats
path: root/agents/aliyun
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--agents/aliyun/fence_aliyun.py192
1 files changed, 192 insertions, 0 deletions
diff --git a/agents/aliyun/fence_aliyun.py b/agents/aliyun/fence_aliyun.py
new file mode 100644
index 0000000..1e9c790
--- /dev/null
+++ b/agents/aliyun/fence_aliyun.py
@@ -0,0 +1,192 @@
+#!@PYTHON@ -tt
+
+import sys
+import logging
+import atexit
+import json
+
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing import fail_usage, run_delay
+
+
+try:
+ from aliyunsdkcore import client
+ from aliyunsdkcore.auth.credentials import EcsRamRoleCredential
+ from aliyunsdkcore.profile import region_provider
+except ImportError as e:
+ logging.warn("The 'aliyunsdkcore' module has been not installed or is unavailable, try to execute the command 'pip install aliyun-python-sdk-core --upgrade' to solve. error: %s" % e)
+
+
+try:
+ from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
+ from aliyunsdkecs.request.v20140526.StartInstanceRequest import StartInstanceRequest
+ from aliyunsdkecs.request.v20140526.StopInstanceRequest import StopInstanceRequest
+ from aliyunsdkecs.request.v20140526.RebootInstanceRequest import RebootInstanceRequest
+except ImportError as e:
+ logging.warn("The 'aliyunsdkecs' module has been not installed or is unavailable, try to execute the command 'pip install aliyun-python-sdk-ecs --upgrade' to solve. error: %s" % e)
+
+
+def _send_request(conn, request):
+ logging.debug("send request action: %s" % request.get_action_name())
+ request.set_accept_format('json')
+ try:
+ response_str = conn.do_action_with_exception(request)
+ except Exception as e:
+ fail_usage("Failed: send request failed: Error: %s" % e)
+
+ response_detail = json.loads(response_str)
+ logging.debug("reponse: %s" % response_detail)
+ return response_detail
+
+def start_instance(conn, instance_id):
+ logging.debug("start instance %s" % instance_id)
+ request = StartInstanceRequest()
+ request.set_InstanceId(instance_id)
+ _send_request(conn, request)
+
+def stop_instance(conn, instance_id):
+ logging.debug("stop instance %s" % instance_id)
+ request = StopInstanceRequest()
+ request.set_InstanceId(instance_id)
+ request.set_ForceStop('true')
+ _send_request(conn, request)
+
+def reboot_instance(conn, instance_id):
+ logging.debug("reboot instance %s" % instance_id)
+ request = RebootInstanceRequest()
+ request.set_InstanceId(instance_id)
+ request.set_ForceStop('true')
+ _send_request(conn, request)
+
+def get_status(conn, instance_id):
+ logging.debug("get instance %s status" % instance_id)
+ request = DescribeInstancesRequest()
+ request.set_InstanceIds(json.dumps([instance_id]))
+ response = _send_request(conn, request)
+ instance_status = None
+ if response is not None:
+ instance_list = response.get('Instances').get('Instance')
+ for item in instance_list:
+ instance_status = item.get('Status')
+ return instance_status
+
+def get_nodes_list(conn, options):
+ logging.debug("start to get nodes list")
+ result = {}
+ request = DescribeInstancesRequest()
+ request.set_PageSize(100)
+ response = _send_request(conn, request)
+ if response is not None:
+ instance_list = response.get('Instances').get('Instance')
+ for item in instance_list:
+ instance_id = item.get('InstanceId')
+ instance_name = item.get('InstanceName')
+ result[instance_id] = (instance_name, None)
+ logging.debug("get nodes list: %s" % result)
+ return result
+
+def get_power_status(conn, options):
+ logging.debug("start to get power(%s) status" % options["--plug"])
+ state = get_status(conn, options["--plug"])
+
+ if state == "Running":
+ status = "on"
+ elif state == "Stopped":
+ status = "off"
+ else:
+ status = "unknown"
+ logging.debug("the power(%s) status is %s" % (options["--plug"], status))
+ return status
+
+def set_power_status(conn, options):
+ logging.info("start to set power(%s) status to %s" % (options["--plug"], options["--action"]))
+
+ if (options["--action"]=="off"):
+ stop_instance(conn, options["--plug"])
+ elif (options["--action"]=="on"):
+ start_instance(conn, options["--plug"])
+ elif (options["--action"]=="reboot"):
+ reboot_instance(conn, options["--plug"])
+
+def define_new_opts():
+ all_opt["region"] = {
+ "getopt" : "r:",
+ "longopt" : "region",
+ "help" : "-r, --region=[name] Region, e.g. cn-hangzhou",
+ "shortdesc" : "Region.",
+ "required" : "0",
+ "order" : 2
+ }
+ all_opt["access_key"] = {
+ "getopt" : "a:",
+ "longopt" : "access-key",
+ "help" : "-a, --access-key=[name] Access Key",
+ "shortdesc" : "Access Key.",
+ "required" : "0",
+ "order" : 3
+ }
+ all_opt["secret_key"] = {
+ "getopt" : "s:",
+ "longopt" : "secret-key",
+ "help" : "-s, --secret-key=[name] Secret Key",
+ "shortdesc" : "Secret Key.",
+ "required" : "0",
+ "order" : 4
+ }
+ all_opt["ram_role"] = {
+ "getopt": ":",
+ "longopt": "ram-role",
+ "help": "--ram-role=[name] Ram Role",
+ "shortdesc": "Ram Role.",
+ "required": "0",
+ "order": 5
+ }
+
+# Main agent method
+def main():
+ conn = None
+
+ device_opt = ["port", "no_password", "region", "access_key", "secret_key", "ram_role"]
+
+ atexit.register(atexit_handler)
+
+ define_new_opts()
+
+ all_opt["power_timeout"]["default"] = "60"
+
+ options = check_input(device_opt, process_input(device_opt))
+
+ docs = {}
+ docs["shortdesc"] = "Fence agent for Aliyun (Aliyun Web Services)"
+ docs["longdesc"] = "fence_aliyun is an I/O Fencing agent for Aliyun"
+ docs["vendorurl"] = "http://www.aliyun.com"
+ show_docs(options, docs)
+
+ run_delay(options)
+
+ if "--region" in options:
+ region = options["--region"]
+ if "--access-key" in options and "--secret-key" in options:
+ access_key = options["--access-key"]
+ secret_key = options["--secret-key"]
+ conn = client.AcsClient(access_key, secret_key, region)
+ elif "--ram-role" in options:
+ ram_role = options["--ram-role"]
+ role = EcsRamRoleCredential(ram_role)
+ conn = client.AcsClient(region_id=region, credential=role)
+ else:
+ fail_usage("Failed: User credentials are not set. Please set the Access Key and the Secret Key, or configure the RAM role.")
+
+ # Use intranet endpoint to access ECS service
+ try:
+ region_provider.modify_point('Ecs', region, 'ecs.%s.aliyuncs.com' % region)
+ except Exception as e:
+ logging.warn("Failed: failed to modify endpoint to 'ecs.%s.aliyuncs.com': %s" % (region, e))
+
+ # Operate the fencing device
+ result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list)
+ sys.exit(result)
+
+if __name__ == "__main__":
+ main()