MoeClub пре 5 година
родитељ
комит
de1b0cca4b
1 измењених фајлова са 109 додато и 15 уклоњено
  1. 109 15
      OracleAction.py

+ 109 - 15
OracleAction.py

@@ -3,22 +3,32 @@
 # Author:  MoeClub.org
 
 # pip3 install rsa
-# python3 OracleAction.py -c "config/defaults.json" -i "ocid1.instance." -a "action" -n "name"
+# python3 OracleAction.py -c "config/defaults.json" -i "ocid1.instance...|create/defaults.json" -a "<action>" -n "name"
 
-# defaults.json
+# config/defaults.json
 # {
 #   "compartmentId": "ocid1.tenancy...",
 #   "userId": "ocid1.user...",
-#   "URL": "https://iaas.xxxxx.oraclecloud.com/20160918/",
+#   "URL": "https://iaas.xxx.oraclecloud.com/20160918/",
 #   "certFinger": "ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff",
 #   "certKey": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
 # }
 
+# create/defaults.json
+# {
+#   "shape": "VM.Standard.E2.1.Micro",
+#   "availabilityDomain": "xx:XX",
+#   "subnetId": "ocid1.subnet...",
+#   "imageId": "BASE64...",
+#   "ssh_authorized_keys": "ssh-rsa ...",
+# }
+
 
 import hashlib
 import datetime
 import base64
 import json
+import time
 import rsa
 from urllib import request, error, parse
 
@@ -98,11 +108,13 @@ class oracle:
 
 
 class action:
-    def __init__(self, apiDict, instancesId=None):
+    def __init__(self, apiDict, instancesId=None, configDict=None):
         self.apiDict = apiDict
-        self.privateKey = apiDict["certKey"]
+        self.privateKey = self.apiDict["certKey"]
+        self.apiKey = "/".join([self.apiDict["compartmentId"], self.apiDict["userId"], self.apiDict["certFinger"]])
+        self.configDict = configDict
         self.instancesId = instancesId
-        self.apiKey = "/".join([apiDict["compartmentId"], apiDict["userId"], apiDict["certFinger"]])
+        self.instancesDict = None
         self.VNIC = None
         self.PRIVATE = None
 
@@ -197,6 +209,81 @@ class action:
         response_json["status_code"] = str(response.code)
         print(json.dumps(response_json, indent=4))
 
+    def createInstancesPre(self, Name=None):
+        self.instancesDict = {
+            'displayName': str(str(self.configDict["availabilityDomain"]).split(":", 1)[-1].split("-")[1]),
+            'shape': self.configDict["shape"],
+            'compartmentId': self.configDict["compartmentId"],
+            'availabilityDomain': self.configDict["availabilityDomain"],
+            'sourceDetails': {
+                'sourceType': 'image',
+                'imageId': self.configDict['imageId'],
+            },
+            'createVnicDetails': {
+                'subnetId': self.configDict['subnetId'],
+                'assignPublicIp': True
+            },
+            'metadata': {
+                'user_data': self.configDict['user_data'],
+                'ssh_authorized_keys': self.configDict['ssh_authorized_keys'],
+            },
+            'agentConfig': {
+                'isMonitoringDisabled': False,
+                'isManagementDisabled': False
+            },
+        }
+        if Name and str(Name).strip():
+            self.instancesDict['displayName'] = str(Name).strip()
+
+    def createInstances(self, Name=None, Full=True, WaitResource=True):
+        url = self.apiDict["URL"] + "instances"
+        if not self.instancesDict or Name is not None:
+            self.createInstancesPre(Name=Name)
+        body = json.dumps(self.instancesDict, ensure_ascii=False)
+        while True:
+            FLAG = False
+            try:
+                try:
+                    response = oracle.api("POST", url, keyID=self.apiKey, privateKey=self.privateKey, data=body)
+                    response_json = json.loads(response.read().decode())
+                    response_json["status_code"] = str(response.code)
+                except Exception as e:
+                    print(e)
+                    response_json = {"code": "InternalError", "message": "Timeout.", "status_code": "555"}
+                if str(response_json["status_code"]).startswith("4"):
+                    FLAG = True
+                    if str(response_json["status_code"]) == "401":
+                        response_json["message"] = "Not Authenticated."
+                    elif str(response_json["status_code"]) == "400":
+                        if str(response_json["code"]) == "LimitExceeded":
+                            response_json["message"] = "Limit Exceeded."
+                        if str(response_json["code"]) == "QuotaExceeded":
+                            response_json["message"] = "Quota Exceeded."
+                    elif str(response_json["status_code"]) == "429":
+                        FLAG = False
+                    elif str(response_json["status_code"]) == "404":
+                        if WaitResource and str(response_json["code"]) == "NotAuthorizedOrNotFound":
+                            FLAG = False
+                if int(response_json["status_code"]) < 300:
+                    vm_ocid = str(str(response_json["id"]).split(".")[-1])
+                    print(str("{} [{}] {}").format(time.strftime("[%Y/%m/%d %H:%M:%S]", time.localtime()), response_json["status_code"], str(vm_ocid[:5] + "..." + vm_ocid[-7:])))
+                else:
+                    print(str("{} [{}] {}").format(time.strftime("[%Y/%m/%d %H:%M:%S]", time.localtime()), response_json["status_code"], response_json["message"]))
+                if Full is False and str(response_json["status_code"]) == "200":
+                    FLAG = True
+                if not FLAG:
+                    if str(response_json["status_code"]) == "429":
+                        time.sleep(60)
+                    elif str(response_json["status_code"]) == "404":
+                        time.sleep(30)
+                    else:
+                        time.sleep(5)
+            except Exception as e:
+                FLAG = True
+                print(e)
+            if FLAG:
+                break
+
 
 if __name__ == "__main__":
     def Exit(code=0, msg=None):
