python調(diào)用cloudstack api批量操作機(jī)器

前言:公司為優(yōu)化資源占用和節(jié)約服務(wù)器成本蛙讥,考慮自建私有云平臺(tái)坎藐,最初領(lǐng)導(dǎo)有考慮用當(dāng)下最火的docker完成候醒,后來(lái)為保持穩(wěn)定性和可維護(hù)性(實(shí)際情況是對(duì)docker不熟能颁,怕出問(wèn)題搞不定,而cloudstack之前略有接觸)倒淫,最終決定用cloudstack來(lái)搭建云平臺(tái)伙菊,因?yàn)闄C(jī)房網(wǎng)絡(luò)環(huán)境特殊,以及cloudstack的版本問(wèn)題敌土,前后折騰一個(gè)多星期镜硕,才把這個(gè)私有云環(huán)境搭好,對(duì)著界面擼了一陣后返干,發(fā)現(xiàn)他沒(méi)有批量化操作兴枯,以及回收主機(jī)不回收磁盤等等毛病,于是想利用調(diào)官方提供的api來(lái)對(duì)它進(jìn)行批量化操作矩欠,于是并有了這篇文章财剖。

官方api地址:http://cloudstack.apache.org/docs/api/apidocs-4.2/TOC_Root_Admin.html

api腳本

cloud_api.py

#coding:utf-8

import urllib, urllib2
import hashlib
import hmac
import base64
import json
import sys
import argparse
from time import sleep

# 設(shè)置全局代理
#import socket, socks
#socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", 1090)
#socket.socket = socks.socksocket

# 設(shè)置默認(rèn)字符編碼
reload(sys)
sys.setdefaultencoding('utf-8')

