@@ -90,6 +90,7 @@ type Options struct {
9090 Force bool
9191 WaitComplete bool
9292 CreateOnly bool
93+ All bool
9394 Timeout time.Duration
9495}
9596
@@ -102,40 +103,79 @@ func (l *Lifecycle) Run(cmd *cobra.Command, args []string) error {
102103 if err != nil {
103104 return err
104105 }
105- name , namespace , err := l .getNameNamespace (defaultNamespace , args )
106- key := types.NamespacedName {Namespace : namespace , Name : name }
107- if err != nil {
108- return err
106+
107+ if len (args ) > 0 && l .opts .All {
108+ return fmt .Errorf ("cannot use --all flag with specific keys" )
109+ }
110+
111+ var keys []types.NamespacedName
112+ if l .opts .All {
113+ keys , err = l .getVirtualMachines (cmd .Context (), defaultNamespace , client )
114+ if err != nil {
115+ return fmt .Errorf ("failed to get virtual machines in namespace %q: %w" , defaultNamespace , err )
116+ }
117+ } else {
118+ keys , err = l .getNamespacedNames (defaultNamespace , args )
119+ if err != nil {
120+ return fmt .Errorf ("failed to parse keys: %w" , err )
121+ }
122+ }
123+
124+ if len (keys ) == 0 {
125+ return fmt .Errorf ("no one virtual machine found for execute command" )
109126 }
127+
110128 forceSet := cmd .Flags ().Changed (forceFlag )
111- mgr := l .getManager (client , forceSet )
129+ mgr := l .getManager (client , forceSet , len ( keys ) > 1 )
112130
113131 ctx , cancel := context .WithTimeout (context .Background (), l .opts .Timeout )
114132 defer cancel ()
115- var msg string
133+
116134 switch l .cmd {
117135 case Stop :
118- cmd .Printf ("Stopping virtual machine %q\n " , key .String ())
119- msg , err = mgr .Stop (ctx , name , namespace )
136+ for _ , key := range keys {
137+ cmd .Printf ("Stopping virtual machine %q\n " , key .String ())
138+ msg , err := mgr .Stop (ctx , key .Name , key .Namespace )
139+ l .handleMsgError (cmd , msg , err )
140+ }
120141 case Start :
121- cmd .Printf ("Starting virtual machine %q\n " , key .String ())
122- msg , err = mgr .Start (ctx , name , namespace )
142+ for _ , key := range keys {
143+ cmd .Printf ("Starting virtual machine %q\n " , key .String ())
144+ msg , err := mgr .Start (ctx , key .Name , key .Namespace )
145+ l .handleMsgError (cmd , msg , err )
146+ }
123147 case Restart :
124- cmd .Printf ("Restarting virtual machine %q\n " , key .String ())
125- msg , err = mgr .Restart (ctx , name , namespace )
148+ for _ , key := range keys {
149+ cmd .Printf ("Restarting virtual machine %q\n " , key .String ())
150+ msg , err := mgr .Restart (ctx , key .Name , key .Namespace )
151+ l .handleMsgError (cmd , msg , err )
152+ }
126153 case Evict :
127- cmd .Printf ("Evicting virtual machine %q\n " , key .String ())
128- msg , err = mgr .Evict (ctx , name , namespace )
154+ for _ , key := range keys {
155+ cmd .Printf ("Evicting virtual machine %q\n " , key .String ())
156+ msg , err := mgr .Evict (ctx , key .Name , key .Namespace )
157+ l .handleMsgError (cmd , msg , err )
158+ }
129159 case Migrate :
130- cmd .Printf ("Migrating virtual machine %q\n " , key .String ())
131- msg , err = mgr .Migrate (ctx , name , namespace , l .migrationOpts .TargetNodeName )
160+ for _ , key := range keys {
161+ cmd .Printf ("Migrating virtual machine %q\n " , key .String ())
162+ msg , err := mgr .Migrate (ctx , key .Name , key .Namespace , l .migrationOpts .TargetNodeName )
163+ l .handleMsgError (cmd , msg , err )
164+ }
132165 default :
133166 return fmt .Errorf ("invalid command %q" , l .cmd )
134167 }
168+
169+ return nil
170+ }
171+
172+ func (l * Lifecycle ) handleMsgError (cmd * cobra.Command , msg string , err error ) {
135173 if msg != "" {
136- cmd .Printf ("%s" , msg )
174+ cmd .Printf ("%s\n " , msg )
175+ }
176+ if err != nil {
177+ cmd .Printf ("Error: %s\n " , err .Error ())
137178 }
138- return err
139179}
140180
141181func (l * Lifecycle ) Usage () string {
@@ -157,26 +197,52 @@ func (l *Lifecycle) Usage() string {
157197 return usage
158198}
159199
160- func (l * Lifecycle ) getNameNamespace (defaultNamespace string , args [] string ) (string , string , error ) {
161- namespace , name , err := templates .ParseTarget (args [ 0 ] )
200+ func (l * Lifecycle ) getNamespacedName (defaultNamespace , arg string ) (types. NamespacedName , error ) {
201+ namespace , name , err := templates .ParseTarget (arg )
162202 if err != nil {
163- return "" , "" , err
203+ return types. NamespacedName {} , err
164204 }
165205 if namespace == "" {
166206 namespace = defaultNamespace
167207 }
168- return name , namespace , nil
208+ return types.NamespacedName {Namespace : namespace , Name : name }, nil
209+ }
210+
211+ func (l * Lifecycle ) getNamespacedNames (defaultNamespace string , args []string ) ([]types.NamespacedName , error ) {
212+ var keys []types.NamespacedName
213+ for _ , arg := range args {
214+ key , err := l .getNamespacedName (defaultNamespace , arg )
215+ if err != nil {
216+ return nil , err
217+ }
218+ keys = append (keys , key )
219+ }
220+ return keys , nil
221+ }
222+
223+ func (l * Lifecycle ) getVirtualMachines (ctx context.Context , namespace string , client kubeclient.Client ) ([]types.NamespacedName , error ) {
224+ vmList , err := client .VirtualMachines (namespace ).List (ctx , metav1.ListOptions {})
225+ if err != nil {
226+ return nil , err
227+ }
228+
229+ var keys []types.NamespacedName
230+ for _ , vm := range vmList .Items {
231+ keys = append (keys , types.NamespacedName {Namespace : vm .Namespace , Name : vm .Name })
232+ }
233+
234+ return keys , nil
169235}
170236
171- func (l * Lifecycle ) getManager (client kubeclient.Client , forceSet bool ) Manager {
237+ func (l * Lifecycle ) getManager (client kubeclient.Client , forceSet bool , severalVms bool ) Manager {
172238 var forcePtr * bool
173239 if forceSet {
174240 forcePtr = ptr .To (l .opts .Force )
175241 }
176242
177243 return vmop .New (
178244 client ,
179- vmop .WithCreateOnly (l .opts .CreateOnly ),
245+ vmop .WithCreateOnly (l .opts .CreateOnly || severalVms ),
180246 vmop .WithWaitComplete (l .opts .WaitComplete ),
181247 vmop .WithForce (forcePtr ),
182248 )
@@ -219,6 +285,7 @@ const (
219285 forceFlag , forceFlagShort = "force" , "f"
220286 waitFlag , waitFlagShort = "wait" , "w"
221287 createOnlyFlag , createOnlyFlagShort = "create-only" , "c"
288+ allFlag , allFlagShort = "all" , "a"
222289 timeoutFlag , timeoutFlagShort = "timeout" , "t"
223290)
224291
@@ -229,6 +296,8 @@ func AddCommandLineArgs(flagset *pflag.FlagSet, opts *Options) {
229296 "Set this flag to wait for the operation to complete." )
230297 flagset .BoolVarP (& opts .CreateOnly , createOnlyFlag , createOnlyFlagShort , opts .CreateOnly ,
231298 "Set this flag to only create the action without status warnings or notifications." )
299+ flagset .BoolVarP (& opts .All , allFlag , allFlagShort , opts .All ,
300+ "Set this flag to apply the action to all VMs." )
232301 flagset .DurationVarP (& opts .Timeout , timeoutFlag , timeoutFlagShort , opts .Timeout ,
233302 "Set this flag to change the timeout." )
234303}
0 commit comments