KubeVela: como apresentar rapidamente os 50 recursos de nuvem mais populares da AWS com 100 linhas de código

Autor: Comunidade KubeVela

KubeVela atualmente suporta fornecedores de nuvem como AWS, Azure, GCP, Alibaba Cloud, Tencent Cloud, Baidu Cloud e UCloud, e também fornece ferramentas de linha de comando simples e rápidas [1] para introduzir recursos de nuvem de provedores de serviços de nuvem, mas no KubeVela one O suporte aos recursos de nuvem de provedores de serviços de nuvem por si só não é adequado para atender rapidamente às necessidades dos usuários por recursos de nuvem. Este artigo fornece uma solução para apresentar rapidamente os 50 principais recursos de nuvem mais populares na AWS com menos de 100 linhas de código.

Ao mesmo tempo, também esperamos que os usuários se inspirem neste artigo e contribuam com recursos de nuvem de outros provedores de serviços de nuvem.

Onde estão os recursos de nuvem mais populares da AWS?

O site oficial da Terraform fornece módulos Terraform de vários provedores de serviços em nuvem, como os módulos Terraform de recursos de nuvem da AWS[2]. Entre eles, os recursos de nuvem são classificados por popularidade (downloads), por exemplo, AWS VPC tem 18,7 milhões de downloads.

Por meio de uma análise simples, descobrimos que os dados dos 50 principais módulos Terraform da AWS podem ser obtidos solicitando registry.terraform.io/v2/modules?… .

antes do início

O código aceita dois parâmetros passados ​​pelo usuário: • o nome do provedor • a URL dos Módulos Terraform correspondentes ao provedor

Para AWS, o nome do provedor é "aws", e os módulos Terraform correspondentes são a interface de formato json do Terraform Modules [3] (ou seja, pesquise no Terraform Registry [4] pelos 50 recursos de nuvem mais populares quando o provedor for aws) . Antes de executar o código, você precisa confirmar se os links providerName(aws) e Modules estão corretos.

executar código

Em seguida, você pode apresentar rapidamente os 50 principais recursos de nuvem da AWS mais populares em lotes por meio das cerca de 100 linhas de código a seguir (nome do arquivo gen.go).

