@@ -18,6 +18,7 @@ import (
1818 "encoding/base64"
1919 "fmt"
2020 "io"
21+ "regexp"
2122 "strings"
2223 "sync"
2324 "time"
@@ -59,6 +60,7 @@ func NewCmdUHost() *cobra.Command {
5960 cmd .AddCommand (NewCmdUhostReinstallOS (out ))
6061 cmd .AddCommand (NewCmdUhostCreateImage (out ))
6162 cmd .AddCommand (NewCmdIsolation (out ))
63+ cmd .AddCommand (NewCmdUhostLeaveIsolationGroup (out ))
6264
6365 return cmd
6466}
@@ -211,12 +213,20 @@ func getAllUHosts(req *uhost.DescribeUHostInstanceRequest, pageOff bool, allRegi
211213func NewCmdUHostList (out io.Writer ) * cobra.Command {
212214 var allRegion , pageOff , idOnly bool
213215 var output string
216+ var uhostIds []string
214217 req := base .BizClient .NewDescribeUHostInstanceRequest ()
215218 cmd := & cobra.Command {
216219 Use : "list" ,
217220 Short : "List all UHost Instances" ,
218221 Long : `List all UHost Instances` ,
219222 Run : func (cmd * cobra.Command , args []string ) {
223+ * req .VPCId = base .PickResourceID (* req .VPCId )
224+ * req .SubnetId = base .PickResourceID (* req .SubnetId )
225+ * req .IsolationGroup = base .PickResourceID (* req .IsolationGroup )
226+ for _ , uhost := range uhostIds {
227+ req .UHostIds = append (req .UHostIds , base .PickResourceID (uhost ))
228+ }
229+
220230 uhosts , err := getAllUHosts (req , pageOff , allRegion )
221231 if err != nil {
222232 base .HandleError (err )
@@ -233,9 +243,12 @@ func NewCmdUHostList(out io.Writer) *cobra.Command {
233243 req .ProjectId = cmd .Flags ().String ("project-id" , base .ConfigIns .ProjectID , "Optional. Assign project-id" )
234244 req .Region = cmd .Flags ().String ("region" , base .ConfigIns .Region , "Optional. Assign region." )
235245 req .Zone = cmd .Flags ().String ("zone" , "" , "Optional. Assign availability zone" )
236- cmd .Flags ().StringSliceVar (& req .UHostIds , "uhost-id" , make ([]string , 0 ), "Optional. Resource ID of uhost instances, multiple values separated by comma(without space)" )
237246 req .Offset = cmd .Flags ().Int ("offset" , 0 , "Optional. Offset default 0" )
238247 req .Limit = cmd .Flags ().Int ("limit" , 50 , "Optional. Limit default 50, max value 100" )
248+ req .VPCId = cmd .Flags ().String ("vpc-id" , "" , "Optional. Resource ID of VPC. List uhost instances of the specified VPC" )
249+ req .SubnetId = cmd .Flags ().String ("subnet-id" , "" , "Optional. Resource ID of Subnet. List uhost instances of the specified Subnet" )
250+ req .IsolationGroup = cmd .Flags ().String ("isolation-group" , "" , "Optional. Resource ID of isolation group. List uhost instances of the specified isolation group" )
251+ cmd .Flags ().StringSliceVar (& uhostIds , "uhost-id" , make ([]string , 0 ), "Optional. Resource ID of uhost instances, multiple values separated by comma(without space)" )
239252 cmd .Flags ().BoolVar (& allRegion , "all-region" , false , "Optional. Accpet values: true or false. List uhost instances of all regions when assigned true" )
240253 cmd .Flags ().BoolVar (& pageOff , "page-off" , false , "Optional. Paging or not. If all-region is specified this flag will be true. Accept values: true or false. If assigned, the limit flag will be disabled and list all uhost instances" )
241254 cmd .Flags ().BoolVar (& idOnly , "uhost-id-only" , false , "Optional. Just display resource id of uhost" )
@@ -251,6 +264,20 @@ func NewCmdUHostList(out io.Writer) *cobra.Command {
251264 return getZoneList (req .GetRegion ())
252265 })
253266
267+ flags := cmd .Flags ()
268+ flags .SetFlagValuesFunc ("vpc-id" , func () []string {
269+ return getAllVPCIdNames (* req .ProjectId , * req .Region )
270+ })
271+ flags .SetFlagValuesFunc ("subnet-id" , func () []string {
272+ return getAllSubnetIDNames (* req .VPCId , * req .ProjectId , * req .Region )
273+ })
274+ flags .SetFlagValuesFunc ("isolation-group" , func () []string {
275+ return getIsolationGroupList (* req .ProjectId , * req .Region )
276+ })
277+ flags .SetFlagValuesFunc ("uhost-id" , func () []string {
278+ return getUhostList (nil , * req .ProjectId , * req .Region , * req .Zone )
279+ })
280+
254281 return cmd
255282}
256283
@@ -260,6 +287,7 @@ func NewCmdUHostCreate() *cobra.Command {
260287 var hotPlug string
261288 var async bool
262289 var count int
290+ var hotPlugImageFlag bool
263291
264292 req := base .BizClient .NewCreateUHostInstanceRequest ()
265293 eipReq := base .BizClient .NewAllocateEIPRequest ()
@@ -277,6 +305,24 @@ func NewCmdUHostCreate() *cobra.Command {
277305 req .IsolationGroup = sdk .String (base .PickResourceID (* req .IsolationGroup ))
278306 if hotPlug == "true" {
279307 req .HotplugFeature = sdk .Bool (true )
308+ any , err := describeImageByID (* req .ImageId , * req .ProjectId , * req .Region , * req .Zone )
309+ if err != nil {
310+ base .LogError (fmt .Sprintf ("check image support hot-plug failed: %v" , err ))
311+ } else {
312+ image , ok := any .(* uhost.UHostImageSet )
313+ if ! ok {
314+ base .LogError (fmt .Sprintf ("check image support hot-plug failed, image %s may not exist" , * req .ImageId ))
315+ }
316+ for _ , feature := range image .Features {
317+ if feature == "HotPlug" {
318+ hotPlugImageFlag = true
319+ }
320+ }
321+ }
322+ if ! hotPlugImageFlag {
323+ base .LogWarn (fmt .Sprintf ("warning. image %s does not support hot-plug" , * req .ImageId ))
324+ req .HotplugFeature = sdk .Bool (false )
325+ }
280326 }
281327
282328 wg := & sync.WaitGroup {}
@@ -359,7 +405,7 @@ func NewCmdUHostCreate() *cobra.Command {
359405 req .UHostType = flags .String ("type" , "" , "Optional. Accept values: N1, N2, N3, G1, G2, G3, I1, I2, C1. Forward to https://docs.ucloud.cn/api/uhost-api/uhost_type for details" )
360406 req .GPU = flags .Int ("gpu" , 0 , "Optional. The count of GPU cores." )
361407 req .NetCapability = flags .String ("net-capability" , "Normal" , "Optional. Default is 'Normal', also support 'Super' which will enhance multiple times network capability as before" )
362- flags .StringVar (& hotPlug , "hot-plug" , "false " , "Optional. Enable hot plug feature or not. Accept values: true or false" )
408+ flags .StringVar (& hotPlug , "hot-plug" , "true " , "Optional. Enable hot plug feature or not. Accept values: true or false" )
363409 req .Disks [0 ].Type = flags .String ("os-disk-type" , "CLOUD_SSD" , "Optional. Enumeration value. 'LOCAL_NORMAL', Ordinary local disk; 'CLOUD_NORMAL', Ordinary cloud disk; 'LOCAL_SSD',local ssd disk; 'CLOUD_SSD',cloud ssd disk; 'EXCLUSIVE_LOCAL_DISK',big data. The disk only supports a limited combination." )
364410 req .Disks [0 ].Size = flags .Int ("os-disk-size-gb" , 20 , "Optional. Default 20G. Windows should be bigger than 40G Unit GB" )
365411 req .Disks [0 ].BackupType = flags .String ("os-disk-backup-type" , "NONE" , "Optional. Enumeration value, 'NONE' or 'DATAARK'. DataArk supports real-time backup, which can restore the disk back to any moment within the last 12 hours. (Normal Local Disk and Normal Cloud Disk Only)" )
@@ -938,10 +984,14 @@ func getUhostList(states []string, project, region, zone string) []string {
938984 }
939985 list := []string {}
940986 for _ , host := range resp .UHostSet {
941- for _ , s := range states {
942- if host .State == s {
943- list = append (list , host .UHostId + "/" + strings .Replace (host .Name , " " , "-" , - 1 ))
987+ if states != nil {
988+ for _ , s := range states {
989+ if host .State == s {
990+ list = append (list , host .UHostId + "/" + strings .Replace (host .Name , " " , "-" , - 1 ))
991+ }
944992 }
993+ } else {
994+ list = append (list , host .UHostId + "/" + strings .Replace (host .Name , " " , "-" , - 1 ))
945995 }
946996 }
947997 return list
@@ -1271,6 +1321,54 @@ func NewCmdUhostReinstallOS(out io.Writer) *cobra.Command {
12711321 return cmd
12721322}
12731323
1324+ //NewCmdUhostLeaveIsolationGroup ucloud uhost leave-isolation-group
1325+ func NewCmdUhostLeaveIsolationGroup (out io.Writer ) * cobra.Command {
1326+ var uhostIds []string
1327+ req := base .BizClient .NewLeaveIsolationGroupRequest ()
1328+ cmd := & cobra.Command {
1329+ Use : "leave-isolation-group" ,
1330+ Short : "Detach uhost from its isolation group" ,
1331+ Run : func (c * cobra.Command , args []string ) {
1332+ for _ , idname := range uhostIds {
1333+ id := base .PickResourceID (idname )
1334+ any , err := describeUHostByID (id , * req .ProjectId , * req .Region , * req .Zone )
1335+ if err != nil {
1336+ base .LogError (fmt .Sprintf ("fetch uhost %s failed: %v" , idname , err ))
1337+ continue
1338+ }
1339+ ins , ok := any .(* uhost.UHostInstanceSet )
1340+ if ! ok {
1341+ base .LogError (fmt .Sprintf ("uhost %s may not exist" , idname ))
1342+ continue
1343+ }
1344+ if ins .IsolationGroup == "" {
1345+ base .LogPrint (fmt .Sprintf ("uhost %s doesn't attached any isolation group" , idname ))
1346+ continue
1347+ }
1348+ req .GroupId = sdk .String (ins .IsolationGroup )
1349+ req .UHostId = & id
1350+ _ , err = base .BizClient .LeaveIsolationGroup (req )
1351+ if err != nil {
1352+ base .HandleError (err )
1353+ continue
1354+ }
1355+ base .LogPrint (fmt .Sprintf ("uhost %s detached from isolation group %s" , idname , ins .IsolationGroup ))
1356+ }
1357+ },
1358+ }
1359+ flags := cmd .Flags ()
1360+ flags .SortFlags = false
1361+ flags .StringSliceVar (& uhostIds , "uhost-id" , nil , "Required. Resource ID of uhosts to be detech from its isolation group" )
1362+ bindRegion (req , flags )
1363+ bindProjectID (req , flags )
1364+ bindZone (req , flags )
1365+ cmd .MarkFlagRequired ("uhost-id" )
1366+ flags .SetFlagValuesFunc ("uhost-id" , func () []string {
1367+ return getUhostList (nil , * req .ProjectId , * req .Region , * req .Zone )
1368+ })
1369+ return cmd
1370+ }
1371+
12741372//NewCmdIsolation ucloud uhost isolation-gorup
12751373func NewCmdIsolation (out io.Writer ) * cobra.Command {
12761374 cmd := & cobra.Command {
@@ -1279,6 +1377,76 @@ func NewCmdIsolation(out io.Writer) *cobra.Command {
12791377 Long : "List and manipulate isolation group of uhost" ,
12801378 }
12811379 cmd .AddCommand (NewCmdIsolationList (out ))
1380+ cmd .AddCommand (NewCmdIsolationCreate (out ))
1381+ cmd .AddCommand (NewCmdIsolationDelete (out ))
1382+ return cmd
1383+ }
1384+
1385+ //NewCmdIsolationCreate ucloud uhost isolation-group create
1386+ func NewCmdIsolationCreate (out io.Writer ) * cobra.Command {
1387+ req := base .BizClient .NewCreateIsolationGroupRequest ()
1388+ cmd := & cobra.Command {
1389+ Use : "create" ,
1390+ Short : "Create isolation group instance" ,
1391+ Long : "Create isolation group instance" ,
1392+ Run : func (c * cobra.Command , args []string ) {
1393+ re := regexp .MustCompile (cli .REGEXP_NAME )
1394+ if ! re .Match ([]byte (* req .GroupName )) {
1395+ base .LogError (fmt .Sprintf ("group-name %s is invalid! Length 1~63, only English,Chinese,number and '-_.' are allowed" , * req .GroupName ))
1396+ return
1397+ }
1398+ resp , err := base .BizClient .CreateIsolationGroup (req )
1399+ if err != nil {
1400+ base .HandleError (err )
1401+ return
1402+ }
1403+ base .LogPrint (fmt .Sprintf ("isolation group %s created" , resp .GroupId ))
1404+ },
1405+ }
1406+ flags := cmd .Flags ()
1407+ flags .SortFlags = false
1408+
1409+ req .GroupName = flags .String ("group-name" , "" , "Required. Name of isolation group. Length 1~63, only English,Chinese,number and '-_.' are allowed" )
1410+ bindRegion (req , flags )
1411+ bindProjectID (req , flags )
1412+ req .Remark = flags .String ("remark" , "" , "Optional. Remark ok isolation group" )
1413+
1414+ cmd .MarkFlagRequired ("group-name" )
1415+ return cmd
1416+ }
1417+
1418+ //NewCmdIsolationDelete ucloud uhost
1419+ func NewCmdIsolationDelete (out io.Writer ) * cobra.Command {
1420+ var ids []string
1421+ req := base .BizClient .NewDeleteIsolationGroupRequest ()
1422+ cmd := & cobra.Command {
1423+ Use : "delete" ,
1424+ Short : "Delete isolation group instances" ,
1425+ Run : func (c * cobra.Command , args []string ) {
1426+ for _ , idname := range ids {
1427+ id := base .PickResourceID (idname )
1428+ req .GroupId = & id
1429+ _ , err := base .BizClient .DeleteIsolationGroup (req )
1430+ if err != nil {
1431+ base .HandleError (err )
1432+ continue
1433+ }
1434+ base .LogPrint (fmt .Sprintf ("isolation group %s deleted" , idname ))
1435+ }
1436+ },
1437+ }
1438+
1439+ flags := cmd .Flags ()
1440+ flags .SortFlags = false
1441+ flags .StringSliceVar (& ids , "group-id" , nil , "Required. Resource ID of isolation groups to be deleted" )
1442+ bindRegion (req , flags )
1443+ bindProjectID (req , flags )
1444+
1445+ cmd .MarkFlagRequired ("group-id" )
1446+ flags .SetFlagValuesFunc ("group-id" , func () []string {
1447+ return getIsolationGroupList (* req .ProjectId , * req .Region )
1448+ })
1449+
12821450 return cmd
12831451}
12841452
@@ -1321,12 +1489,16 @@ func NewCmdIsolationList(out io.Writer) *cobra.Command {
13211489 flags := cmd .Flags ()
13221490 flags .SortFlags = false
13231491
1324- flags .String ("group-id" , "" , "Optional. Resource ID of isolation group to describe" )
1492+ req . GroupId = flags .String ("group-id" , "" , "Optional. Resource ID of isolation group to describe" )
13251493 bindRegion (req , flags )
13261494 bindProjectID (req , flags )
13271495 bindLimit (req , flags )
13281496 bindOffset (req , flags )
13291497
1498+ flags .SetFlagValuesFunc ("group-id" , func () []string {
1499+ return getIsolationGroupList (* req .ProjectId , * req .Region )
1500+ })
1501+
13301502 return cmd
13311503}
13321504
0 commit comments