從SCFCLI/SCF VSCode遷移過(guò)渡到Serverless Framework

SCFCLI和VSCode的插件很早之前就有了,也有很多用戶(hù)在使用這兩個(gè)工具, 使用它們可以通過(guò)已經(jīng)寫(xiě)的Yaml直接把函數(shù)部署到線(xiàn)上,非常方便艺智。但是眼尖的小伙伴已經(jīng)發(fā)現(xiàn)這樣一件事:SCFCLI和VSCode插件貌似很久都沒(méi)更新了,而且云函數(shù)的小伙伴在極力推動(dòng)大家使用Serverless Framework圾亏∈穑可以看到SCFCLI在6月份的時(shí)候更新頻繁,而現(xiàn)在志鹃,更新緩慢夭问。

同時(shí),細(xì)心的小伙伴還發(fā)現(xiàn)了弄跌,Serverless Framework貌似比SCFCLI好用凹缀取!因?yàn)樗粌H僅可以部署函數(shù)铛只,還可以部署APIGW埠胖,COS,CDN......最主要淳玩,通過(guò)Serverless Frameworek還可以快速的把常用的框架直撤,例如Express、Flask蜕着、Django.....等直接部署到云函數(shù)上谋竖,這是多方便的一件事情啊承匣!

就問(wèn)還在用SCFCLI的小伙伴蓖乘,你們酸沒(méi)酸?

有的小伙伴在躍躍欲試之后韧骗,終于下定決心嘉抒,將SCFCLI放棄掉,開(kāi)始使用Serverless Framework袍暴,那么問(wèn)題來(lái)了些侍,這兩個(gè)東西的Yaml寫(xiě)的不一樣,是完全不一樣政模,那么應(yīng)該如何把已有的SCFCLI/VSCode插件的Yaml快速轉(zhuǎn)換成為Serverless Framework的Yaml呢岗宣?

下面就是幾個(gè)簡(jiǎn)單的實(shí)現(xiàn)方法:

通過(guò)網(wǎng)頁(yè)進(jìn)行轉(zhuǎn)換

作為社區(qū)愛(ài)好者,我必然要提供一個(gè)簡(jiǎn)單的網(wǎng)頁(yè)淋样,來(lái)做這個(gè)事情:

http://serverless.0duzhan.com/app/scf_2_serverless/

通過(guò)這個(gè)網(wǎng)址耗式,你只需要輸入基于SCFCLI的Yaml,就可以快速轉(zhuǎn)換:

image

轉(zhuǎn)換結(jié)果是可以同時(shí)生成Component的Yaml和Plugin的Yaml

通過(guò)接口自主轉(zhuǎn)換

接口地址:

輸入?yún)?shù):yaml,字符串類(lèi)型纽什,就是之前SCFCLI/VSCODE插件的Yaml內(nèi)容

輸出參數(shù):error措嵌,布爾類(lèi)型躲叼,是否出錯(cuò)芦缰;result,字符串類(lèi)型枫慷,結(jié)果(error為true让蕾,此處輸出錯(cuò)誤信息,為false時(shí)輸出新的yaml結(jié)果)

以Python語(yǔ)言為例或听,將原有的Yaml轉(zhuǎn)換成為Component的Yaml可以這樣操作:

import urllib.request
import json

with open("template.yaml", 'r') as f:
    yamlData = f.read()

url = "http://service-8d3fi753-1256773370.bj.apigw.tencentcs.com/release/scf_2_serverless/components/"
data = {
    "yaml": yamlData
}
yamlResult = json.loads(urllib.request.urlopen(urllib.request.Request(url=url, data=json.dumps(data).encode("utf-8"))).read().decode("utf-8"))

print(yamlResult)

with open("output.yaml", "w") as f:
    f.write(yamlResult['result'])

這樣就可以把已有的SCFCLI Yaml轉(zhuǎn)換成Serverless Component的Yaml了探孝,Plugin的轉(zhuǎn)換方法同理,只需要更換一個(gè)一下url地址就好了誉裆。

自己寫(xiě)本地腳本來(lái)轉(zhuǎn)

