@@ -10,6 +10,7 @@ import (
1010 "log"
1111 "net/http"
1212 "reflect"
13+ "strings"
1314 "time"
1415
1516 "github.com/apache/cloudstack-go/v2/cloudstack"
@@ -567,8 +568,12 @@ func (c *Controller) applyVM(vm *v1.VirtualMachine) error {
567568 // search CloudStack by name and project
568569 params := c .csClient .VirtualMachine .NewListVirtualMachinesParams ()
569570 params .SetName (vm .Metadata .Name )
570- if vm .Spec .ProjectID != "" {
571- params .SetProjectid (vm .Spec .ProjectID )
571+ if vm .Spec .Project != "" {
572+ if pid , perr := handlers .ResolveProject (vm .Spec .Project ); perr == nil {
573+ params .SetProjectid (pid )
574+ } else {
575+ params .SetProjectid (vm .Spec .Project )
576+ }
572577 }
573578 tags := map [string ]string {"managed_by" : "cloudstackctl" }
574579 params .SetTags (tags )
@@ -618,7 +623,7 @@ func compareVMSpec(a, b v1.VirtualMachineSpec) bool {
618623 if a .ServiceOffering != b .ServiceOffering {
619624 return false
620625 }
621- if a .ProjectID != b .ProjectID {
626+ if a .Project != b .Project {
622627 return false
623628 }
624629 if len (a .NetworkIDs ) != len (b .NetworkIDs ) {
@@ -673,7 +678,14 @@ func (c *Controller) createVM(vm *v1.VirtualMachine) error {
673678 "" ,
674679 )
675680 params .SetName (vm .Metadata .Name )
676- params .SetProjectid (vm .Spec .ProjectID )
681+ // Accept project name or ID
682+ if vm .Spec .Project != "" {
683+ if pid , perr := handlers .ResolveProject (vm .Spec .Project ); perr == nil {
684+ params .SetProjectid (pid )
685+ } else {
686+ params .SetProjectid (vm .Spec .Project )
687+ }
688+ }
677689 if len (vm .Spec .NetworkIDs ) > 0 {
678690 params .SetNetworkids (vm .Spec .NetworkIDs )
679691 }
@@ -683,6 +695,32 @@ func (c *Controller) createVM(vm *v1.VirtualMachine) error {
683695 params .SetKeypair (vm .Spec .SSHKeys [0 ])
684696 }
685697
698+ // Apply optional deploy parameters from the VM spec where possible.
699+ // This attempts to call SDK setter methods (e.g., SetBootMode) if they exist.
700+ if vm .Spec .Parameters != nil {
701+ pv := reflect .ValueOf (params )
702+ for k , v := range vm .Spec .Parameters {
703+ parts := strings .FieldsFunc (k , func (r rune ) bool { return r == '_' || r == '-' || r == ' ' })
704+ for i := range parts {
705+ parts [i ] = strings .Title (parts [i ])
706+ }
707+ camel := strings .Join (parts , "" )
708+ candidates := []string {"Set" + camel , "Set" + strings .Title (k )}
709+ applied := false
710+ for _ , m := range candidates {
711+ meth := pv .MethodByName (m )
712+ if meth .IsValid () && meth .Type ().NumIn () == 1 && meth .Type ().In (0 ).Kind () == reflect .String {
713+ meth .Call ([]reflect.Value {reflect .ValueOf (v )})
714+ applied = true
715+ break
716+ }
717+ }
718+ if ! applied {
719+ log .Printf ("info: VM parameter '%s' not applied (no SDK setter found)" , k )
720+ }
721+ }
722+ }
723+
686724 // Tagging is handled after deployment via the Resourcetags service below.
687725
688726 // Execute API call
0 commit comments