class CloudAPI():

    def __init__(self):
        # 配置 cloudstack api
        self.config = {
            'api_url': 'http://10.10.252.116:8080/client/api?',
            'api_response_type': 'json',
            #key
            'api_key': 'FkZxPdLWvMVYJBZW82NZvXWPwG7NSE0f8i6OgqS2XYUt-cd4uKZbfaAC94oDa9lf6HqbCvw2u-hYTBVCvZCDjg',
            'api_secretkey': 'l2WyVLtjVEv1Eb8jYWW9GF6t1U-xciwQagQUwkDEa77CtNmn7hvI_CMdouCsX5VBXXiWnQjZ3C9zUORU2ijUVA',

            'zoneid': '6f30bf67-7342-4025-977f-0e989a772e25'  # weimob_sub11
        }

    def apiresult(self,params):
        params['apikey'] = self.config['api_key']
        params['response'] = self.config['api_response_type']

        request_str = '&'.join(['='.join([k, urllib.quote_plus(params[k])]) for k in params.keys()])
        sig_str = '&'.join(['='.join([k.lower(), urllib.quote_plus(params[k].lower().replace('+', '%20'))]) for k in
                            sorted(params.iterkeys())])
        signature = urllib.quote_plus(
            base64.encodestring(hmac.new(self.config['api_secretkey'], sig_str, hashlib.sha1).digest()).strip())

        request_url = self.config['api_url'] + request_str + '&signature=' + signature
        result = urllib2.urlopen(request_url)
        response = json.loads(result.read())
        return response

    # 列出虛擬機(jī)實(shí)例
    def listVirtualMachines(self,hostname=''):
        print "查詢主機(jī)信息"
        params = {
            'command':'listVirtualMachines',
            'name':hostname
        }

        response = self.apiresult(params)

        instances = []
        if not response['listvirtualmachinesresponse']:
            print "VirtualMachine is \033[31mnot exist\033[0m!"
            return False
        elif hostname:
            for instance in response['listvirtualmachinesresponse']['virtualmachine']:
                try:
                    if hostname == instance['name']:
                        instance_info = [instance['id'],instance['name'],instance['nic'][0]['ipaddress'],instance['hostname'],instance['templatename'],instance['serviceofferingname'],instance['state']]
                        print "HostName:\033[32m%s\033[0m HostIp:\033[32m%s\033[0m PhysicalHost:\033[32m%s\033[0m Template:\033[32m%s\033[0m Spec:\033[32m%s\033[0m Status:\033[32m%s\033[0m" \
                                % (instance_info[1],instance_info[2],instance_info[3],instance_info[4],instance_info[5],instance_info[6])
                        return [instance['id'],instance['state']]
                except KeyError as e:
                    print "\033[35m%s\033[0m status is \033[31merror\033[0m !" % instance['name']
                    return [instance['id'],instance['state']]
        else:
            for instance in response['listvirtualmachinesresponse']['virtualmachine']:
                try:
                    instance_info = [instance['id'],instance['name'],instance['nic'][0]['ipaddress'],instance['hostname'],instance['templatename'],instance['serviceofferingname'],instance['state']]
                    print "HostName:\033[32m%s\033[0m HostIp:\033[32m%s\033[0m PhysicalHost:\033[32m%s\033[0m Template:\033[32m%s\033[0m Spec:\033[32m%s\033[0m Status:\033[32m%s\033[0m" \
                                % (instance_info[1],instance_info[2],instance_info[3],instance_info[4],instance_info[5],instance_info[6])
                    instances.append(instance_info)
                except KeyError as e:
                    print "\033[35m%s status is error\033[0m !" % instance['name']
                    return [instance['id'],instance['state']]
            print "統(tǒng)計(jì): %s" % len(instances)
            return instances

        return response

    # 列出模板
    def listTemplates(self,templatename=''):
        params = {
            'command':'listTemplates',
            'templatefilter':'all'
        }

        response = self.apiresult(params)

        instances = []
        if not response['listtemplatesresponse']:
            print "Template is not exist!"
            return False
        elif templatename:
            for instance in response['listtemplatesresponse']['template']:
                if templatename == instance['name']:
                    instance_info = [instance['id'], instance['name']]
                    print "TemplateId:\033[32m%s\033[0m TemplateName:\033[32m%s\033[0m" % (instance_info[0],instance_info[1])
                    return instance['id']
        else:
            for instance in response['listtemplatesresponse']['template']:
                instance_info = [instance['id'],instance['name']]
                print "TemplateId:\033[32m%s\033[0m TemplateName:\033[32m%s\033[0m" % (instance_info[0],instance_info[1])
                instances.append(instance_info)
            print "統(tǒng)計(jì): %s" % len(instances)
            return instances

        return response

    # 列出計(jì)算方案
    def listServiceOfferings(self,serviceoffername=''):
        params = {
            'command':'listServiceOfferings'
        }

        response = self.apiresult(params)

        instances = []
        if not response['listserviceofferingsresponse']:
            print "ServiceOffer is not exist!"
            return False
        elif serviceoffername:
            for instance in response['listserviceofferingsresponse']['serviceoffering']:
                if serviceoffername == instance['name']:
                    instance_info = [instance['id'], instance['name'], instance['storagetype']]
                    print "ServiceOfferId:\033[32m%s\033[0m ServiceOfferName:\033[32m%s\033[0m StorageType:\033[32m%s\033[0m" % (instance_info[0],instance_info[1],instance_info[2])
                    return instance['id']
        else:
            for instance in response['listserviceofferingsresponse']['serviceoffering']:
                instance_info = [instance['id'], instance['name'], instance['storagetype']]
                print "ServiceOfferId:\033[32m%s\033[0m ServiceOfferName:\033[32m%s\033[0m StorageType:\033[32m%s\033[0m" % (instance_info[0],instance_info[1],instance_info[2])
                instances.append(instance_info)
            print "統(tǒng)計(jì): %s" % len(instances)
            return instances

        return response

    # 列出磁盤方案
    def listDiskOfferings(self,diskoffername=''):
        params = {
            'command':'listDiskOfferings'
        }

        response = self.apiresult(params)

        instances = []
        if not response['listdiskofferingsresponse']:
            print "DiskOffer is not exist!"
            return False
        elif diskoffername:
            for instance in response['listdiskofferingsresponse']['diskoffering']:
                if diskoffername == instance['name']:
                    instance_info = [instance['id'], instance['name'], instance['disksize'], instance['storagetype']]
                    print "DiskOfferId:\033[32m%s\033[0m DiskOfferName:\033[32m%s\033[0m DiskSize:\033[32m%s\033[0m StorageType:\033[32m%s\033[0m" % (instance_info[0],instance_info[1],instance_info[2],instance_info[3])
                    return instance['id']
        else:
            for instance in response['listdiskofferingsresponse']['diskoffering']:
                instance_info = [instance['id'], instance['name'], instance['disksize'], instance['storagetype']]
                print "DiskOfferId:\033[32m%s\033[0m DiskOfferName:\033[32m%s\033[0m DiskSize:\033[32m%s\033[0m StorageType:\033[32m%s\033[0m" % (instance_info[0],instance_info[1],instance_info[2],instance_info[3])
                instances.append(instance_info)
            print "統(tǒng)計(jì): %s" % len(instances)
            return instances

        return response

    # 列出數(shù)據(jù)磁盤
    def listVolumes(self, hostname=''):
        params = {
            'command':'listVolumes'
        }

        response = self.apiresult(params)

        instances = []
        if not response['listvolumesresponse']:
            print "listVolumes is not exist!"
            return False
        elif hostname:
            for instance in response['listvolumesresponse']['volume']:
                try:
                    if instance['type'] == 'DATADISK' and hostname == instance['vmname']:
                        instance_info = [instance['id'], instance['name'], instance['type'], instance['diskofferingdisplaytext'], instance['vmstate'], instance['vmname']]
                        print "VolumeId:\033[32m%s\033[0m VolumeName:\033[32m%s\033[0m VolumeType:\033[32m%s\033[0m VolumeSize:\033[32m%s\033[0m VolumeStatus:\033[32m%s\033[0m VolumeHost:\033[32m%s\033[0m" % (instance_info[0],instance_info[1],instance_info[2],instance_info[3], instance_info[4], instance_info[5])
                        return [instance['id'], instance['name']]
                except KeyError as e:
                    print "\033[35m%s status is error\033[0m !" % instance['name']
                    return response['listvolumesresponse']['volume']
        else:
            for instance in response['listvolumesresponse']['volume']:
                try:
                    if instance['type'] == 'DATADISK':
                        instance_info = [instance['id'], instance['name'], instance['type'], instance['diskofferingdisplaytext'], instance['vmstate'], instance['vmname']]
                        print "VolumeId:\033[32m%s\033[0m VolumeName:\033[32m%s\033[0m VolumeType:\033[32m%s\033[0m VolumeSize:\033[32m%s\033[0m VolumeStatus:\033[32m%s\033[0m VolumeHost:\033[32m%s\033[0m" % (instance_info[0],instance_info[1],instance_info[2],instance_info[3], instance_info[4], instance_info[5])
                        instances.append(instance_info)
                except KeyError as e:
                    print "\033[35m%s status is error\033[0m !" % instance['name']
                    return response['listvolumesresponse']['volume']
            print "統(tǒng)計(jì): %s" % len(instances)
            return instances

        return response

    # 部署虛擬機(jī)實(shí)例
    def deployVirtualMachine(self, hostname='',templatename='',serviceoffername='',diskoffername=''):
        if self.listVirtualMachines(hostname=hostname) or not (hostname and serviceoffername and templatename and diskoffername):
            print "you need four args,or the hostname is exist!"
            sys.exit()

        serviceofferingid = self.listServiceOfferings(serviceoffername=serviceoffername)
        templateid = self.listTemplates(templatename=templatename)
        diskofferingid = self.listDiskOfferings(diskoffername=diskoffername)

        params = {
            'command': 'deployVirtualMachine',
            'zoneid': self.config['zoneid'],
            'name':hostname,
            'displayname':hostname,
            'serviceofferingid': serviceofferingid,
            'templateid':templateid,
            'diskofferingid':diskofferingid
        }

        response = self.apiresult(params)
        print "The \033[32m%s\033[0 mis will be \033[32mDeploy\033[0m...!" % hostname
        return response

    # 操作虛擬機(jī)實(shí)例,包括啟動(dòng)癌淮、停止躺坟、重啟、銷毀乳蓄、重置密碼
    def actionVirtualMachine(self, hostname='', action=''):
        status = {
            'start':'Running',
            'stop':'Stopped',
            'reboot':'',
            'destroy':''
        }

        hostinfo = self.listVirtualMachines(hostname=hostname)
        if not (hostname and action and hostinfo):
            print "You need \033[36mtwo args\033[0m!"
            sys.exit()

        if hostinfo[1] == status[action]:
            print "The \033[36m%s\033[0m Status is \033[33m%s\033[0m !" % (hostname,hostinfo[1])
            sys.exit()

        params = {
            'command': action + 'VirtualMachine',
            'id': hostinfo[0]
        }

        response = self.apiresult(params)
        sleep(3)

        # 回收機(jī)器時(shí)咪橙,刪除掛載數(shù)據(jù)盤, 這個(gè)有點(diǎn)問(wèn)題,因?yàn)闄C(jī)器刪掉時(shí)還沒(méi)關(guān)機(jī)虚倒,直接刪磁盤會(huì)報(bào)錯(cuò), 暫時(shí)注釋掉
        # 我想的是先把掛載的磁盤name寫(xiě)入到一個(gè)文件美侦,之后在根據(jù)這個(gè)文件刪除數(shù)據(jù)磁盤
        # if action == 'destroy':
        #     volumeid = self.listVolumes(hostname=hostname)[0]
        #     params = {
        #         'command': 'deleteVolume',
        #         'id': volumeid
        #     }
        #     response = self.apiresult(params)

        print "the %s now is \033[32m%s\033[0m , it will be \033[31m%s\033[0m...!" % (hostname,hostinfo[1],action)
        return response

