11package block
22
33import (
4+ "strconv"
45 "github.com/spf13/cobra"
56
67 slErr "github.ibm.com/SoftLayer/softlayer-cli/plugin/errors"
@@ -19,6 +20,7 @@ type AccessAuthorizeCommand struct {
1920 Virtual_id []int
2021 Ip_address_id []int
2122 Ip_address []string
23+ Subnet_id int
2224}
2325
2426func NewAccessAuthorizeCommand (sl * metadata.SoftlayerStorageCommand ) * AccessAuthorizeCommand {
@@ -32,24 +34,42 @@ func NewAccessAuthorizeCommand(sl *metadata.SoftlayerStorageCommand) *AccessAuth
3234 Short : T ("Authorize hosts to access a given volume." ),
3335 Long : T (`EXAMPLE:
3436 ${COMMAND_NAME} sl {{.storageType}} access-authorize 12345678 --virtual-id 87654321
35- This command authorizes virtual server with ID 87654321 to access volume with ID 12345678.` , sl .StorageI18n ),
37+ This command authorizes virtual server with ID 87654321 to access volume with ID 12345678.` , sl .StorageI18n ) + "\n " +
38+ T (`
39+ ${COMMAND_NAME} sl {{.storageType}} access-authorize 5555 --subnet-id 1111
40+ This command adds subnet with id 1111 to the Allowed Host with id 5555. Use 'access-list' to find this id.
41+ SoftLayer_Account::iscsiIsolationDisabled must be False for this command to do anything.` , sl .StorageI18n ),
3642 Args : metadata .OneArgs ,
3743 RunE : func (cmd * cobra.Command , args []string ) error {
3844 return thisCmd .Run (args )
3945 },
4046 }
4147
42- cobraCmd .Flags ().IntSliceVarP (& thisCmd .Hardware_id , "hardware-id" , "d" , []int {}, T ("The ID of one hardware server to authorize." ))
43- cobraCmd .Flags ().IntSliceVarP (& thisCmd .Virtual_id , "virtual-id" , "v" , []int {}, T ("The ID of one virtual server to authorize." ))
44- cobraCmd .Flags ().IntSliceVarP (& thisCmd .Ip_address_id , "ip-address-id" , "i" , []int {}, T ("The ID of one IP address to authorize." ))
45- cobraCmd .Flags ().StringSliceVarP (& thisCmd .Ip_address , "ip-address" , "p" , []string {}, T ("An IP address to authorize." ))
48+ cobraCmd .Flags ().IntSliceVarP (& thisCmd .Hardware_id , "hardware-id" , "d" , []int {},
49+ T ("The ID of one hardware server to authorize." ))
50+ cobraCmd .Flags ().IntSliceVarP (& thisCmd .Virtual_id , "virtual-id" , "v" , []int {},
51+ T ("The ID of one virtual server to authorize." ))
52+ cobraCmd .Flags ().IntSliceVarP (& thisCmd .Ip_address_id , "ip-address-id" , "i" , []int {},
53+ T ("The ID of one IP address to authorize." ))
54+ cobraCmd .Flags ().StringSliceVarP (& thisCmd .Ip_address , "ip-address" , "p" , []string {},
55+ T ("An IP address to authorize." ))
56+ cobraCmd .Flags ().IntVarP (& thisCmd .Subnet_id , "subnet-id" , "s" , 0 ,
57+ T ("A Subnet Id. With this option IDENTIFIER should be an 'allowed_host_id' from the access-list command." ))
4658 thisCmd .Command = cobraCmd
4759
4860 return thisCmd
4961}
5062
5163func (cmd * AccessAuthorizeCommand ) Run (args []string ) error {
5264
65+ // Subnets have to get added to an existing authorized host.
66+ if cmd .Subnet_id > 0 {
67+ hostId , err := strconv .Atoi (args [0 ])
68+ if err != nil {
69+ return slErr .NewInvalidSoftlayerIdInputError ("Allowed Host IDENTIFIER" )
70+ }
71+ return cmd .AddSubnetToHost (hostId )
72+ }
5373 volumeID , err := cmd .StorageManager .GetVolumeId (args [0 ], cmd .StorageType )
5474 if err != nil {
5575 return err
@@ -60,7 +80,8 @@ func (cmd *AccessAuthorizeCommand) Run(args []string) error {
6080 for _ , ip := range IPs {
6181 ipRecord , err := cmd .NetworkManager .IPLookup (ip )
6282 if err != nil {
63- return slErr .NewAPIError (T ("IP address {{.IP}} is not found on your account.Please confirm IP and try again.\n " ,
83+ return slErr .NewAPIError (
84+ T ("IP address {{.IP}} is not found on your account.Please confirm IP and try again.\n " ,
6485 map [string ]interface {}{"IP" : ip }), err .Error (), 2 )
6586 }
6687 if ipRecord .Id != nil {
@@ -82,14 +103,61 @@ func (cmd *AccessAuthorizeCommand) Run(args []string) error {
82103 }
83104
84105 cmd .UI .Ok ()
85- for _ , vsID := range cmd .Virtual_id {
86- cmd .UI .Print (T ("The virtual server {{.VsID}} was authorized to access {{.VolumeId}}." , map [string ]interface {}{"VolumeId" : volumeID , "VsID" : vsID }))
106+ subs := map [string ]interface {}{
107+ "VolumeId" : volumeID ,
108+ "SL_ID" : 0 ,
109+ "SL_Object" : "" ,
87110 }
88- for _ , hwID := range cmd .Hardware_id {
89- cmd .UI .Print (T ("The hardware server {{.HwID}} was authorized to access {{.VolumeId}}." , map [string ]interface {}{"VolumeId" : volumeID , "HwID" : hwID }))
111+ for _ , sl_id := range cmd .Virtual_id {
112+ subs ["SL_Object" ] = T ("Virtual Server" )
113+ subs ["SL_ID" ] = sl_id
114+ cmd .UI .Print (T ("The {{.SL_Object}} {{.SL_ID}} was authorized to access {{.VolumeId}}." , subs ))
90115 }
91- for _ , ip := range IPIds {
92- cmd .UI .Print (T ("The IP address {{.IP}} was authorized to access {{.VolumeId}}." , map [string ]interface {}{"VolumeId" : volumeID , "IP" : ip }))
116+ for _ , sl_id := range cmd .Hardware_id {
117+ subs ["SL_Object" ] = T ("Hardware Server" )
118+ subs ["SL_ID" ] = sl_id
119+ cmd .UI .Print (T ("The {{.SL_Object}} {{.SL_ID}} was authorized to access {{.VolumeId}}." , subs ))
120+ }
121+ for _ , sl_id := range IPIds {
122+ subs ["SL_Object" ] = T ("IP Address" )
123+ subs ["SL_ID" ] = sl_id
124+ cmd .UI .Print (T ("The {{.SL_Object}} {{.SL_ID}} was authorized to access {{.VolumeId}}." , subs ))
93125 }
94126 return nil
95127}
128+
129+ func (cmd * AccessAuthorizeCommand ) AddSubnetToHost (host_id int ) error {
130+
131+ outputFormat := cmd .GetOutputFlag ()
132+ subnet_ids := []int {cmd .Subnet_id }
133+ resp , err := cmd .StorageManager .AssignSubnetsToAcl (host_id , subnet_ids )
134+ if err != nil {
135+ subs := map [string ]interface {}{"subnetID" : cmd .Subnet_id , "accessID" : host_id }
136+ return slErr .NewAPIError (
137+ T ("Failed to assign subnet id: {{.subnetID}} to allowed host id: {{.accessID}}" , subs ),
138+ err .Error (), 2 )
139+ }
140+ // If the API returns an empty array, that means it didn't add the subnet we asked for.
141+ // Likely because ISCSI Isolation is disabled on the account.
142+ // ibmcloud sl call-api SoftLayer_Account getObject --mask="mask[id,iscsiIsolationDisabled]"
143+ if len (resp ) == 0 || utils .IntInSlice (cmd .Subnet_id , resp ) == - 1 {
144+ subs := map [string ]interface {}{"subnetID" : cmd .Subnet_id , "accessID" : host_id }
145+ return slErr .NewAPIError (
146+ T ("Failed to assign subnet id: {{.subnetID}} to allowed host id: {{.accessID}}" , subs ) + "\n " +
147+ T ("Make sure ISCSI Isolation is enabled for this account." ),
148+ "" , 2 ,
149+ )
150+ }
151+ if outputFormat == "JSON" {
152+ return utils .PrintPrettyJSON (cmd .UI , resp )
153+ }
154+
155+ cmd .UI .Ok ()
156+ subs := map [string ]interface {}{
157+ "VolumeId" : host_id ,
158+ "SL_ID" : cmd .Subnet_id ,
159+ "SL_Object" : T ("Subnet" ),
160+ }
161+ cmd .UI .Print (T ("The {{.SL_Object}} {{.SL_ID}} was authorized to access {{.VolumeId}}." , subs ))
162+ return nil
163+ }
0 commit comments