def getBaseFunctionComponents(functionInformation, functionName=None, tempInputs=None):
    tempInputs = tempInputs if tempInputs else {}
    if functionName:
        tempInputs["name"] = functionName
    if isinstance(functionInformation, dict):
        for eveFunctionKey, eveFunctionValue in functionInformation.items():
            if eveFunctionKey not in ["Events", "Environment", "VpcConfig", "Type", "Role"]:
                tempKey = str.lower(eveFunctionKey[0]) + eveFunctionKey[1:]
                tempInputs[tempKey] = eveFunctionValue
            else:
                if eveFunctionKey == "Environment":
                    if eveFunctionValue and "Variables" in eveFunctionValue:
                        tempEnvironment = {
                            "variables": eveFunctionValue["Variables"]
                        }
                        tempInputs["environment"] = tempEnvironment
                elif eveFunctionKey == "VpcConfig":
                    tempVpcConfig = {}
                    if eveFunctionValue and "SubnetId" in eveFunctionValue:
                        tempSubnetId = eveFunctionValue["SubnetId"]
                        tempVpcConfig["subnetId"] = tempSubnetId
                    if eveFunctionValue and "VpcId" in eveFunctionValue:
                        tempVpcId = eveFunctionValue["VpcId"]
                        tempVpcConfig["vpcId"] = tempVpcId
                    tempInputs["vpcConfig"] = tempVpcConfig
                elif eveFunctionKey == "Events":
                    tempEvents = []
                    if isinstance(eveFunctionValue, dict):
                        for eveEventKey, eveEventValue in eveFunctionValue.items():
                            if isinstance(eveEventValue["Properties"], dict):
                                tempEvent = {}
                                if eveEventValue["Type"] == "APIGW":
                                    tempEvent['apigw'] = {
                                        "name": eveEventKey,
                                        "parameters": {}
                                    }
                                    tempParameter = {}
                                    tempEndpoints = {"path": "/" + functionName}
                                    for eveParameterKey, eveParameterValue in eveEventValue["Properties"].items():
                                        if eveParameterKey == "StageName":
                                            tempParameter["environment"] = eveParameterValue
                                        elif eveParameterKey == "ServiceId" and eveParameterValue:
                                            tempParameter["serviceId"] = eveParameterValue
                                        elif eveParameterKey == "HttpMethod":
                                            tempEndpoints["method"] = eveParameterValue
                                        elif eveParameterKey == "IntegratedResponse":
                                            tempEndpoints["function"] = {"isIntegratedResponse": eveParameterValue}
                                    tempParameter["endpoints"] = [tempEndpoints, ]
                                    tempEvent['apigw']["parameters"] = tempParameter
                                elif eveEventValue["Type"] == "COS":
                                    tempEvent['cos'] = {
                                        "name": eveEventKey,
                                        "parameters": {}
                                    }
                                    tempParameter = {}
                                    for eveParameterKey, eveParameterValue in eveEventValue["Properties"].items():
                                        if eveParameterKey == "Filter":
                                            tempFilter = {}
                                            for eveFilterKey, eveFilterValue in eveParameterValue.items():
                                                tempKey = str.lower(eveFilterKey[0]) + eveFilterKey[1:]
                                                tempFilter[tempKey] = eveFilterValue
                                            tempParameter["filter"] = tempFilter
                                        else:
                                            tempKey = str.lower(eveParameterKey[0]) + eveParameterKey[1:]
                                            tempParameter[tempKey] = eveParameterValue
                                    tempEvent['cos']["parameters"] = tempParameter
                                elif eveEventValue["Type"] == "Timer":
                                    tempEvent['timer'] = {
                                        "name": eveEventKey,
                                        "parameters": {}
                                    }
                                    tempParameter = {}
                                    for eveParameterKey, eveParameterValue in eveEventValue["Properties"].items():
                                        tempKey = str.lower(eveParameterKey[0]) + eveParameterKey[1:]
                                        tempParameter[tempKey] = eveParameterValue
                                    tempEvent['timer']["parameters"] = tempParameter
                                elif eveEventValue["Type"] == "CMQ":
                                    tempEvent['cmq'] = {
                                        "name": eveEventKey,
                                        "parameters": {}
                                    }
                                    tempParameter = {}
                                    for eveParameterKey, eveParameterValue in eveEventValue["Properties"].items():
                                        tempKey = str.lower(eveParameterKey[0]) + eveParameterKey[1:]
                                        tempParameter[tempKey] = eveParameterValue
                                    tempEvent['cmq']["parameters"] = tempParameter
                                elif eveEventValue["Type"] == "CKafka":
                                    tempEvent['ckafka'] = {
                                        "name": eveEventKey,
                                        "parameters": {}
                                    }
                                    tempParameter = {}
                                    for eveParameterKey, eveParameterValue in eveEventValue["Properties"].items():
                                        tempKey = str.lower(eveParameterKey[0]) + eveParameterKey[1:]
                                        tempParameter[tempKey] = eveParameterValue
                                    tempEvent['ckafka']["parameters"] = tempParameter

                                tempEvents.append(tempEvent)
                    if tempEvents:
                        tempInputs["events"] = tempEvents
    return tempInputs