if __name__ == '__main__':
    cloudapi=CloudAPI()
    parser=argparse.ArgumentParser(description='cloudstack api ',usage='%(prog)s [options]')
    parser.add_argument('-l','--host',nargs='?',dest='listhost',default='host',help='查詢主機(jī)')
    parser.add_argument('-s','--serviceoffer',nargs='?',dest='serviceoffer',default='serviceoffer',help='查詢計(jì)算方案')
    parser.add_argument('-d','--diskoffer',nargs='?',dest='diskoffer',default='diskoffer',help='查詢磁盤方案')
    parser.add_argument('-t','--template',nargs='?',dest='template',default='template',help='查詢模板信息')
    parser.add_argument('-vd', '--volume', nargs='?', dest='volume', default='volume', help='查詢掛載的數(shù)據(jù)磁盤')
    parser.add_argument('-A','--add-host',dest='addhost',nargs=4,metavar=('sh-aa-01','centos_6.5','S1-2c-2g-local','disk_10G'),help='部署主機(jī),填寫(xiě)主機(jī)名、模板魂奥、計(jì)算方案菠剩、磁盤方案')
    parser.add_argument('-S','--start-host',dest='starthost',nargs=1,metavar=('sh-aa-01'),help='啟動(dòng)主機(jī),填寫(xiě)主機(jī)名')
    parser.add_argument('-P','--stop-host',dest='stophost',nargs=1,metavar=('sh-aa-01'),help='停掉主機(jī),填寫(xiě)主機(jī)名')
    parser.add_argument('-R','--reboot-host',dest='reboothost',nargs=1,metavar=('sh-aa-01'),help='重啟主機(jī),填寫(xiě)主機(jī)名')
    parser.add_argument('-D','--destroy-host',dest='destroyhost',nargs=1,metavar=('sh-aa-01'),help='銷毀主機(jī),填寫(xiě)主機(jī)名')
    parser.add_argument('-v','--version', action='version', version='%(prog)s 1.0')

    if len(sys.argv) == 1:    
        #html = parser.print_help()
        html = cloudapi.listVolumes(hostname='sh-ops-cloud-test-online-01')
        #html = cloudapi.listVirtualMachines(hostname='sh-ops-cloud-test-online-01')
        #html = cloudapi.deployVirtualMachine(hostname='sh-ops-cloud-test-online-03',serviceoffername='S1-2c-2g-local',templatename='centos_6.5',diskoffername='disk_10G')
        print html
    else:
        args = parser.parse_args()
        if args.listhost != 'host':
            if args.listhost:
                cloudapi.listVirtualMachines(args.listhost)
            else:
                cloudapi.listVirtualMachines()
        if args.serviceoffer != 'serviceoffer':
            if args.serviceoffer:
                cloudapi.listServiceOfferings(args.serviceoffer)
            else:
                cloudapi.listServiceOfferings()
        if args.diskoffer != 'diskoffer':
            if args.diskoffer:
                cloudapi.listDiskOfferings(args.diskoffer)
            else:
                cloudapi.listDiskOfferings()
        if args.template != 'template':
            if args.template:
                cloudapi.listTemplates(args.template)
            else:
                cloudapi.listTemplates()
        if args.volume != 'volume':
            if args.volume:
                cloudapi.listVolumes(args.volume)
            else:
                cloudapi.listVolumes()
        if args.addhost:
            cloudapi.deployVirtualMachine(args.addhost[0], args.addhost[1], args.addhost[2], args.addhost[3])
        if args.starthost:
            cloudapi.actionVirtualMachine(args.starthost[0],'start')
        if args.stophost:
            cloudapi.actionVirtualMachine(args.stophost[0],'stop')
        if args.reboothost:
            cloudapi.actionVirtualMachine(args.reboothost[0],'reboot')
        if args.destroyhost:
            cloudapi.actionVirtualMachine(args.destroyhost[0],'destroy')

