Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/products.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

241 changes: 241 additions & 0 deletions products/uhadoop/TEST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
## UHadoop CLI 测试清单

### 准备工作

```bash
# 1. 确认凭据已配置
ucloud config list

# 2. 查看可用地域
ucloud region


# 3. 替换测试参数
# --region cn-bj2 --zone cn-bj2-02
```

---

### 一、查询命令

#### 1.1 list-framework-app — 查询框架和应用

```bash
go run . uhadoop list-framework-app --region <region> --zone <zone>
go run . uhadoop list-framework-app --region <region> --zone <zone> --output json
```

#### 1.2 list-node-type — 查询可用机型

```bash
go run . uhadoop list-node-type --region <region> --zone <zone>
go run . uhadoop list-node-type --region <region> --zone <zone> --node-role master
go run . uhadoop list-node-type --region <region> --zone <zone> --framework Hadoop --framework-version 3.3.4-udh3.2
```

#### 1.3 list — 列出集群

```bash
go run . uhadoop list --region <region>
go run . uhadoop list --region <region> --zone <zone> --limit 5
go run . uhadoop list --region <region> --id-only
go run . uhadoop list --all-region --output json
```

#### 1.4 describe — 查询集群详情

```bash
go run . uhadoop describe <instance-id> --region <region> --zone <zone>
go run . uhadoop describe <instance-id> --region <region> --zone <zone> --output json
```

---

### 二、修改命令

> ⚠️ 会对真实资源产生修改

#### 2.1 create — 创建集群

| 参数 | 必填 | 说明 |
|------|:--:|------|
| `--region` | ✅ | 地域 |
| `--zone` | ✅ | 可用区 |
| `--name` | ✅ | 集群名称 |
| `--framework` | ✅ | Hadoop / HDFS / MR / StarRocks-* |
| `--framework-version` | ✅ | 如 `3.3.4-udh3.2` |
| `--password` | ✅ | 登录密码(明文,自动 base64) |
| `--master-node-type` | | Master 机型,默认 `o.hadoop4m.xlarge` |
| `--core-node-type` | | Core 机型,默认 `o.hadoop2m.xlarge` |
| `--task-node-type` | | Task 机型(可选) |
| `--master-count` | | 默认 2(StarRocks 默认 3) |
| `--core-count` | | 默认 3 |
| `--task-count` | | 默认 0 |
| `--cluster-case` | | Spark / Hbase / Core-Hadoop |
| `--app-config` | | 手动指定组件,格式 `App#Version` |
| `--master-boot-disk-size` | | 系统盘 GB,默认 50 |
| `--master-data-disk-size` | | 数据盘 GB,默认 100 |
| `--core-boot-disk-size` | | 系统盘 GB,默认 50 |
| `--core-data-disk-size` | | 数据盘 GB,默认 200 |
| `--vpc-id` | | 可选 |
| `--subnet-id` | | 可选 |
| `--async` | | 异步模式,不等待创建完成 |

```bash
# Spark 模板创建
go run . uhadoop create \
--region <region> --zone <zone> \
--name test-spark --framework Hadoop \
--framework-version 3.3.4-udh3.2 \
--password 'YourPass123!' \
--cluster-case Spark

# 手动指定 app-config
go run . uhadoop create \
--region <region> --zone <zone> \
--name test-manual --framework Hadoop \
--framework-version 3.3.4-udh3.2 \
--password 'YourPass123!' \
--app-config Spark#3.5.3 --app-config Hive#3.1.3

# MR 集群(需要 --storage-cluster-id)
go run . uhadoop create \
--region <region> --zone <zone> \
--name test-mr --framework MR \
--framework-version 3.3.4-udh3.2 \
--password 'YourPass123!' \
--storage-cluster-id <id> \
--cluster-case Spark
```

#### 2.2 delete — 删除集群

| 参数 | 必填 | 说明 |
|------|:--:|------|
| `<instance-id>` | ✅ | 位置参数 |
| `--region` | ✅ | 地域 |
| `--zone` | ✅ | 可用区 |
| `--release-eip` | | 释放 EIP |
| `--yes` / `-y` | | 跳过确认 |

```bash
go run . uhadoop delete <instance-id> --region <region> --zone <zone>
go run . uhadoop delete <instance-id> --region <region> --zone <zone> --release-eip -y
```

#### 2.3 add-node — 扩容节点