def getFunctionComponents(functionName, function, tempInputs):
    isFunction = False
    if isinstance(function, dict):
        for eveKey, eveValue in function.items():
            if eveKey == "Type" and eveValue == "TencentCloud::Serverless::Function":
                isFunction = True
        if isFunction:
            for eveKey, eveValue in function.items():
                if eveKey == "Type" and eveValue == "TencentCloud::Serverless::Function":
                    continue
                else:
                    tempInputs = getBaseFunctionComponents(eveValue, functionName, tempInputs)
                    serverlessPluginYaml = {
                        "component": '@serverless/tencent-scf',
                        "inputs": tempInputs
                    }
                    return serverlessPluginYaml
        else:
            return False


def getEventPlugin(eventType, eventName, eventSource, deepList=[]):
    tempEvent = {}
    tempEvent[eventType] = {
        "name": eventName,
        "parameters": {}
    }
    tempParameter = {}
    for eveParameterKey, eveParameterValue in eventSource["Properties"].items():
        tempKey = str.lower(eveParameterKey[0]) + eveParameterKey[1:]
        if deepList and eveParameterKey in deepList:
            tempDeepData = {}
            for eveFilterKey, eveFilterValue in eveParameterValue.items():
                tempThisKey = str.lower(eveFilterKey[0]) + eveFilterKey[1:]
                tempDeepData[tempThisKey] = eveFilterValue
            tempParameter[tempKey] = tempDeepData
            continue
        tempParameter[tempKey] = eveParameterValue
    tempEvent[eventType]["parameters"] = tempParameter
    return tempEvent


def getBaseFunctionPlugin(functionInformation, functionName=None, tempInputs=None):
    tempInputs = tempInputs if tempInputs else {}
    if functionName:
        tempInputs["name"] = functionName
    if isinstance(functionInformation, dict):
        for eveFunctionKey, eveFunctionValue in functionInformation.items():
            if eveFunctionKey not in ["Events", "Environment", "VpcConfig", "Type", "Role"]:
                tempKey = str.lower(eveFunctionKey[0]) + eveFunctionKey[1:]
                tempInputs[tempKey] = eveFunctionValue
            else:
                if eveFunctionKey == "Environment":
                    if eveFunctionValue and "Variables" in eveFunctionValue:
                        tempEnvironment = {
                            "variables": eveFunctionValue["Variables"]
                        }
                        tempInputs["environment"] = tempEnvironment
                elif eveFunctionKey == "VpcConfig":
                    tempVpcConfig = {}
                    if eveFunctionValue and "SubnetId" in eveFunctionValue:
                        tempSubnetId = eveFunctionValue["SubnetId"]
                        tempVpcConfig["subnetId"] = tempSubnetId
                    if eveFunctionValue and "VpcId" in eveFunctionValue:
                        tempVpcId = eveFunctionValue["VpcId"]
                        tempVpcConfig["vpcId"] = tempVpcId
                    tempInputs["vpcConfig"] = tempVpcConfig
                elif eveFunctionKey == "Events":
                    tempEvents = []
                    if isinstance(eveFunctionValue, dict):
                        for eveEventKey, eveEventValue in eveFunctionValue.items():
                            if isinstance(eveEventValue["Properties"], dict):
                                tempEvent = {}
                                if eveEventValue["Type"] == "APIGW":
                                    tempEvent = getEventPlugin("apigw", eveEventKey, eveEventValue)
                                elif eveEventValue["Type"] == "COS":
                                    tempEvent = getEventPlugin("cos", eveEventKey, eveEventValue, ["Filter"])
                                elif eveEventValue["Type"] == "Timer":
                                    tempEvent = getEventPlugin("timer", eveEventKey, eveEventValue)
                                elif eveEventValue["Type"] == "CMQ":
                                    tempEvent['cmq'] = getEventPlugin("cmq", eveEventKey, eveEventValue)
                                elif eveEventValue["Type"] == "CKafka":
                                    tempEvent = getEventPlugin("ckafka", eveEventKey, eveEventValue)

                                tempEvents.append(tempEvent)
                    if tempEvents:
                        tempInputs["events"] = tempEvents
    return tempInputs


