def POST(self, swarmName, swarmIp): """ add a swarm cluster into current, check, pickle. """ res = {"msg": None, "code": 0} swarmIp = swarmIp.strip() swarmName = swarmName.strip() logger.debug( "post a swarm cluster, name is %s, ip is %s, check ip is %s" % (swarmName, swarmIp, ip_check(swarmIp))) if not swarmName or not swarmIp or not ip_check(swarmIp): res.update(msg="POST: data params error", code=-1020) elif self.isMember(swarmName): res.update(msg="POST: swarm cluster already exists", code=-1021) else: #access node ip's info, and get all remote managers url = Splice(netloc=swarmIp, port=self.port, path='/info').geturl swarm = dict(name=swarmName) logger.info( "init a swarm cluter named %s, will get swarm ip info, that url is %s" % (swarmName, url)) try: nodeinfo = requests.get(url, timeout=self.timeout, verify=self.verify).json() logger.debug("get swarm ip info, response is %s" % nodeinfo) swarm["manager"] = [ nodes["Addr"].split(":")[0] for nodes in nodeinfo["Swarm"]["RemoteManagers"] ] except Exception, e: logger.error(e, exc_info=True) res.update(msg="POST: access the node ip has exception", code=-1022) else:
def _checkSwarmHealth(self, leader): """ 根据Leader查询某swarm集群是否健康 """ state = [] mnum = 0 logger.info( "To determine whether the cluster is healthy, starting, swarm leader is %s" % leader) try: nodes = requests.get(Splice(netloc=leader, port=self.port, path='/nodes').geturl, timeout=self.timeout, verify=self.verify).json() logger.debug("check swarm health, swarm nodes length is %d" % len(nodes)) for node in nodes: if node['Spec'].get('Role') == 'manager': mnum += 1 isHealth = True if node['Status'][ 'State'] == 'ready' and node['Spec'].get( 'Availability') == 'active' and node.get( 'ManagerStatus', {}).get( 'Reachability') == 'reachable' else False if isHealth: state.append(isHealth) except Exception, e: logger.warn(e, exc_info=True) return "ERROR"
def home(user=None): logger.debug(user) if g.signin: user = get_user_profile(g.username) blog = get_user_blog(g.username) return render_template("front/home.html", user=user, blog=blog) else: return redirect(url_for(".login"))
def put(self): """ 更新节点信息(Labels、Role等) """ node_id = request.form.get("node_id") node_role = request.form.get("node_role") node_labels = request.form.get("node_labels") logger.debug("{}, {}, {}".format(node_id, node_role, node_labels)) return g.node.PUT(node_id=node_id, node_role=node_role, node_labels=node_labels)
def _checkSwarmManager(self, ip): """ 查询节点的Manager """ url = Splice(netloc=ip, port=self.port, path='/info').geturl logger.info("Get or Update swarm manager, that url is %s" % url) try: nodeinfo = requests.get(url, timeout=self.timeout, verify=self.verify).json() logger.debug("Get or Update swarm manager, response is %s" % nodeinfo) managers = [ nodes["Addr"].split(":")[0] for nodes in nodeinfo["Swarm"]["RemoteManagers"] ] except Exception, e: logger.error(e, exc_info=True) return []
def feed(): data = get_index_data(limit=10) logger.debug(data) feed = AtomFeed('Interest.blog Feed', feed_url=request.url, url=request.url_root, subtitle="From the latest article in www.saintic.com") for article in data: feed.add(article['title'], unicode(article['content']), content_type='html', author=article['author'], id=article['id'], url=urljoin(request.url_root, url_for(".blogShow", bid=article['id'])), updated=datetime.datetime.strptime( article['update_time'] or article['create_time'], "%Y-%m-%d"), published=datetime.datetime.strptime(article['create_time'], "%Y-%m-%d")) return feed.get_response()
def UploadProfileAvatar(): logger.debug(request.files) f = request.files.get('file') # Check if the file is one of the allowed types/extensions if f and allowed_file(f.filename): filename = secure_filename(gen_filename() + "." + f.filename.split('.')[-1]) #随机命名 filedir = os.path.join(upload_page.root_path, AVATAR_UPLOAD_FOLDER) logger.info("get allowed file %s, its name is %s, save in %s" % (f, filename, filedir)) if not os.path.exists(filedir): os.makedirs(filedir) f.save(os.path.join(filedir, filename)) if PLUGINS['UpYunStorage']['enable']: imgUrl = "/interest.blog/avatar/" + filename upres = UploadImage2Upyun(os.path.join(filedir, filename), imgUrl) imgUrl = PLUGINS['UpYunStorage']['dn'].strip("/") + imgUrl logger.info( "Avatar to Upyun file saved, its url is %s, result is %s" % (imgUrl, upres)) else: imgUrl = "/" + AVATAR_IMAGE_UPLOAD_DIR + filename logger.info("Avatar to local file saved in %s, its url is %s" % (filedir, imgUrl)) # return user home and write avatar url into mysql db. res = requests.put(g.apiurl + "/user/", timeout=5, verify=False, headers={ 'User-Agent': 'Interest.blog' }, params={ "change": "avatar" }, data={ "avatar": imgUrl, "username": g.username }).json() logger.info(res) return redirect(url_for('front.home'))
def GET(self, node=None): """ 查询所有可用的节点群,并组织返回节点信息 """ res = {"code": 0, "msg": None, "data": []} if self.leader: #format (host, id, role, status, availability, reachability, containers, cpu, mem, label, UpdatedAt, DockerVersion). req_data = self._checkSwarmNode(self.leader, node) req_data = req_data if isinstance(req_data, (list, tuple)) else (req_data,) node_data = [] for i in req_data: try: node_id = i['ID'] node_role = 'Leader' if i.get('ManagerStatus', {}).get('Leader') else i['Spec'].get('Role') node_host = i.get('ManagerStatus', {}).get('Addr', '').split(':')[0] or i['Spec'].get('Labels', {}).get('ipaddr', i['Description']['Hostname']) node_status = i['Status']['State'] node_availability = i['Spec'].get('Availability') node_reachability = i.get('ManagerStatus', {}).get('Reachability') node_containers = self._checkSwarmNodeinfo(node_host).get("ContainersRunning") if ip_check(node_host) and node_status == "ready" and node_availability == "active" else 'Unknown' node_cpu = int(i['Description']['Resources']['NanoCPUs'] / 1e9) node_mem = int(i['Description']['Resources']['MemoryBytes'] / 1e6 / 1024) #bytes to G node_label = i['Spec'].get('Labels') if isinstance(node_label, dict): _node_label = '' for k,v in node_label.iteritems(): _node_label += '%s=%s, ' %(k, v) node_label = _node_label.strip(' ,') node_CreatedAt = timeChange(i['CreatedAt']) node_UpdatedAt = timeChange(i['UpdatedAt']) node_dockerVersion = i['Description']['Engine']['EngineVersion'] node_indexVersion = i.get("Version", {}).get("Index") except Exception,e: logger.error(e, exc_info=True) logger.debug(i) node_host = i.get('ManagerStatus', {}).get('Addr', '').split(':')[0] or i['Spec'].get('Labels', {}).get('ipaddr', i['Description']['Hostname']) node_data.append((node_host, i.get("ID"))) else: node_data.append((node_host, node_id, node_role, node_status, node_availability, node_reachability, node_containers, node_cpu, node_mem, node_label, node_CreatedAt, node_UpdatedAt, node_dockerVersion)) res.update(data=node_data)
def POST(self, image, **params): """ Create a service in docker swarm mode cluster with api. 1. get, convert, check params, 2. post data to swarm api. """ res = {"msg": None, "code": 0} logger.info("Create service, the required image is %s" % image) #check leader if not self.leader: res.update(msg="No active swarm", code=-1000) logger.info(res) return res ###get params, in version 0.1.10, optional only is "name, env, mount, publish, replicas", required "image". logger.debug(params) try: name = params.get("name") #str, needn't convert env = self.commaConvert( params.get("env")) if params.get("env") else [] #source data likes "key=value, key2=value2", convert to list or tuple, \n, #`env`'ask likes this, [key=value, key2=value2] or (key3=value3, key4=value4). mount = self.commaConvert( params.get("mount")) if params.get("mount") else [] #source data likes "src:dst:true:mode, src:dst:true|false:mode", example "/data/swarmopsapi-logs:/SwarmOpsApi/logs:true:bind, /data/cmlogs:/data/cmdata/logs:false:bind", convert it, \n, #`mount`'ask likes this, [src:dst:true|false(default false, rw):mode, ]. publish = self.commaConvert( params.get("publish")) if params.get("publish") else [] #source data likes "src:desc:protocol, src2:desc2", such as `env`, convert it, \n #list or tuple, `publish`'ask likes this, [src:desc, src2:desc2] or (). except Exception, e: logger.warn(e, exc_info=True) res.update(msg="parameters error", code=40000) logger.info(res) return res
def UploadImage(): editorType = request.args.get("editorType", "wangEditor") logger.debug(request.files) f = request.files.get("WriteBlogImage") or request.files.get( "editormd-image-file") if f and allowed_file(f.filename): filename = secure_filename(gen_filename() + "." + f.filename.split('.')[-1]) #随机命名 filedir = os.path.join(upload_page.root_path, BLOG_UPLOAD_FOLDER) logger.info("get allowed file %s, its name is %s, save in %s" % (f, filename, filedir)) if not os.path.exists(filedir): os.makedirs(filedir) f.save(os.path.join(filedir, filename)) if PLUGINS['UpYunStorage']['enable']: imgUrl = "/interest.blog/blog/" + filename upres = UploadImage2Upyun(os.path.join(filedir, filename), imgUrl) imgUrl = PLUGINS['UpYunStorage']['dn'].strip("/") + imgUrl logger.info( "Blog to Upyun file saved, its url is %s, result is %s" % (imgUrl, upres)) else: imgUrl = request.url_root + BLOG_IMAGE_UPLOAD_DIR + filename logger.info("Blog to local file saved in %s, its url is %s" % (filedir, imgUrl)) if editorType == "wangEditor": res = Response(imgUrl) res.headers["ContentType"] = "text/html" else: res = jsonify(url=imgUrl, message=None, success=1) res.headers["ContentType"] = "application/json" res.headers["Charset"] = "utf-8" logger.debug(res) return res else: result = r"error|未成功获取文件,上传失败" logger.warn(result) if editorType == "wangEditor": res = Response(result) res.headers["ContentType"] = "text/html" else: res = jsonify(message=result, success=0) res.headers["ContentType"] = "application/json" res.headers["Charset"] = "utf-8" logger.debug(res) return res
def PUT(self, serviceFlag, **params): """update a service in docker swarm mode cluster with api. 1. get, convert, check params, 2. post data to swarm api. """ res = {"msg": None, "code": 0} logger.info("Update service flag(id/name) is %s, other params is %s" % (serviceFlag, params)) #check params if not serviceFlag: logger.warn("service id/name is empty") res.update(msg="service id/name is empty", code=50000) logger.info(res) return res #check leader if not self.leader: res.update(msg="No active swarm", code=-1000) logger.info(res) return res #check UpdateServiceType USType = params.get("UpdateServiceType", "api") if USType not in ("ui", "api"): res.update("UpdateServiceType error", code=50001) logger.info(res) return res serviceSourceData = self.GET(service=serviceFlag, core=True).get("data") logger.debug(serviceSourceData) if isinstance(serviceSourceData, (list, tuple)) and len(serviceSourceData) > 0: serviceSourceData = serviceSourceData[0] serviceFlag2ID = serviceSourceData.get("ID") #default service data for api(UI filled). defaultName = serviceSourceData.get("Name") defaultEnv = serviceSourceData.get("Env") defaultMount = serviceSourceData.get("Mounts") defaultPublish = serviceSourceData.get("NetPorts") defaultImage = serviceSourceData.get("Image") defaultReplicas = serviceSourceData.get("Replicas") defaultVersion = serviceSourceData.get("Version") try: if USType == "ui": image = params.get("image") name = params.get("name") env = self.commaConvert( params.get("env")) if params.get("env") else None mount = self.commaConvert( params.get("mount")) if params.get("mount") else None publish = self.commaConvert(params.get( "publish")) if params.get("publish") else None replicas = int(params.get("replicas")) delay = int(params.get("delay", 10)) parallelism = int(params.get("parallelism", 1)) else: image = params.get("image") or defaultImage name = params.get("name") or defaultName env = self.commaConvert( params.get("env")) if params.get("env") else defaultEnv mount = self.commaConvert(params.get( "mount")) if params.get("mount") else defaultMount publish = self.commaConvert( params.get("publish")) if params.get( "publish") else defaultPublish replicas = int(params.get("replicas")) if params.get( "replicas") else defaultReplicas delay = int( params.get("delay")) if params.get("delay") else 10 parallelism = int(params.get("parallelism")) if params.get( "parallelism") else 1 except Exception, e: logger.warn(e, exc_info=True) res.update(msg="parameters error", code=50001) logger.info(res) return res
def GET(self, service=None, core=False, core_convert=False): res = {"msg": None, "code": 0, "data": ()} if self.leader: ServiceUrl = Splice( netloc=self.leader, port=self.port, path="/services/%s" % service).geturl if service else Splice( netloc=self.leader, port=self.port, path="/services").geturl logger.info( "Get service url is %s, core is %s, core_convert is %s" % (ServiceUrl, core, core_convert)) try: r = requests.get(ServiceUrl, timeout=self.timeout, verify=self.verify) services = r.json() services = services if isinstance(services, (list, tuple)) else (services, ) services_core = [] except Exception, e: logger.error(e, exc_info=True) res.update(msg="Retrieve service fail", code=30000) else: if r.status_code == 404: res.update(msg="No such service<%s>" % service, data=[], code=30010) logger.info(res) return res elif core == False: res.update(data=services) elif core == True and core_convert == True: try: for i in services: logger.debug(i) i_ID = i.get("ID") i_Name = i.get("Spec", {}).get("Name") i_CreatedAt = timeChange(i.get("CreatedAt")) i_UpdatedAt = timeChange(i.get("UpdatedAt")) i_Labels = i.get("Spec", {}).get("Labels") i_Image = i.get("Spec", {}).get( "TaskTemplate", {}).get("ContainerSpec", {}).get("Image") i_Env = i.get("Spec", {}).get("TaskTemplate", {}).get("ContainerSpec", {}).get("Env") #### start convert mount i_Mounts = i.get("Spec", {}).get( "TaskTemplate", {}).get("ContainerSpec", {}).get("Mounts", []) _i_Mounts = [] for _ in i_Mounts: _i_Mounts.append( "%s:%s:%s:%s" % (_.get("Source"), _.get("Target"), _.get("ReadOnly", ""), _.get("Type", ""))) i_Mounts = _i_Mounts #### end convert mount i_Replicas = "global" if "Global" in i.get( "Spec", {}).get("Mode", {}) else i.get( "Spec", {}).get("Mode", {}).get( "Replicated", {}).get("Replicas") i_NetMode = i.get("Endpoint", {}).get( "Spec", {}).get("Mode") or i.get("Spec", {}).get( "EndpointSpec", {}).get("Mode") #### start convert publish i_NetPorts = i.get("Endpoint", {}).get("Spec", {}).get("Ports", []) _i_NetPorts = [] for _ in i_NetPorts: _i_NetPorts.append( "%s:%s:%s" % (_.get("PublishedPort"), _.get("TargetPort"), _.get("Protocol"))) i_NetPorts = _i_NetPorts #### end convert publish #### start convert vip i_NetVip = i.get("Endpoint", {}).get("VirtualIPs", []) _i_NetVip = [] for _ in i_NetVip: _i_NetVip.append(_.get("Addr")) i_NetVip = _i_NetVip #### end convert vip i_Version = i.get("Version", {}).get("Index") i_UpdateStatus = "%s(%s)" % ( i.get("UpdateStatus").get("State"), timeChange( i.get("UpdateStatus").get("CompletedAt")) ) if i.get("UpdateStatus").get("State") else None services_core.append({ "ID": i_ID, "Name": i_Name, "CreatedAt": i_CreatedAt, "UpdatedAt": i_UpdatedAt, "Labels": i_Labels, "Image": i_Image, "Env": i_Env, "Mounts": i_Mounts, "Replicas": i_Replicas, "NetMode": i_NetMode, "NetPorts": i_NetPorts, "NetVip": i_NetVip, "Version": i_Version, "UpdateStatus": i_UpdateStatus }) except Exception, e: logger.error(e, exc_info=True) else: res.update(data=services_core) elif core == True and core_convert == False: try: for i in services: logger.debug(i) services_core.append({ "ID": i.get("ID"), "Name": i.get("Spec", {}).get("Name"), "CreatedAt": i.get("CreatedAt"), "UpdatedAt": i.get("UpdatedAt"), "Labels": i.get("Spec", {}).get("Labels"), "Image": i.get("Spec", {}).get("TaskTemplate", {}).get("ContainerSpec", {}).get("Image"), "Env": i.get("Spec", {}).get("TaskTemplate", {}).get("ContainerSpec", {}).get("Env"), "Mounts": i.get("Spec", {}).get("TaskTemplate", {}).get("ContainerSpec", {}).get("Mounts", []), "Replicas": i.get("Spec", {}).get("Mode", {}).get( "Replicated", {}).get("Replicas") or "global", "NetMode": i.get("Endpoint", {}).get("Spec", {}).get("Mode") or i.get("Spec", {}).get("EndpointSpec", {}).get("Mode"), "NetPorts": i.get("Endpoint", {}).get("Spec", {}).get("Ports"), "NetVip": i.get("Endpoint", {}).get("VirtualIPs"), "Version": i.get("Version", {}).get("Index"), "UpdateStatus": "%s(%s)" % (i.get("UpdateStatus").get("State"), i.get("UpdateStatus").get("CompletedAt")) if i.get("UpdateStatus").get("State") else None }) except Exception, e: logger.error(e, exc_info=True)
mountype = mountype or "bind" except Exception, e: logger.warn(e, exc_info=True) res.update(msg="mount format error", code=50002) logger.info(res) return res else: #Like this [{'source': '/data/swarmopsapi-logs', 'readonly': False, 'Type': 'bind', 'target': '/SwarmOpsApi/logs'}] Mounts.append({ "Source": source, "Target": target, "ReadOnly": readonly, "Type": mountype }) mount = Mounts logger.debug(mount) if isinstance(publish, (list, tuple)): Ports = [] for p in publish: logger.debug("publish a port data for split is %s" % p) if isinstance(p, dict): Ports.append(p) else: try: port = p.split(":") if len(port) == 2: logger.debug("split port 2") PublishedPort = int(port[0]) TargetPort = int(port[-1]) Protocol = "tcp"
def UpdatePasswd(): if g.signin: logger.debug(request.form) #ImmutableMultiDict([('username', u'admin'), ('new_pass', u''), ('new_repass', u''), ('old_pass', u'')]) else: abort(403)