查看執(zhí)行效果

python cloud_api.py -l
查詢
python cloud_api.py -h
help

對(duì)主機(jī)進(jìn)行操作

python cloud_api.py -S sh-ops-cloud-test-online-02
action

批量執(zhí)行腳本

cloud_cli.py

# -*- coding: utf-8 -*-

import os
import sys
import argparse

from cloud_api import CloudAPI

reload(sys)
sys.setdefaultencoding('utf-8')

host_file = 'target'
s_template = 'centos-6.5-templete'   # 這里是默認(rèn)系統(tǒng)模板
s_diskoffer = ''    # 這里是默認(rèn)規(guī)格磁盤
cmd = 'python cloud_api.py'


def deploy_hosts():
    # 實(shí)例化cloud_api
    cloudstack = CloudAPI()
    cloudstack.listServiceOfferings()

    s_serviceoffer = raw_input("Please Input ServiceOffer Name: ")
    # s_diskoffer = raw_input("Please Input DiskOffer Name: ")

    with open(host_file) as fb:
        host_info = list(line.strip() for line in fb)

    for s_hostname in host_info:
        cmd1 = ' '.join([cmd, sys.argv[1], s_hostname, s_template, s_serviceoffer])
        #cmd1 = ' '.join([cmd, sys.argv[1], s_hostname, s_template, s_serviceoffer, s_diskoffer])
        os.system(cmd1)