def getFunctionPlugin(functionName, function, tempInputs):
    isFunction = False
    if isinstance(function, dict):
        for eveKey, eveValue in function.items():
            if eveKey == "Type" and eveValue == "TencentCloud::Serverless::Function":
                isFunction = True
        if isFunction:
            for eveKey, eveValue in function.items():
                if eveKey == "Type" and eveValue == "TencentCloud::Serverless::Function":
                    continue
                else:
                    return getBaseFunctionPlugin(eveValue, functionName, tempInputs)
        else:
            return False


def doComponents(scfYaml):
    try:
        yamlData = yaml.load(scfYaml)
        functions = {}

        if "Globals" in yamlData:
            inputs = getBaseFunctionComponents(yamlData["Globals"]["Function"])

        if isinstance(yamlData['Resources'], dict):
            for eveKey, eveValue in yamlData['Resources'].items():
                for eveNamespaceKey, eveNamespaceValue in eveValue.items():
                    tempInputs = inputs.copy()
                    if eveNamespaceKey == "Type" and eveNamespaceValue == "TencentCloud::Serverless::Namespace":
                        continue
                    tempFunction = getFunctionComponents(eveNamespaceKey, eveNamespaceValue, tempInputs)
                    if tempFunction:
                        functions[eveNamespaceKey] = tempFunction
        return {
            "error": False,
            "result": yaml.safe_dump(functions)
        }
    except:
        return {
            "error": True,
            "result": "Scf Yaml未能正常轉(zhuǎn)換為Serverless Component Yaml"
        }


def doPlugin(scfYaml):
    try:

        yamlData = yaml.load(scfYaml)

        # 獲取Provider
        print("獲取Provider")
        if "Globals" in yamlData:
            provider = getBaseFunctionPlugin(yamlData["Globals"]["Function"])
        provider["name"] = "tencent"
        provider["credentials"] = "~/credentials"

        # 獲取service
        print("獲取Service")
        service = "Tencent-Serverless-Framework"

        # 獲取插件
        print("獲取Plugin")
        plugin = ["serverless-tencent-scf"]

        # 獲取函數(shù)
        print("獲取Function")
        functions = {}

        if isinstance(yamlData['Resources'], dict):
            for eveKey, eveValue in yamlData['Resources'].items():
                for eveNamespaceKey, eveNamespaceValue in eveValue.items():
                    tempInputs = {}
                    if eveNamespaceKey == "Type" and eveNamespaceValue == "TencentCloud::Serverless::Namespace":
                        continue
                    tempFunction = getFunctionPlugin(eveNamespaceKey, eveNamespaceValue, tempInputs)
                    if tempFunction:
                        functions[eveNamespaceKey] = tempFunction

        serverlessJson = {
            "service": service,
            "provider": provider,
            "plugins": plugin,
            "functions": functions
        }

        return {
            "error": False,
            "result": yaml.safe_dump(serverlessJson)
        }
    except Exception as e:
        print(e)
        return {
            "error": True,
            "result": "Scf Yaml未能正常轉(zhuǎn)換為Serverless Plugin Yaml"
        }