| 参数 | 必填 | 说明 |
|------|:--:|------|
| `--region` | ✅ | 地域 |
| `--zone` | ✅ | 可用区 |
| `--instance-id` | ✅ | 集群 ID |
| `--node-role` | ✅ | core / task / client |
| `--node-type` | ✅ | 机型 |
| `--node-count` | | 默认 1 |
| `--password` | | Client 角色需要(明文) |
| `--boot-disk-size` | | 系统盘 GB,默认 50 |
| `--data-disk-size` | | 数据盘 GB,默认 200 |
| `--async` | | 异步模式 |

```bash
go run . uhadoop add-node \
--region <region> --zone <zone> \
--instance-id <id> --node-role core \
--node-type o.hadoop2m.xlarge
```

#### 2.4 restart-service — 启停服务

| 参数 | 必填 | 说明 |
|------|:--:|------|
| `--region` | ✅ | 地域 |
| `--zone` | ✅ | 可用区 |
| `--instance-id` | ✅ | 集群 ID |
| `--service-name` | ✅ | 服务名 |
| `--only-start` / `--only-stop` | | 只启/只停 |
| `--yes` / `-y` | | 跳过确认 |

```bash
go run . uhadoop restart-service \
--region <region> --zone <zone> \
--instance-id <id> --service-name Hive
```

#### 2.5 upgrade-node — 升级节点

| 参数 | 必填 | 说明 |
|------|:--:|------|
| `--region` | ✅ | 地域 |
| `--zone` | ✅ | 可用区 |
| `--instance-id` | ✅ | 集群 ID |
| `--node-role` | ✅ | master / core / task / client |
| `--node-type` | ✅ | 新机型 |
| `--node-name` | | 节点名(非 master 必填) |
| `--yes` / `-y` | | 跳过确认 |

```bash
go run . uhadoop upgrade-node \
--region <region> --zone <zone> \
--instance-id <id> --node-role master \
--node-type o.hadoop2m.xlarge
```

#### 2.6 upgrade-disk — 扩容磁盘

| 参数 | 必填 | 说明 |
|------|:--:|------|
| `--region` | ✅ | 地域 |
| `--zone` | ✅ | 可用区 |
| `--instance-id` | ✅ | 集群 ID |
| `--node-role` | ✅ | master / core / task / client |
| `--data-disk-size` | ✅ | 新数据盘大小 GB |
| `--boot-disk-size` | | 新系统盘大小 GB |
| `--node-name` | | 节点名(非 master 必填) |
| `--yes` / `-y` | | 跳过确认 |

```bash
go run . uhadoop upgrade-disk \
--region <region> --zone <zone> \
--instance-id <id> --node-role core \
--data-disk-size 500 --node-name <id>-core1
```

---

### 三、校验

```bash
# 编译
go build ./...

# golden 测试
GOROOT=/Users/user/.g/go GOTOOLCHAIN=local go test ./hack/snapshot -v -run 'uhadoop'

# 缺参立即报错
go run . uhadoop create --name test
# → required flag(s) "framework", "framework-version", "password", "region", "zone" not set
```

---

### 测试结果

| # | 命令 | 状态 |
|---|------|------|
| 1 | `list-framework-app` | ✅ |
| 2 | `list-node-type` | ✅ |
| 3 | `list` | ✅ |
| 4 | `describe` | ✅ |
| 5 | `create --cluster-case Spark` | ✅ |
| 6 | `create --app-config ...` | ✅ |
| 7 | `delete` | ✅ |
| 8 | `add-node` | ✅ |
| 9 | `restart-service` | ✅ |
| 10 | `upgrade-node` | ✅ |
| 11 | `upgrade-disk` | ✅ |
| 12 | `create` 缺参 | ✅ |
| 13 | `go build ./...` | ✅ |
| 14 | `go test ./hack/snapshot -v` | ✅ |

> ⬜ = 待测试 &ensp; ✅ = 通过 &ensp; ❌ = 失败
75 changes: 75 additions & 0 deletions products/uhadoop/internal/uhadoop/add_node.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package uhadoop

import (
"encoding/base64"
"fmt"
"time"

"github.com/spf13/cobra"
sdk "github.com/ucloud/ucloud-sdk-go/ucloud"

uhadoopsdk "github.com/ucloud/ucloud-sdk-go/services/uhadoop"

"github.com/ucloud/ucloud-cli/pkg/cli"
"github.com/ucloud/ucloud-cli/pkg/command"
)

