Skip to content

Commit fb0918e

Browse files
allmightyspiffGitHub Enterprise
authored andcommitted
Merge pull request #900 from SoftLayer/issues898
Removed reliance on vlan.PrimaryRouter to find a vlans pod/datacenter
2 parents 8d31963 + ddc8bb0 commit fb0918e

21 files changed

+195
-2533
lines changed

plugin/commands/vlan/detail.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ func NewDetailCommand(sl *metadata.SoftlayerCommand) *DetailCommand {
2929
cobraCmd := &cobra.Command{
3030
Use: "detail " + T("IDENTIFIER"),
3131
Short: T("Get details about a VLAN"),
32-
Long: T(`${COMMAND_NAME} sl vlan detail IDENTIFIER [OPTIONS]
33-
34-
EXAMPLE:
32+
Long: T(`EXAMPLE:
3533
${COMMAND_NAME} sl vlan detail 12345678 --no-vs --no-hardware
3634
This command shows details of vlan with ID 12345678, and not list virtual server or hardware server.`),
3735
Args: metadata.OneArgs,
@@ -66,8 +64,10 @@ func (cmd *DetailCommand) Run(args []string) error {
6664
table := cmd.UI.Table([]string{T("Name"), T("Value")})
6765
table.Add(T("id"), utils.FormatIntPointer(vlan.Id))
6866
table.Add(T("number"), utils.FormatIntPointer(vlan.VlanNumber))
67+
if vlan.Datacenter != nil {
68+
table.Add(T("datacenter"), utils.FormatStringPointer(vlan.Datacenter.Name))
69+
}
6970
if vlan.PrimaryRouter != nil {
70-
table.Add(T("datacenter"), utils.FormatStringPointer(vlan.PrimaryRouter.DatacenterName))
7171
table.Add(T("primary_router"), utils.FormatStringPointer(vlan.PrimaryRouter.FullyQualifiedDomainName))
7272
}
7373
firewall := T("Yes")

plugin/commands/vlan/list.go

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ func NewListCommand(sl *metadata.SoftlayerCommand) *ListCommand {
3434
cobraCmd := &cobra.Command{
3535
Use: "list",
3636
Short: T("List all the VLANs on your account"),
37-
Long: T(`${COMMAND_NAME} sl vlan list [OPTIONS]
38-
39-
EXAMPLE:
37+
Long: T(`EXAMPLE:
4038
${COMMAND_NAME} sl vlan list -d dal09 --sortby number
4139
This commands lists all vlans on current account filtering by datacenter equals to dal09, and sort them by vlan number.
4240
@@ -71,21 +69,41 @@ func (cmd *ListCommand) Run(args []string) error {
7169

7270
sortby := cmd.Sortby
7371
if sortby == "id" || sortby == "ID" {
74-
sort.Sort(utils.VlanById(vlans))
72+
sort.Slice(vlans, func(i, j int) bool {
73+
return *vlans[i].Id < *vlans[j].Id
74+
})
7575
} else if sortby == "number" {
76-
sort.Sort(utils.VlanByNumber(vlans))
76+
sort.Slice(vlans, func(i, j int) bool {
77+
return *vlans[i].VlanNumber < *vlans[j].VlanNumber
78+
})
7779
} else if sortby == "name" {
78-
sort.Sort(utils.VlanByName(vlans))
80+
sort.Slice(vlans, func(i, j int) bool {
81+
return *vlans[i].VlanNumber < *vlans[j].VlanNumber
82+
})
7983
} else if sortby == "firewall" {
80-
sort.Sort(utils.VlanByFirewall(vlans))
84+
sort.Slice(vlans, func(i, j int) bool {
85+
return len(vlans[i].FirewallInterfaces) < len(vlans[j].FirewallInterfaces)
86+
})
8187
} else if sortby == "datacenter" {
82-
sort.Sort(utils.VlanByDatacenter(vlans))
88+
sort.Slice(vlans, func(i, j int) bool {
89+
if vlans[i].Datacenter != nil && vlans[i].Datacenter.Name != nil &&
90+
vlans[j].Datacenter != nil && vlans[j].Datacenter.Name != nil {
91+
return *vlans[i].Datacenter.Name < *vlans[j].Datacenter.Name
92+
}
93+
return false
94+
})
8395
} else if sortby == "hardware" {
84-
sort.Sort(utils.VlanByHardwareCount(vlans))
96+
sort.Slice(vlans, func(i, j int) bool {
97+
return *vlans[i].HardwareCount < *vlans[j].HardwareCount
98+
})
8599
} else if sortby == "virtual_servers" {
86-
sort.Sort(utils.VlanByVirtualServerCount(vlans))
100+
sort.Slice(vlans, func(i, j int) bool {
101+
return *vlans[i].VirtualGuestCount < *vlans[j].VirtualGuestCount
102+
})
87103
} else if sortby == "public_ips" {
88-
sort.Sort(utils.VlanByPublicIPCount(vlans))
104+
sort.Slice(vlans, func(i, j int) bool {
105+
return *vlans[i].TotalPrimaryIpAddressCount < *vlans[j].TotalPrimaryIpAddressCount
106+
})
89107
} else if sortby == "" {
90108
//do nothing
91109
} else {
@@ -107,8 +125,8 @@ func (cmd *ListCommand) Run(args []string) error {
107125
premium = T("No")
108126
}
109127
datacenterName := ""
110-
if vlan.PrimaryRouter != nil && vlan.PrimaryRouter.Datacenter != nil && vlan.PrimaryRouter.Datacenter.Name != nil {
111-
datacenterName = utils.FormatStringPointer(vlan.PrimaryRouter.Datacenter.Name)
128+
if vlan.Datacenter != nil && vlan.Datacenter.Name != nil {
129+
datacenterName = utils.FormatStringPointer(vlan.Datacenter.Name)
112130
}
113131
table.Add(
114132
utils.FormatIntPointer(vlan.Id),
@@ -142,7 +160,7 @@ func getFirewallGateway(vlan datatypes.Network_Vlan) string {
142160

143161
func getPodWithClosedAnnouncement(vlan datatypes.Network_Vlan, pods []datatypes.Network_Pod) string {
144162
for _, pod := range pods {
145-
if *pod.BackendRouterId == *vlan.PrimaryRouter.Id || *pod.FrontendRouterId == *vlan.PrimaryRouter.Id {
163+
if *pod.Name == *vlan.PodName {
146164
namePod := cases.Title(language.Und).String(strings.Split(utils.FormatStringPointer(pod.Name), ".")[1])
147165
if utils.WordInList(pod.Capabilities, "CLOSURE_ANNOUNCED") {
148166
return namePod + "*"

plugin/commands/vlan/list_test.go

Lines changed: 45 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
. "github.com/onsi/gomega"
1111
"github.com/softlayer/softlayer-go/datatypes"
1212
"github.com/softlayer/softlayer-go/session"
13-
"github.com/softlayer/softlayer-go/sl"
13+
1414
"github.ibm.com/SoftLayer/softlayer-cli/plugin/commands/vlan"
1515
"github.ibm.com/SoftLayer/softlayer-cli/plugin/metadata"
1616
"github.ibm.com/SoftLayer/softlayer-cli/plugin/managers"
@@ -24,30 +24,35 @@ var _ = Describe("VLAN List", func() {
2424
fakeSession *session.Session
2525
slCommand *metadata.SoftlayerCommand
2626
fakeNetworkManager *testhelpers.FakeNetworkManager
27-
27+
fakeHandler *testhelpers.FakeTransportHandler
2828
)
2929
BeforeEach(func() {
3030
fakeUI = terminal.NewFakeUI()
31-
fakeSession = testhelpers.NewFakeSoftlayerSession([]string{""})
31+
fakeSession = testhelpers.NewFakeSoftlayerSession(nil)
32+
fakeHandler = testhelpers.GetSessionHandler(fakeSession)
3233
slCommand = metadata.NewSoftlayerCommand(fakeUI, fakeSession)
3334
cliCommand = vlan.NewListCommand(slCommand)
3435
cliCommand.Command.PersistentFlags().Var(cliCommand.OutputFlag, "output", "--output=JSON for json output.")
3536
fakeNetworkManager = new(testhelpers.FakeNetworkManager)
3637
cliCommand.NetworkManager = fakeNetworkManager
3738
})
38-
39+
AfterEach(func() {
40+
// Clear API call logs and any errors that might have been set after every test
41+
fakeHandler.ClearApiCallLogs()
42+
fakeHandler.ClearErrors()
43+
})
3944
Describe("VLAN list", func() {
4045
Context("VLAN list but server API call fails", func() {
4146
BeforeEach(func() {
4247
fakeNetworkManager.ListVlansReturns([]datatypes.Network_Vlan{}, errors.New("Internal Server Error"))
4348
})
44-
It("return error", func() {
49+
It("Account::getNetworkVlans() failed", func() {
4550
err := testhelpers.RunCobraCommand(cliCommand.Command)
4651
Expect(err).To(HaveOccurred())
4752
Expect(err.Error()).To(ContainSubstring("Failed to list VLANs on your account."))
4853
Expect(err.Error()).To(ContainSubstring("Internal Server Error"))
4954
})
50-
It("return error", func() {
55+
It("Network_Pod::getPods failed", func() {
5156
fakeNetworkManager.ListVlansReturns([]datatypes.Network_Vlan{}, nil)
5257
fakeNetworkManager.GetPodsReturns([]datatypes.Network_Pod{}, errors.New("Internal Server Error"))
5358
err := testhelpers.RunCobraCommand(cliCommand.Command)
@@ -61,14 +66,14 @@ var _ = Describe("VLAN List", func() {
6166
BeforeEach(func() {
6267
fakeNetworkManager.ListVlansReturns([]datatypes.Network_Vlan{}, nil)
6368
})
64-
It("return error", func() {
69+
It("Incorrect Usage: --sortby", func() {
6570
err := testhelpers.RunCobraCommand(cliCommand.Command, "--sortby", "abcd")
6671
Expect(err).To(HaveOccurred())
6772
Expect(err.Error()).To(ContainSubstring("Incorrect Usage: --sortby abcd is not supported."))
6873
})
6974
})
7075

71-
Context("VLAN list", func() {
76+
Context("VLAN list Empty", func() {
7277
BeforeEach(func() {
7378
fakeNetworkManager.ListVlansReturns([]datatypes.Network_Vlan{}, nil)
7479
})
@@ -79,159 +84,78 @@ var _ = Describe("VLAN List", func() {
7984
})
8085
})
8186

82-
Context("VLAN list", func() {
87+
Context("Happy Path Tests", func() {
88+
8389
BeforeEach(func() {
84-
fakeNetworkManager.ListVlansReturns([]datatypes.Network_Vlan{
85-
datatypes.Network_Vlan{
86-
Id: sl.Int(123456),
87-
VlanNumber: sl.Int(100),
88-
FullyQualifiedName: sl.String("dal05.fcr01.784"),
89-
Name: sl.String("Bill"),
90-
FirewallInterfaces: []datatypes.Network_Firewall_Module_Context_Interface{
91-
datatypes.Network_Firewall_Module_Context_Interface{
92-
Id: sl.Int(1),
93-
},
94-
datatypes.Network_Firewall_Module_Context_Interface{
95-
Id: sl.Int(2),
96-
},
97-
},
98-
PrimaryRouter: &datatypes.Hardware_Router{
99-
Hardware_Switch: datatypes.Hardware_Switch{
100-
Hardware: datatypes.Hardware{
101-
Id: sl.Int(987654),
102-
Datacenter: &datatypes.Location{
103-
Name: sl.String("dal05"),
104-
},
105-
},
106-
},
107-
},
108-
BillingItem: &datatypes.Billing_Item{
109-
Id: sl.Int(456321),
110-
},
111-
AttachedNetworkGateway: &datatypes.Network_Gateway{
112-
Name: sl.String("support"),
113-
},
114-
NetworkSpace: sl.String("Public"),
115-
HardwareCount: sl.Uint(uint(30)),
116-
VirtualGuestCount: sl.Uint(uint(40)),
117-
TotalPrimaryIpAddressCount: sl.Uint(uint(50)),
118-
TagReferences: []datatypes.Tag_Reference{
119-
datatypes.Tag_Reference{
120-
Tag: &datatypes.Tag{
121-
Name: sl.String("Tag"),
122-
},
123-
},
124-
},
125-
},
126-
datatypes.Network_Vlan{
127-
Id: sl.Int(123458),
128-
VlanNumber: sl.Int(73),
129-
FullyQualifiedName: sl.String("dal06.fcr01.797"),
130-
Name: sl.String("Anne"),
131-
FirewallInterfaces: []datatypes.Network_Firewall_Module_Context_Interface{},
132-
PrimaryRouter: &datatypes.Hardware_Router{
133-
Hardware_Switch: datatypes.Hardware_Switch{
134-
Hardware: datatypes.Hardware{
135-
Id: sl.Int(87654),
136-
Datacenter: &datatypes.Location{
137-
Name: sl.String("dal06"),
138-
},
139-
},
140-
},
141-
},
142-
NetworkVlanFirewall: &datatypes.Network_Vlan_Firewall{
143-
FullyQualifiedDomainName: sl.String("firewall"),
144-
},
145-
NetworkSpace: sl.String("Private"),
146-
HardwareCount: sl.Uint(uint(5)),
147-
VirtualGuestCount: sl.Uint(uint(6)),
148-
TotalPrimaryIpAddressCount: sl.Uint(uint(7)),
149-
TagReferences: []datatypes.Tag_Reference{
150-
datatypes.Tag_Reference{
151-
Tag: &datatypes.Tag{
152-
Name: sl.String("Tag"),
153-
},
154-
},
155-
},
156-
},
157-
}, nil)
158-
fakeNetworkManager.GetPodsReturns([]datatypes.Network_Pod{
159-
datatypes.Network_Pod{
160-
BackendRouterId: sl.Int(987654),
161-
FrontendRouterId: sl.Int(123456),
162-
Capabilities: []string{"CLOSURE_ANNOUNCED"},
163-
Name: sl.String("dal05.pod01"),
164-
},
165-
datatypes.Network_Pod{
166-
BackendRouterId: sl.Int(213456),
167-
FrontendRouterId: sl.Int(87654),
168-
Capabilities: []string{},
169-
Name: sl.String("dal06.pod02"),
170-
},
171-
}, nil)
90+
// Set to a real network manager to get results from test fixtures
91+
cliCommand.NetworkManager = managers.NewNetworkManager(fakeSession)
17292
})
173-
It("return no error", func() {
93+
It("--sortby id", func() {
17494
err := testhelpers.RunCobraCommand(cliCommand.Command, "--sortby", "id")
17595
Expect(err).NotTo(HaveOccurred())
17696
results := strings.Split(fakeUI.Outputs(), "\n")
177-
Expect(results[1]).To(ContainSubstring("123456"))
178-
Expect(results[2]).To(ContainSubstring("123458"))
97+
Expect(len(results)).To(Equal(5))
98+
Expect(results[1]).To(ContainSubstring("12345"))
99+
Expect(results[2]).To(ContainSubstring("554422"))
100+
Expect(results[3]).To(ContainSubstring("663322"))
179101
})
180102

181-
It("return no error", func() {
103+
It("--sortby number", func() {
182104
err := testhelpers.RunCobraCommand(cliCommand.Command, "--sortby", "number")
183105
Expect(err).NotTo(HaveOccurred())
184106
results := strings.Split(fakeUI.Outputs(), "\n")
185-
Expect(results[1]).To(ContainSubstring("73"))
186-
Expect(results[2]).To(ContainSubstring("100"))
107+
Expect(len(results)).To(Equal(5))
108+
Expect(results[1]).To(ContainSubstring("554422 1111 dal14.bcr03.1111"))
109+
Expect(results[2]).To(ContainSubstring("663322 2222 dal15.bcr03.2222"))
187110
})
188111

189-
It("return no error", func() {
112+
It("--sortby name", func() {
190113
err := testhelpers.RunCobraCommand(cliCommand.Command, "--sortby", "name")
191114
Expect(err).NotTo(HaveOccurred())
192115
results := strings.Split(fakeUI.Outputs(), "\n")
193-
Expect(results[1]).To(ContainSubstring("Anne"))
194-
Expect(results[2]).To(ContainSubstring("Bill"))
116+
Expect(len(results)).To(Equal(5))
117+
Expect(results[1]).To(ContainSubstring("554422 1111 dal14.bcr03.1111"))
118+
Expect(results[2]).To(ContainSubstring("663322 2222 dal15.bcr03.2222"))
195119
})
196120

197-
It("return no error", func() {
121+
It("--sortby firewall", func() {
198122
err := testhelpers.RunCobraCommand(cliCommand.Command, "--sortby", "firewall")
199123
Expect(err).NotTo(HaveOccurred())
200124
results := strings.Split(fakeUI.Outputs(), "\n")
201-
Expect(results[1]).To(ContainSubstring("No"))
202-
Expect(results[2]).To(ContainSubstring("Yes"))
125+
Expect(results[1]).To(ContainSubstring("12345 3333 dal13.bcr03.3333"))
126+
Expect(results[2]).To(ContainSubstring("554422 1111 dal14.bcr03.1111"))
203127
})
204128

205-
It("return no error", func() {
129+
It("--sortby datacenter", func() {
206130
err := testhelpers.RunCobraCommand(cliCommand.Command, "--sortby", "datacenter")
207131
Expect(err).NotTo(HaveOccurred())
208132
results := strings.Split(fakeUI.Outputs(), "\n")
209-
Expect(results[1]).To(ContainSubstring("dal05"))
210-
Expect(results[2]).To(ContainSubstring("dal06"))
133+
Expect(results[1]).To(ContainSubstring("12345 3333 dal13.bcr03.3333"))
134+
Expect(results[2]).To(ContainSubstring("554422 1111 dal14.bcr03.1111"))
211135
})
212136

213-
It("return no error", func() {
137+
It("--sortby hardware", func() {
214138
err := testhelpers.RunCobraCommand(cliCommand.Command, "--sortby", "hardware")
215139
Expect(err).NotTo(HaveOccurred())
216140
results := strings.Split(fakeUI.Outputs(), "\n")
217-
Expect(results[1]).To(ContainSubstring("5"))
218-
Expect(results[2]).To(ContainSubstring("30"))
141+
Expect(results[1]).To(ContainSubstring("12345 3333 dal13.bcr03.3333"))
142+
Expect(results[2]).To(ContainSubstring("663322 2222 dal15.bcr03.2222"))
219143
})
220144

221-
It("return no error", func() {
145+
It("--sortby virtual_servers", func() {
222146
err := testhelpers.RunCobraCommand(cliCommand.Command, "--sortby", "virtual_servers")
223147
Expect(err).NotTo(HaveOccurred())
224148
results := strings.Split(fakeUI.Outputs(), "\n")
225-
Expect(results[1]).To(ContainSubstring("6"))
226-
Expect(results[2]).To(ContainSubstring("40"))
149+
Expect(results[1]).To(ContainSubstring("12345 3333 dal13.bcr03.3333"))
150+
Expect(results[2]).To(ContainSubstring("554422 1111 dal14.bcr03.1111"))
227151
})
228152

229-
It("return no error", func() {
153+
It("--sortby public_ips", func() {
230154
err := testhelpers.RunCobraCommand(cliCommand.Command, "--sortby", "public_ips")
231155
Expect(err).NotTo(HaveOccurred())
232156
results := strings.Split(fakeUI.Outputs(), "\n")
233-
Expect(results[1]).To(ContainSubstring("7"))
234-
Expect(results[2]).To(ContainSubstring("50"))
157+
Expect(results[1]).To(ContainSubstring("12345 3333 dal13.bcr03.3333"))
158+
Expect(results[2]).To(ContainSubstring("554422 1111 dal14.bcr03.1111"))
235159
})
236160

237161
It("return no error", func() {

plugin/i18n/v2Resources/active.de_DE.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,14 @@
302302
"${COMMAND_NAME} sl vlan create [OPTIONS]\n\t\nEXAMPLE:\n ${COMMAND_NAME} sl vlan create -t public -d dal09 -n myvlan\n This command creates a public vlan located in datacenter dal09 named \"myvlan\".\n ${COMMAND_NAME} sl vlan create -r bcr01a.dal09 -n myvlan\n This command creates a vlan on router bcr01a.dal09 named \"myvlan\".": {
303303
"other": "${COMMAND_NAME} sl vlan create [OPTIONEN]\n\t\nBEISPIEL:\n ${COMMAND_NAME} sl vlan create -t public -d dal09 -n myvlan\n Dieser Befehl erstellt ein öffentliches VLAN in Rechenzentrum dal09 namens \"myvlan\".\n ${COMMAND_NAME} sl vlan create -r bcr01a.dal09 -n myvlan\n Dieser Befehl erstellt ein VLAN auf Router bcr01a.dal09 namens \"myvlan\"."
304304
},
305-
"${COMMAND_NAME} sl vlan detail IDENTIFIER [OPTIONS]\n\nEXAMPLE:\n ${COMMAND_NAME} sl vlan detail 12345678\t--no-vs --no-hardware\n This command shows details of vlan with ID 12345678, and not list virtual server or hardware server.": {
306-
"other": "${COMMAND_NAME} sl vlan detail IDENTIFIER [OPTIONEN]\n\nBEISPIEL:\n ${COMMAND_NAME} sl vlan detail 12345678\t--no-vs --no-hardware\n Dieser Befehl zeigt Details zum VLAN mit der ID 12345678 an, ohne virtuelle Server oder Hardware-Server aufzulisten."
305+
"EXAMPLE:\n ${COMMAND_NAME} sl vlan detail 12345678\t--no-vs --no-hardware\n This command shows details of vlan with ID 12345678, and not list virtual server or hardware server.": {
306+
"other": "BEISPIEL:\n ${COMMAND_NAME} sl vlan detail 12345678\t--no-vs --no-hardware\n Dieser Befehl zeigt Details zum VLAN mit der ID 12345678 an, ohne virtuelle Server oder Hardware-Server aufzulisten."
307307
},
308308
"${COMMAND_NAME} sl vlan edit IDENTIFIER [OPTIONS]\n\t\nEXAMPLE:\n ${COMMAND_NAME} sl vlan edit 12345678 -n myvlan-rename\n This command updates vlan with ID 12345678 and gives it a new name \"myvlan-rename\".": {
309309
"other": "${COMMAND_NAME} sl vlan edit IDENTIFIER [OPTIONEN]\n\t\nBEISPIEL:\n ${COMMAND_NAME} sl vlan edit 12345678 -n myvlan-rename\n Dieser Befehl aktualisiert das VLAN mit der ID 12345678 und benennt es in \"myvlan-rename\" um."
310310
},
311-
"${COMMAND_NAME} sl vlan list [OPTIONS]\n\t\nEXAMPLE:\n ${COMMAND_NAME} sl vlan list -d dal09 --sortby number\n This commands lists all vlans on current account filtering by datacenter equals to dal09, and sort them by vlan number.\n \nNote: In field Pod, if add (*) indicated that closed soon": {
312-
"other": "${COMMAND_NAME} sl vlan list [OPTIONEN]\n \nBEISPIEL:\n ${COMMAND_NAME} sl vlan list -d dal09 --sortby number\n Dieser Befehl listet alle Vlans des aktuellen Kontos auf, filtert nach Rechenzentrum gleich dal09 und sortiert sie nach VLAN-Nummer.\n \nHinweis: Wenn \"add (*)\" im Feld \"Pod\" angegeben wurde, gibt dies an, dass bald eine Schliessung ansteht"
311+
"EXAMPLE:\n ${COMMAND_NAME} sl vlan list -d dal09 --sortby number\n This commands lists all vlans on current account filtering by datacenter equals to dal09, and sort them by vlan number.\n \nNote: In field Pod, if add (*) indicated that closed soon": {
312+
"other": "BEISPIEL:\n ${COMMAND_NAME} sl vlan list -d dal09 --sortby number\n Dieser Befehl listet alle Vlans des aktuellen Kontos auf, filtert nach Rechenzentrum gleich dal09 und sortiert sie nach VLAN-Nummer.\n \nHinweis: Wenn \"add (*)\" im Feld \"Pod\" angegeben wurde, gibt dies an, dass bald eine Schliessung ansteht"
313313
},
314314
"${COMMAND_NAME} sl vs authorize-storage [OPTIONS] IDENTIFIER\n\nEXAMPLE:\n ${COMMAND_NAME} sl vs authorize-storage --username-storage SL01SL30-37 1234567\n Authorize File, Block and Portable Storage to a Virtual Server.": {
315315
"other": "${COMMAND_NAME} sl vs authorize-storage [OPTIONEN] IDENTIFIER\n\nBEISPIEL:\n ${COMMAND_NAME} sl vs authorize-storage --username-storage SL01SL30-37 1234567\n Datei, Block und portierbaren Speicher für einen virtuellen Server autorisieren."

0 commit comments

Comments
 (0)