-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.go
182 lines (154 loc) · 5.02 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Copyright(C) 2022 PingCAP. All Rights Reserved.
package main
import (
"fmt"
"os"
"strconv"
)
const (
Host = "https://api.tidbcloud.com"
)
// getSpecifications returns all the available specifications
func getSpecifications() (*GetSpecificationsResp, error) {
var (
url = fmt.Sprintf("%s/api/v1beta/clusters/provider/regions", Host)
result GetSpecificationsResp
)
_, err := doGET(url, nil, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func getSpecClusterUsing(specifications *GetSpecificationsResp, cluster *GetClusterResp) (*Specification, error) {
for _, i := range specifications.Items {
if i.ClusterType == cluster.ClusterType && i.CloudProvider == cluster.CloudProvider && i.Region == cluster.Region {
return &i, nil
}
}
return nil, fmt.Errorf("No specification found")
}
// addTiFlashToCluster add TiFlash to a existing cluster
// If the vCPUs of TiDB or TiKV component is 2 or 4, then the cluster does not support TiFlash.
func addTiFlashToCluster(cluster *GetClusterResp, projectID uint64, spec *Specification) error {
var (
url = fmt.Sprintf("%s/api/v1beta/projects/%d/clusters/%d", Host, projectID, cluster.ID)
tiFlashComponent = cluster.Config.Components.TiFlash
)
if tiFlashComponent.NodeSize == "" {
if len(spec.Tiflash) == 0 {
return fmt.Errorf("No specification found")
}
// add TiFlash for cluster
tiFlashSpec := spec.Tiflash[0]
tiFlashComponent.NodeSize = tiFlashSpec.NodeSize
tiFlashComponent.StorageSizeGib = tiFlashSpec.StorageSizeGibRange.Min
tiFlashComponent.NodeQuantity = tiFlashSpec.NodeQuantityRange.Step
} else {
tiFlashComponent.NodeQuantity += 1 // add 1 TiFlash node it already has TiFlash
}
payload := ScaleClusterReq{
Config: ClusterConfig{
Components: Components{
TiDB: ComponentTiDB{
NodeSize: cluster.Config.Components.TiDB.NodeSize,
StorageSizeGib: cluster.Config.Components.TiDB.StorageSizeGib,
NodeQuantity: cluster.Config.Components.TiDB.NodeQuantity,
},
TiKV: ComponentTiKV{
NodeSize: cluster.Config.Components.TiKV.NodeSize,
StorageSizeGib: cluster.Config.Components.TiKV.StorageSizeGib,
NodeQuantity: cluster.Config.Components.TiKV.NodeQuantity,
},
TiFlash: tiFlashComponent,
},
},
}
_, err := doPATCH(url, payload, nil)
return err
}
// getClusterByID return detail status of given cluster
func getClusterByID(projectID, clusterID uint64) (*GetClusterResp, error) {
var (
url = fmt.Sprintf("%s/api/v1beta/projects/%d/clusters/%d", Host, projectID, clusterID)
result GetClusterResp
)
_, err := doGET(url, nil, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func main() {
fmt.Printf("\nWelcome to the TiDB Cloud demo!\n\n")
// Step 0: we need to initialize http client first
var (
publicKey = os.Getenv("TIDBCLOUD_PUBLIC_KEY")
privateKey = os.Getenv("TIDBCLOUD_PRIVATE_KEY")
projectID uint64
clusterID uint64
)
if publicKey == "" || privateKey == "" {
fmt.Printf("Please set TIDBCLOUD_PUBLIC_KEY(%s), TIDBCLOUD_PRIVATE_KEY(%s) in environment variable first\n", publicKey, privateKey)
return
}
projectID, err := strconv.ParseUint(os.Getenv("DEDICATED_PROJECT_ID"), 10, 64)
if err != nil {
fmt.Printf("Please set DEDICATED_PROJECT_ID in environment variable first\n")
return
}
clusterID, err = strconv.ParseUint(os.Getenv("DEDICATED_CLUSTER_ID"), 10, 64)
if err != nil {
fmt.Printf("Please set DEDICATED_CLUSTER_ID in environment variable first\n")
return
}
fmt.Printf("Step 0: initialize HTTP client\n")
err = initClient(publicKey, privateKey)
if err != nil {
fmt.Printf("Failed to init HTTP client\n")
return
}
// Step 1: scale cluster, add one TiFlash node
specs, err := getSpecifications()
if err != nil {
fmt.Printf("Failed to get specifications: %s\n", err)
return
}
cluster, err := getClusterByID(projectID, clusterID)
if err != nil {
fmt.Printf("Failed to get cluster %d: %s", clusterID, err)
return
}
if cluster.Status.ClusterStatus != ClusterAvailable {
fmt.Printf("Bad cluster status: %s", cluster.Status.ClusterStatus)
return
}
spec, err := getSpecClusterUsing(specs, cluster)
if err != nil {
fmt.Printf("Failed to get dedicated specification: %s\n", err)
return
}
fmt.Printf("Step 1: add TiFlash to cluster %d\n", clusterID)
err = addTiFlashToCluster(cluster, projectID, spec)
if err != nil {
fmt.Printf("Failed to add TiFlash to cluster %d: %s\n", clusterID, err)
return
}
// Step 2: check progress
fmt.Printf("Step 2: wait cluster to get ready\n")
cluster, err = getClusterByID(projectID, clusterID)
if err != nil {
fmt.Printf("Failed to get cluster status: %s\n", err)
return
}
fmt.Printf("Cluster status: %+v\n", cluster)
//waitFor("cluster", func() bool {
//cluster, err := getClusterByID(projectID, clusterID)
//if err != nil {
//fmt.Printf("Failed to query cluster detail by id %d: %s\n", clusterID, err)
//return false
//}
//return cluster.Status.ClusterStatus == ClusterAvailable
//})
fmt.Printf("You have scaled the cluster and add TiFlash\n")
}