def action_hosts():
    with open(host_file) as fb:
        host_info = list(line.strip() for line in fb)
    for s_hostname in host_info:
        cmd1 = ' '.join([cmd, sys.argv[1], s_hostname])
        os.system(cmd1)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='cloudstack api ', usage='%(prog)s [options]')
    parser.add_argument('-l', '--listhost', nargs='?', dest='listhost', default='listhost', help='批量查詢主機(jī)')
    parser.add_argument('-A', '--addhost', nargs='?', dest='addhost', default='addhost', help='批量部署主機(jī)')
    parser.add_argument('-S', '--starthost', nargs='?', dest='starthost', default='starthost', help='批量啟動(dòng)主機(jī)')
    parser.add_argument('-P', '--stophost', nargs='?', dest='stophost', default='stophost', help='批量關(guān)掉主機(jī)')
    parser.add_argument('-R', '--reboothost', nargs='?', dest='reboothost', default='reboothost', help='批量重啟主機(jī)')
    parser.add_argument('-D', '--destroyhost', nargs='?', dest='destroyhost', default='destroyhost', help='批量銷毀主機(jī)')

    if len(sys.argv) == 1:
        html = parser.print_help()
        print html
    elif sys.argv[1] == '-A':
        deploy_hosts()
    else:
        action_hosts()