是的顿颅,就是這么粗暴,上來(lái)就扔代碼足丢。

使用方法很簡(jiǎn)單粱腻,如果是轉(zhuǎn)Plugin:

pluginYaml = doPlugin(scfYaml)

如果是轉(zhuǎn)Component:

componentYaml = doComponent(scfYaml)

代碼不是很好看,但是可以用斩跌,所以各位大佬輕噴就好绍些。另外代碼開(kāi)源了,可以參考:https://github.com/anycodes/ServerlessPractice/tree/master/scf_2_serverless


image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耀鸦,一起剝皮案震驚了整個(gè)濱河市柬批,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌袖订,老刑警劉巖氮帐,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異洛姑,居然都是意外死亡上沐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)吏口,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)奄容,“玉大人,你說(shuō)我怎么就攤上這事产徊“豪眨” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵舟铜,是天一觀的道長(zhǎng)戈盈。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么塘娶? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任归斤,我火速辦了婚禮,結(jié)果婚禮上刁岸,老公的妹妹穿的比我還像新娘脏里。我一直安慰自己,他們只是感情好虹曙,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布迫横。 她就那樣靜靜地躺著,像睡著了一般酝碳。 火紅的嫁衣襯著肌膚如雪矾踱。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,792評(píng)論 1 290
  • 那天疏哗,我揣著相機(jī)與錄音呛讲,去河邊找鬼。 笑死返奉,一個(gè)胖子當(dāng)著我的面吹牛贝搁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衡瓶,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼徘公,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了哮针?” 一聲冷哼從身側(cè)響起关面,我...
    開(kāi)封第一講書(shū)人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎十厢,沒(méi)想到半個(gè)月后等太,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛮放,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年缩抡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片包颁。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瞻想,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出娩嚼,到底是詐尸還是另有隱情蘑险,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布岳悟,位于F島的核電站佃迄,受9級(jí)特大地震影響泼差,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呵俏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一堆缘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧普碎,春花似錦吼肥、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至绪氛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涝影,已是汗流浹背枣察。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留燃逻,地道東北人序目。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像伯襟,于是被迫代替她去往敵國(guó)和親猿涨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

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

  • 前言 自2006年8月9日姆怪,Google首席執(zhí)行官埃里克·施密特(Eric Schmidt)在搜索引擎大會(huì)(SES...
    Dfounderliu閱讀 781評(píng)論 0 0
  • 前言 上一節(jié)稽揭,和大家分享了騰訊云的云函數(shù)俺附,我們非常簡(jiǎn)單的創(chuàng)建了一個(gè)函數(shù),并且通過(guò)一個(gè)叫API網(wǎng)關(guān)的觸發(fā)器溪掀,將簡(jiǎn)單的...
    Dfounderliu閱讀 355評(píng)論 0 0
  • AI_Album說(shuō)明 項(xiàng)目背景 在日常生活中事镣,我們經(jīng)常會(huì)遇到搜索照片的情況,尤其是對(duì)尋找過(guò)去很久的圖片揪胃,記憶中僅剩...
    Dfounderliu閱讀 641評(píng)論 0 0
  • 燈火留影相思某璃哟, 識(shí)得少年輕卷簾。 一灘水的光影讓人迷糊喊递、錯(cuò)愕随闪、驚喜,雨滴的漣漪擴(kuò)散開(kāi)來(lái)與又一滴雨滴的漣漪碰撞册舞,重...
    含丹閱讀 162評(píng)論 0 1
  • 來(lái)到簡(jiǎn)書(shū)半年之久,寫(xiě)了幾篇不成文的話(huà)盛杰,近幾個(gè)月心情大起大落挽荡,經(jīng)歷錯(cuò)綜復(fù)雜,沒(méi)有時(shí)間整理無(wú)頭的思緒即供,特別是夜深人靜的...
    木子果兒閱讀 122評(píng)論 0 2