@@ -206,34 +293,41 @@ if __name__ == "__main__":
 
     import argparse
     parser = argparse.ArgumentParser()
-    parser.add_argument('-c', type=str, default="", help="Config path")
-    parser.add_argument('-i', type=str, default="", help="Instances Id")
+    parser.add_argument('-c', type=str, default="", help="Config Path")
+    parser.add_argument('-i', type=str, default="", help="Instances Id or Instances Config Path")
     parser.add_argument('-n', type=str, default="", help="New Instances Name")
-    parser.add_argument('-a', type=str, default="", help="Action [show, change, rename]")
+    parser.add_argument('-a', type=str, default="", help="Action [show, change, rename, create]")
     args = parser.parse_args()
     configPath = str(args.c).strip()
     configAction = str(args.a).strip().lower()
     configInstancesId = str(args.i).strip()
     configInstancesName = str(args.n).strip()
-    configActionList = ["show", "change", "rename"]
+    configActionList = ["show", "change", "rename", "create"]
 
     if not configPath:
         Exit(1, "Require Config Path.")
     if not configAction or configAction not in configActionList:
-        Exit(1, "Invalid action.")
+        Exit(1, "Invalid Action.")
     if not configInstancesId:
-        Exit(1, "Require Instances Id.")
+        Exit(1, "Require Instances Id or Instances Config Path.")
 
     if configAction == "show":
-        Action = action(oracle.load_Config(configPath), configInstancesId)
+        Action = action(apiDict=oracle.load_Config(configPath), instancesId=configInstancesId)
         Action.showPublicIP()
     elif configAction == "change":
-        Action = action(oracle.load_Config(configPath), configInstancesId)
+        Action = action(apiDict=oracle.load_Config(configPath), instancesId=configInstancesId)
         Action.changePubilcIP()
     elif configAction == "rename":
         if not configInstancesName:
             Exit(1, "Require Instances Name.")
-        Action = action(oracle.load_Config(configPath), configInstancesId)
+        Action = action(apiDict=oracle.load_Config(configPath), instancesId=configInstancesId)
         Action.rename(configInstancesName)
+    elif configAction == "create":
+        if not configInstancesName:
+            configInstancesName = None
+        else:
+            configInstancesName = str(configInstancesName).strip()
+        Action = action(apiDict=oracle.load_Config(configPath), configDict=oracle.load_Config(configInstancesId))
+        Action.createInstances(configInstancesName)
 
     Exit(0)