func newAddNode(ctx *cli.Context) *cobra.Command {
var (
async *bool
rawPassword string
)
client := cli.NewServiceClient(ctx, uhadoopsdk.NewClient)
req := client.NewAddUHadoopInstanceNodeRequest()
cmd := &cobra.Command{
Use: "add-node",
Short: "Add nodes to a UHadoop cluster",
Long: `Add a number of nodes to an existing UHadoop cluster`,
SilenceUsage: true,
Run: func(cmd *cobra.Command, args []string) {
w := ctx.ProgressWriter()
if rawPassword != "" {
req.Password = sdk.String(base64.StdEncoding.EncodeToString([]byte(rawPassword)))
}
resp, err := client.AddUHadoopInstanceNode(req)
if err != nil {
ctx.HandleError(err)
return
}
if resp.RetCode != 0 {
ctx.HandleError(fmt.Errorf("[%d] %s", resp.RetCode, resp.Message))
return
}
text := fmt.Sprintf("uhadoop[%s] adding %d %s node(s)", *req.InstanceId, *req.NodeCount, *req.NodeRole)
if *async {
fmt.Fprintln(w, text)
} else {
ctx.PollerTo(w, describeClusterForPoll(ctx, client), cli.WithTimeout(60*time.Minute)).Spoll(*req.InstanceId, text, []string{stateRunning})
}
ctx.EmitResult(cli.OpResultRow{ResourceID: *req.InstanceId, Action: "add-node", Status: "Scaling"})
},
}
flags := cmd.Flags()
flags.SortFlags = false
req.Region = flags.String("region", ctx.DefaultRegion(), "Optional. Assign region")
req.Zone = flags.String("zone", "", "Optional. Assign availability zone")
req.ProjectId = flags.String("project-id", ctx.DefaultProjectID(), "Optional. Assign project-id")
req.InstanceId = flags.String("instance-id", "", "Required. Cluster instance ID")
req.NodeRole = flags.String("node-role", "", "Required. Node role: core|task|client")
req.NodeType = flags.String("node-type", "", "Required. Node type")
req.NodeCount = flags.Int("node-count", 1, "Number of nodes, default 1")
flags.StringVar(&rawPassword, "password", "", "Login password (client role requires)")
req.BootDiskSize = flags.String("boot-disk-size", "50", "Boot disk GB, default 50")
req.BootDiskType = flags.String("boot-disk-type", "CLOUD_RSSD", "Boot disk type, default CLOUD_RSSD")
req.DataDiskSize = flags.String("data-disk-size", "200", "Data disk GB, default 200")
req.DataDiskNum = flags.String("data-disk-num", "1", "Data disk num, default 1")
req.DataDiskType = flags.String("data-disk-type", "CLOUD_RSSD", "Data disk type, default CLOUD_RSSD")
async = flags.Bool("async", false, "Optional. Do not wait for node addition to finish")
command.SetFlagValues(cmd, "node-role", "core", "task", "client")
cmd.MarkFlagRequired("instance-id")
cmd.MarkFlagRequired("node-role")
cmd.MarkFlagRequired("node-type")
cmd.MarkFlagRequired("region")
cmd.MarkFlagRequired("zone")
return cmd
}
28 changes: 28 additions & 0 deletions products/uhadoop/internal/uhadoop/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package uhadoop

import (
"github.com/spf13/cobra"

"github.com/ucloud/ucloud-cli/pkg/cli"
)

// NewCommand builds the top-level `uhadoop` command.
func NewCommand(ctx *cli.Context) *cobra.Command {
cmd := &cobra.Command{
Use: "uhadoop",
Short: "List,create,delete,describe UHadoop clusters and manage nodes and services",
Long: `List,create,delete,describe UHadoop clusters and manage nodes and services`,
Args: cobra.NoArgs,
}
cmd.AddCommand(newList(ctx))
cmd.AddCommand(newDescribe(ctx))
cmd.AddCommand(newCreate(ctx))
cmd.AddCommand(newDelete(ctx))
cmd.AddCommand(newAddNode(ctx))
cmd.AddCommand(newListNodeType(ctx))
cmd.AddCommand(newListFrameworkApp(ctx))
cmd.AddCommand(newRestartService(ctx))
cmd.AddCommand(newUpgradeNode(ctx))
cmd.AddCommand(newUpgradeDisk(ctx))
return cmd
}
Loading
Loading