import (
  "encoding/json"
  "fmt"
  "io"
  "log"
  "net/http"
  "os"
  "os/exec"
  "path/filepath"
  "strings"
  "github.com/pkg/errors"
)
type TFDownload struct {
  Data     []DataItem     `json:"data"`
  Included []IncludedItem `json:"included"`
}
type IncludedItem struct {
  Id         string     `json:"id"`
  Attributes Attributes `json:"attributes"`
}
type DataItem struct {
  Attributes    Attributes    `json:"attributes"`
  Relationships Relationships `json:"relationships"`
}
type Relationships struct {
  LatestVersion RelationshipLatestVersion `json:"latest-version"`
}
type RelationshipLatestVersion struct {
  Data RelationshipData `json:"data"`
}
type RelationshipData struct {
  Id string `json:"id"`
}
var errNoVariables = errors.New("failed to find main.tf or variables.tf in Terraform configurations")
type Attributes struct {
  Name        string `json:"name"`
  Downloads   int    `json:"downloads"`
  Source      string `json:"source"`
  Description string `json:"description"`
  Verified    bool   `json:"verified"`
}
func main() {
  if len(os.Args) < 2 {
     fmt.Println("Please provide the cloud provider name and an official Terraform modules URL")
     os.Exit(1)
  }
  providerName := os.Args[1]
  terraformModulesUrl := os.Args[2]
  resp, err := http.Get(terraformModulesUrl)
  if err != nil {
     log.Fatal(err)
  }
  defer resp.Body.Close()
  body, err := io.ReadAll(resp.Body)
  if err != nil {
     log.Fatal(err)
  }
  var modules TFDownload
  if err := json.Unmarshal(body, &modules); err != nil {
     fmt.Println(err.Error())
     os.Exit(1)
  }
  if _, err = os.Stat(providerName); err == nil {
     if err := os.RemoveAll(providerName); err != nil {
        log.Fatal(err)
     }
     fmt.Printf("Successfully deleted existed directory %s\n", providerName)
  }
  if _, err = os.Stat(providerName); os.IsNotExist(err) {
     if err := os.Mkdir(providerName, 0755); err != nil {
        if !os.IsExist(err) {
           log.Fatal(err)
        }
        fmt.Printf("Successfully created directory %s\n", providerName)
     }
  }
  for _, module := range modules.Data {
     var description string
     for _, attr := range modules.Included {
        if module.Relationships.LatestVersion.Data.Id == attr.Id {
           description = attr.Attributes.Description
        }
     }
     if description == "" {
        description = strings.ToUpper(providerName) + " " + strings.Title(module.Attributes.Name)
     }
     outputFile := fmt.Sprintf("%s/terraform-%s-%s.yaml", providerName, providerName, module.Attributes.Name)
     if _, err := os.Stat(outputFile); !os.IsNotExist(err) {
        continue
     }
     if providerName == "aws" && (module.Attributes.Name == "rds" || module.Attributes.Name == "s3-bucket" ||
        module.Attributes.Name == "subnet" || module.Attributes.Name == "vpc") {
        continue
     }
     if err := generateDefinition(providerName, module.Attributes.Name, module.Attributes.Source, "", description); err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
     }
  }
}
func generateDefinition(provider, name, gitURL, path, description string) error {
  defYaml := filepath.Join(provider, fmt.Sprintf("terraform-%s-%s.yaml", provider, name))
  cmd := fmt.Sprintf("vela def init %s --type component --provider %s --git %s.git --desc \"%s\" -o %s",
     name, provider, gitURL, description, defYaml)
  if path != "" {
     cmd = fmt.Sprintf("%s --path %s", cmd, path)
  }
  fmt.Println(cmd)
  stdout, err := exec.Command("bash", "-c", cmd).CombinedOutput()
  if err != nil {
     return errors.Wrap(err, string(stdout))
  }
  fmt.Println(string(stdout))
  return nil
复制代码

Executando um pedido:

go run gen.go aws "https://registry.terraform.io/v2/modules?filter%5Bprovider%5D=aws&include=latest-version&page%5Bsize%5D=50&page%5Bnumber%5D=1"
复制代码

Breve Descrição do Código

解析云资源数据

访问用户传入的 URL,将返回的 json 数据解析为 Go 中的结构体。

资源对应的 json 格式如下:

{
  "data": [
    {
      "type": "modules",
      "id": "23",
      "attributes": {
        "downloads": 18440513,
        "full-name": "terraform-aws-modules/vpc/aws",
        "name": "vpc",
        "namespace": "terraform-aws-modules",
        "owner-name": "",
        "provider-logo-url": "/images/providers/aws.png",
        "provider-name": "aws",
        "source": "https://github.com/terraform-aws-modules/terraform-aws-vpc",
        "verified": true
      },
      "relationships": {
        "latest-version": {
          "data": {
            "id": "142143",
            "type": "module-versions"
          }
        }
      },
      "links": {
        "self": "/v2/modules/23"
      }
    },
    ...
  ],
  "included": [
    {
      "type": "module-versions",
      "id": "36806",
      "attributes": {
        "created-at": "2020-01-03T11:35:36Z",
        "description": "Terraform module Terraform module for creating AWS IAM Roles with heredocs",
        "downloads": 260030,
        "published-at": "2020-02-06T06:26:08Z",
        "source": "",
        "tag": "v2.0.0",
        "updated-at": "2022-02-22T00:45:44Z",
        "version": "2.0.0"
      },
      "links": {
        "self": "/v2/module-versions/36806"
      }
    },
    ...
  ],
  ...
}
复制代码

在 Modules 对应的 json 数据中,我们只关心两个键值对,即:

• data:包含 Modules 名称及属性的列表 • Included:筛选出的特定版本的 Modules 具体信息

其中,对于 data 中的每个 Module 元素,解析它的属性,Id 和 relationship 中的 latest-version 对应的 id;对于 Included 中的每个 Module 版本元素,解析它的属性和Id。

属性又解析如下五项:

• Name • Downloads • Source • Description • Verified

结构体定义在结构体 TFDownload 中,通过 http 库获取 json 数据,再通过 json.Unmarshal 解析出 Terraform modules 的结构体。

批量生产云资源

1. 新建目录,生成资源所需文件

解析完毕后,在当前目录下新建文件夹,文件夹命名为 provider 名称。 遍历解析后的 data,对于其中每个 Module 元素,执行下述操作,为其生成相应配置文件,定义和相应文档。

2. 生成定义文件

通过下述 vela 指令从模块对应的 github 仓库读取相应信息生成定义文件。

vela def init {ModuleName} --type component --provider {providerName} --git {gitURL} --desc {description} -o {yamlFileName}
复制代码

指令中需要填入的几项由解析好的 Module 结构体传入。

• gitURL: {Module.Attributes.Source}.git

• description: 如果 Included 中存在元素 ID 与模块 relationship 中 latest-version 对应 ID 相同,则 description 为 Included 中对应元素属性的 description;否则 description 为 providerName 与模块名称的拼接

• yamlFileName:terraform-{providerName}-{Module.Attributes.Name}.yaml

Você vai tentar também?

Há também muitos provedores de serviços em nuvem que fornecem módulos avançados do Terraform, como

GCP :registry.terraform.io/namespaces/…

Alibaba Cloud: registry.terraform.io/namespaces/…

Você também deseja apresentar os recursos de nuvem do provedor de serviços de nuvem que você está usando ou gosta do KubeVela?

Links Relacionados

[1] Ferramenta de linha de comando simples e rápida

kubevela.io/docs/next/p…

[2] Módulos Terraform de recursos de nuvem da AWS

registry.terraform.io/namespaces/…

[3] Interface de formato json dos Módulos Terraform

registry.terraform.io/v2/modules?…

[4] Registro Terraform

aregistry.terraform.io/

Acho que você gosta

Origin juejin.im/post/7078187427088564255
Recomendado
Clasificación