• 使用 CloudStack API 进行监控(附监控脚本)


    如同 AWS API 一样,CloudStack API 也是基于 Web Service,可以使用任何一种支持 HTTP 调用的语言(例如 Java,PHP)编写代码。
    目前 CloudStack 采用以下两种认证方式:

    1. Session 认证
      通过 login API,获得一个 JSESSIONID cookie 和一个 SESSIONKEY token。
    2. API Key 认证

    一 、session认证方式

    详细请参考
    curl 访问 CloudStack API 的用法

    二、API Key 认证

    和监控有关的command有:

    • listSystemVms
    • listHosts

    我们以CloudStack管理员的身份(admin)为例, 可以先在CloudStack UI上生成用户的apikey和secretkey, 只有管理员权限可以生成这两个key。

    key的获取位置

    首页》帐户》admin》用户》admin》点击相应key右侧的小图标生成如下

    • apikey
      YOESnQc05-sc_PtnLpAP0fqKSKIR4ZYgFqCeFMPF3Sljr9V-Z_QaX6snnsIM_kRA8Md_5iky9-xxxxxxxxxxxx
    • secretkey
      xYdBHdYabSheGg9jy7ajjqQRjihDpdcb10J_09RqqfvGj5OAE5GXJdC7AMBhotrHpcnsyhajVzftjrxxxxxxxxxx

    下面是python的测试过程与最终的脚本

    1. python2.7安装
    首先下载源tar包
    可利用linux自带下载工具wget下载,如下所示:
    wget http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz
    下载完成后到下载目录下,解压
    tar -zxvf Python-2.7.3.tgz
    进入解压缩后的文件夹
    cd Python-2.7.3
    在编译前先在/usr/local建一个文件夹python27(作为python的安装路径,以免覆盖老的版本)
    mkdir /usr/local/python2.7.3
    在解压缩后的目录下编译安装
    ./configure --prefix=/usr/local/python2.7.3
    make
    make install
    此时没有覆盖老版本,再将原来/usr/bin/python链接改为别的名字
    mv /usr/bin/python /usr/bin/python2.6.6
    再建立新版本python的链接
    ln -s /usr/local/python2.7.3/bin/python2.7 /usr/bin/python
    这个时候输入
    python
    就会显示出python的新版本信息
    Python 2.7.3 (default, Sep 29 2013, 11:05:02)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-54)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    
    1. py测试脚本
    CloudStack Documentation, Release 4.8.0
    You will see an API Key and Secret Key field being generated. The keys will be of the form:
    API Key : rtmap
    Secret Key: TJyVDr17nNjvEuxTzga1QzkRLztNCKItaeY-h3hYCnmMXPkQe4Ic5q8hOeQOCGbT-jm3GcHXVFTWn6-ZYH-PnQ
    Open a Python shell and import the basic modules necessary to make the request.  Do note that this request could be
    made many different ways, this is just a low level example. Theurllib* modules are used to make the http request
    and do url encoding.  Thehashlib module gives us the sha1 hash function.  It used to geenrate the hmac
    (Keyed Hashing for Message Authentication) using the secretkey. The result is encoded using the base64 module.
    $python
    Python 2.7.3 (default, Nov 17 2012, 19:54:34)
    [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import urllib2
    >>> import urllib
    >>> import hashlib
    >>> import hmac
    >>> import base64
    Define the endpoint of the Cloud, the command that you want to execute, the type of the response (i.e XML or JSON)
    and the keys of the user.  Note that we do not put the secretkey in our request dictionary because it is only used to
    compute the hmac.
    >>>baseurl='http://localhost:8080/client/api?'
    >>>request={}
    >>>request['command']='listUsers'
    >>>request['response']='json'
    >>>request['apikey']='rtmap'
    >>>secretkey='TJyVDr17nNjvEuxTzga1QzkRLztNCKItaeY-h3hYCnmMXPkQe4Ic5q8hOeQOCGbT-jm3GcHXVFTWn6-ZYH-PnQ'
    Build the base request string, the combination of all the key/pairs of the request, url encoded and joined with amper-
    sand.
    >>>request_str='&'.join(['='.join([k,urllib.quote_plus(request[k])]) for k in request.keys()])
    >>>request_str
    'apikey=plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg&command=listUsers&response=json'
    Compute the signature with hmac, do a 64 bit encoding and a url encoding, the string used for the signature is similar
    to the base request string shown above but the keys/values are lower cased and joined in a sorted order
    >>>sig_str='&'.join(['='.join([k.lower(),urllib.quote_plus(request[k].lower().replace('+','%20'))])
    for
    k
    in
    sorted(request.iterkeys())])
    >>>sig_str
    'apikey=plgwjfzk4gys3momtvmjuvg-x-jlwlnfauj9gabbbf9edm-kaymmailqzzq1elzlyq_u38zcm0bewzgudp66mg&command=listusers&response=json'
    >>>sig=hmac.new(secretkey,sig_str,hashlib.sha1).digest()
    >>>sig
    'M:]x0exafxfbx8fxf2yxf1px91x1ex89x8axa1x05xc4Axdb'
    >>>sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest())
    >>>sig
    'TTpdDq/7j/J58XCRHomKoQXEQds=
    '
    >>>sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip()
    >>>sig
    'TTpdDq/7j/J58XCRHomKoQXEQds='
    >>>
    >>>sig=urllib.quote_plus(base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip())
    
    Finally, build the entire string by joining the baseurl, the request str and the signature. Then do an http GET:
    
    4.1.  CloudStack Installation from GIT repo for Developers
    CloudStack Documentation, Release 4.8.0
    >>>req=baseurl+request_str+'&signature='+sig
    >>>req
    'http://localhost:8080/client/api?apikey=rtmap&command=listUsers&response=json&signature=TTpdDq%2F7j%2FJ58XCRHomKoQXEQds%3D'
    >>>res=urllib2.urlopen(req) #401报错 应该不是代码问题,是url本身的问题,应为401,没有通过
    >>>res.read()
    {
    "listusersresponse" : {
    "count":1 ,
    "user" : [
    {
    "id":"7ed6d5da-93b2-4545-a502-23d20b48ef2a",
    "username":"admin",
    "firstname":"admin",
    "lastname":"cloud",
    "created":"2012-07-05T12:18:27-0700",
    "state":"enabled",
    "account":"admin",
    "accounttype":1,
    "domainid":"8a111e58-e155-4482-93ce-84efff3c7c77",
    "domain":"ROOT",
    "apikey":"plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg",
    "secretkey":"VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ",
    "accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"
    }
    ]
    }
    }
    All the clients that you will find on github will implement this signature technique, you should not have to do it by
    hand.   Now that you have explored the API through the UI and that you understand how to make low level calls,
    pick your favorite client of use CloudMonkey.  CloudMonkey is a sub-project of Apache CloudStack and gives oper-
    ators/developers the ability to use any of the API methods. It has nice auto-completion and help feature as well as an
    API discovery mechanism since 4.2.
    
    Python 2.7.3 (default, Apr 26 2016, 09:35:32) 
    [GCC 4.4.7 20120313 (Red Hat 4.4.7-16)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import urllib2
    import urllib
    import hashlib
    import hmac
    import base64
    baseurl='http://localhost:8080/client/api?'
    request={}
    request['command']='listUsers'
    request['response']='json'
    request['apikey']='rtmap'
    secretkey='TJyVDr17nNjvEuxTzga1QzkRLztNCKItaeY-h3hYCnmMXPkQe4Ic5q8hOeQOCGbT-jm3GcHXVFTWn6-ZYH-PnQ'
    request_str='&'.join(['='.join([k,urllib.quote_plus(request[k])]) for k in request.keys()])
    request_str
    sig_str='&'.join(['='.join([k.lower(),urllib.quote_plus(request[k].lower().replace('+','%20'))]) for k in sorted(request.iterkeys())])
    sig_str
    sig=hmac.new(secretkey,sig_str,hashlib.sha1).digest()
    sig
    sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest())
    sig
    sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip()
    sig
    sig=urllib.quote_plus(base64.encodestring(hmac.new(secretkey.lower(),sig_str,hashlib.sha1).digest()).strip())
    req=baseurl+request_str+'&signature='+sig
    req
    >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> 'apikey=rtmap&command=listUsers&response=json'
    >>> >>> 'apikey=rtmap&command=listusers&response=json'
    >>> >>> "x1dt6x9f?T~Ixed#'B0xa8xa8x81$Bxd5x92"
    >>> >>> 'HXQ2nz9UfkntIydCMKiogSRC1ZI=
    '
    >>> >>> 'HXQ2nz9UfkntIydCMKiogSRC1ZI='
    >>> >>> >>> 'http://localhost:8080/client/api?apikey=rtmap&command=listUsers&response=json&signature=HXQ2nz9UfkntIydCMKiogSRC1ZI%3D'
    >>> 
    >>> 
    
    1. 完整的python脚本(自己一直在用这个脚本)
    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    __author__ = '火罐儿'
    import time
    import re
    import urllib2
    import urllib
    import hashlib
    import hmac
    import base64
    #import requests
    import json
    import smtplib
    from email.mime.text import MIMEText
    from email.utils import formataddr
    import getopt,sys
    import os
    
    
    def requestUrl(url,apikey,signature,command):
        request={}
        request['command']=command
        request['apikey']=apikey
        request['response']='json'
        secretkey=signature
        request_url='&'.join(['='.join([r,urllib.quote_plus(request[r])]) for r in request.keys()])
        sig_url='&'.join(['='.join([r.lower(),urllib.quote_plus(request[r]).lower()]) for r in sorted(request.iterkeys())])
        sig=urllib.quote_plus(base64.encodestring(hmac.new(secretkey,sig_url,hashlib.sha1).digest()).strip())
        req=url+'?'+request_url+'&signature='+sig
        return req
    
    def reqresults(request_url):
        try:
            res = urllib2.urlopen(request_url)
        except urllib2.HTTPError, e: 
            sys.exit('invalid signaturekey!')
        except urllib2.URLError, e:
            sys.exit('invalid signaturekey!')
    
        return res.read()
    
    def api_request(url,params,_method="GET"):#
        if _method == "POST":
            rt = requests.post(url,params)
        else:
            rt = requests.get(url,params)
    
        return rt
    
    def deploy(AllList,url,apikey,secretkey,command):
        request_url = requestUrl(url,apikey,secretkey,command)
        #print request_url
        if command == 'listHosts':
            resultsNeed=json.loads(reqresults(request_url))
            hostList=resultsNeed['listhostsresponse']['host']
            #print json.dumps(hostList,indent=4)
            for i in hostList:
                name=i.get('name','None')
                state=i.get('state','None')
                disconnected=i.get('disconnected','None')
                ipaddress=i.get('ipaddress','None')
                #print('%s:%s state is %s at %s' %(name,ipaddress,state,disconnected))
                if i['state'] !='Up':
                    downListStr='%s:%s state is %s at %s' %(name,ipaddress,state,disconnected)
                    #sendmsg(downListStr,'192.168.xx.xx')
                    AllList.append(downListStr)
            return AllList
    
        elif command == 'listCapacity':
            capacity = {
            'memory':0,
            'CPU':1,
            'primary_storage':3,
            'secondary_storage':6,
            'share_network_ip':8,
            'local_storage':9,
            'management_ip':5
            }
            resultsNeed=json.loads(reqresults(request_url))
            capacityList=resultsNeed['listcapacityresponse']['capacity']
            #print json.dumps(capacityList,indent=4)
            for i in capacityList:
                type=i.get('type','None')
                for key,value in capacity.iteritems():
                    if type==value:
                        type=key
                percentused=i.get('percentused','None')
                #print('%s capacity is %s' %(type,percentused))
                if i['percentused'] > '80.00':
                    downListStr='%s capacity is %s' %(type,percentused)
                    AllList.append(downListStr)
            return AllList
        elif command == 'listVirtualMachines':
            command = 'listVirtualMachines&state=started'
            request_url = requestUrl(url,apikey,secretkey,command)
            print request_url
            print 'this procedure is coming soon.'
        elif command == 'resetPasswordForVirtualMachine':
            print 'this procedure is coming soon.'
        elif command == 'rebootVirtualMachine':
            print 'this procedure is coming soon.'
        elif command == 'startVirtualMachine':
            print 'this procedure is coming soon.'
        elif command == 'stopVirtualMachine':
            print 'this procedure is coming soon.'
        else :
            sys.exit('invalid command!')
    
    def sendmail(infor):
        msg = MIMEText(infor, 'plain', 'utf-8')
        msg['From'] = formataddr(["cloudstack节点告警",'alert@xxx.com'])
        msg['To'] = formataddr(['管理员','xxx@xxx.com'])
        msg['Subject'] = "CloudStack listHosts"
        try:
            server = smtplib.SMTP("smtp.xxx.com", 25)
            server.login("alert@xxx.com", "xxxxxx")
            server.sendmail('alert@xxx.com', 
    	['xxx@xxx.com'], 
            msg.as_string())
            server.quit()
            print "Warnning! 邮件发送成功!"
        except smtplib.SMTPException:
            print "Error: 无法发送邮件"
    
    def sendmsg(infor,server):
        p = re.compile('
    ')
        infor=re.sub(p,';',infor)
        #略
        try:
            os.system('curl "%s"'%(wxstring))
            print "微信发送成功!"
        except Exception, e:
            print "Error: 无法发送微信"
    
    
    def usage():
        msg="""
    option args: [-i,-p,-k,-s,-c]
    usage:
    -h,--help   display this help
    -i,--ip     set the cloudstack management ip
    -p,--port   set the cloudstack port
    -k,--apikey     set the cloudstack apikey
    -s,--secretkey  set the cloudstack secretkey
    -c,--command    set the cloudstack command parameter
    """
        print msg
    
    def main():
        AllList=[]
        try:
            options,args = getopt.getopt(sys.argv[1:],"hi:p:k:s:c:",["help","ip=","port=","apikey=","secretkey=","command="])
        except getopt.GetoptError:
            sys.exit(usage())
    
        #if options==[]:
        #   sys.exit(usage())
    
        for name,value in options:
            if name in ("-h","--help"):
                sys.exit(usage())
            elif name in ("-i","--ip"):
                server=value
            elif name in ("-p","--port"):
                apiport=value
            elif name in ("-k","--apikey"):
                apikey=value
            elif name in ("-s","--secretkey"):
                secretkey=value
            elif name in ("-c","--command"):
                command=value
            else:
                sys.exit(usage())
    
        options,args = getopt.getopt(sys.argv[1:],"hi:p:k:s:c:",["help","ip=","port=","apikey=","secretkey=","command="])
    
        if 'server' not in locals().keys():
            server = '192.168.100.20'
        if 'apiport' not in locals().keys():
            apiport = '8080'
        if 'command' not in locals().keys():
            command = 'listHosts'
        if 'apikey' not in locals().keys():
            apikey='YOESnQc05-sc_PtnLpAP0fqKSKIR4ZYgFqCeFMPF3Sljr9V-Z_QaX6snnsIM_kRA8Md_5iky9-xxxxxxxxxxxx'
        if 'secretkey' not in locals().keys():
            secretkey = 'xYdBHdYabSheGg9jy7ajjqQRjihDpdcb10J_09RqqfvGj5OAE5GXJdC7AMBhotrHpcnsyhajxxxxxxxxxxxx'
    
        url = 'http://' + server + ':' + apiport + '/client/api'
        deploy(AllList,url,apikey,secretkey,command)
        if AllList:
            for i in AllList:
    	    sendmsg(i,server)
            infor_list='
    '.join(AllList)
            sendmail(infor_list)
            sendmsg(infor_list,server)
            print '***************发送邮件内容:*****************'
            print infor_list
        else:
            print '***************一切正常**********************'
    
    if __name__ == '__main__':
        main()
    
    
    1. 脚本的执行
      python cloudstackmonitor.py
      -i 192.168.xx.xx
      -p 8080
      -k 'YOESnQc05-sc_PtnLpAP0fqKSKIR4ZYgFqCeFMPF3Sljr9V-Z_QaX6snnsIM_kRA8Md_5iky9-xxxxxxxxxxxx'
      -s 'xYdBHdYabSheGg9jy7ajjqQRjihDpdcb10J_09RqqfvGj5OAE5GXJdC7AMBhotrHpcnsyhajxxxxxxxxxxxxxxxx'
      -c listVirtualMachines

    附件

    官方API地址,运维自动化可参考
    http://cloudstack.apache.org/docs/api/apidocs-4.5/TOC_Root_Admin.html

    本文系作者原创,转载请注明出处。如您阅读的是转载,请最好再看下原文,原文随时会更新和勘误的。

    @Gordon_chang
    1997年毕业于北京联合大学,先后在中国万网,新媒传信,亚信等公司工作,现在在一家创业型公司担任云计算与大数据运维方面的 PM & Engineer。 专注于以下四个领域: 分布式存储 分布式数据库 云计算 大数据 重点通过技术架构与性能优化(底层)实现基于私有云的大数据平台能力

  • 相关阅读:
    [好好学习]在VMware中安装Oracle Enterprise Linux (v5.7)
    [冲昏头脑]IDEA中的maven项目中学习log4j的日志操作
    [烧脑时刻]EL表达式1分钟完事
    Sublime2 破解教程
    全脑瘫IT时代(八)
    全脑瘫IT时代(九)
    迁移完成
    USB Debug Cable (一)
    一个不是很常见的.Net Interop问题
    全脑瘫IT时代(十二)
  • 原文地址:https://www.cnblogs.com/gordonchang/p/9046173.html
Copyright © 2020-2023  润新知