查看執(zhí)行效果

python cloud_cli.py -h
help

批量部署主機(jī)

填寫(xiě)target文件(被操作主機(jī)名)

> cat target
sh-ops-cloud-test-online-07
sh-ops-cloud-test-online-08

執(zhí)行

 python cloud_cli.py -A
addhosts

批量查看主機(jī)

python cloud_cli.py -l
listhosts

批量啟動(dòng)主機(jī)

python cloud_cli.py -S
starthosts
  • 好了,關(guān)于cloudstack的api操作到此為止捧弃,有其它需求的朋友可參考官方api介紹自行修改腳本赠叼。
  • 近日在github上搜到一個(gè)寫(xiě)的很全的cloudapi項(xiàng)目,cloudstack-python-client违霞,這個(gè)寫(xiě)的非常全嘴办,之后會(huì)以它為模板寫(xiě)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末买鸽,一起剝皮案震驚了整個(gè)濱河市涧郊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眼五,老刑警劉巖妆艘,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彤灶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡批旺,警方通過(guò)查閱死者的電腦和手機(jī)幌陕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)汽煮,“玉大人搏熄,你說(shuō)我怎么就攤上這事∠境啵” “怎么了心例?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鞋囊。 經(jīng)常有香客問(wèn)我止后,道長(zhǎng),這世上最難降的妖魔是什么溜腐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任译株,我火速辦了婚禮,結(jié)果婚禮上逗扒,老公的妹妹穿的比我還像新娘古戴。我一直安慰自己欠橘,他們只是感情好矩肩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著肃续,像睡著了一般黍檩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上始锚,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天刽酱,我揣著相機(jī)與錄音,去河邊找鬼瞧捌。 笑死棵里,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的姐呐。 我是一名探鬼主播殿怜,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼曙砂!你這毒婦竟也來(lái)了头谜?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鸠澈,失蹤者是張志新(化名)和其女友劉穎柱告,沒(méi)想到半個(gè)月后截驮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡际度,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年葵袭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乖菱。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡眶熬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出块请,到底是詐尸還是另有隱情娜氏,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布墩新,位于F島的核電站贸弥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏海渊。R本人自食惡果不足惜绵疲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望臣疑。 院中可真熱鬧盔憨,春花似錦、人聲如沸讯沈。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缺狠。三九已至问慎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挤茄,已是汗流浹背如叼。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留穷劈,地道東北人呻率。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓死姚,卻偏偏與公主長(zhǎng)得像肄鸽,于是被迫代替她去往敵國(guó)和親钓简。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理练湿,服務(wù)發(fā)現(xiàn)猴仑,斷路器,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • Docker — 云時(shí)代的程序分發(fā)方式 要說(shuō)最近一年云計(jì)算業(yè)界有什么大事件?Google Compute Engi...
    ahohoho閱讀 15,530評(píng)論 15 147
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,070評(píng)論 25 707
  • 女人無(wú)所謂正派榴捡,正派是以為受到的引誘不夠;男人無(wú)所謂忠誠(chéng)朱浴,忠誠(chéng)是因?yàn)楸撑?的籌碼太低吊圾。 最近搞笑的賀歲片特別多!但...
    叔夜君閱讀 512評(píng)論 0 1
  • 《滾滾紅塵》翰蠢,三毛的遺世之作项乒。背景是二十世紀(jì)四十年代動(dòng)蕩不安的中國(guó),更是一部讓人太多想象的影片梁沧。故事寫(xiě)的是張愛(ài)玲和...
    青衫素履閱讀 582評(píng)論 0 2