github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/openstack/compute/v2/extensions/schedulerhints/requests.go (about)

     1  package schedulerhints
     2  
     3  import (
     4  	"net"
     5  	"regexp"
     6  	"strings"
     7  
     8  	"github.com/huaweicloud/golangsdk"
     9  	"github.com/huaweicloud/golangsdk/openstack/compute/v2/servers"
    10  )
    11  
    12  // SchedulerHints represents a set of scheduling hints that are passed to the
    13  // OpenStack scheduler.
    14  type SchedulerHints struct {
    15  	// Group specifies a Server Group to place the instance in.
    16  	Group string
    17  
    18  	// DifferentHost will place the instance on a compute node that does not
    19  	// host the given instances.
    20  	DifferentHost []string
    21  
    22  	// SameHost will place the instance on a compute node that hosts the given
    23  	// instances.
    24  	SameHost []string
    25  
    26  	// Query is a conditional statement that results in compute nodes able to
    27  	// host the instance.
    28  	Query []interface{}
    29  
    30  	// TargetCell specifies a cell name where the instance will be placed.
    31  	TargetCell string `json:"target_cell,omitempty"`
    32  
    33  	// BuildNearHostIP specifies a subnet of compute nodes to host the instance.
    34  	BuildNearHostIP string
    35  
    36  	// AdditionalProperies are arbitrary key/values that are not validated by nova.
    37  	AdditionalProperties map[string]interface{}
    38  
    39  	// Specifies whether the ECS is created on a Dedicated Host (DeH) or in a shared pool.
    40  	Tenancy string `json:"tenancy,omitempty"`
    41  
    42  	// DedicatedHostID specifies a DeH ID.
    43  	DedicatedHostID string `json:"dedicated_host_id,omitempty"`
    44  }
    45  
    46  // CreateOptsBuilder builds the scheduler hints into a serializable format.
    47  type CreateOptsBuilder interface {
    48  	ToServerSchedulerHintsCreateMap() (map[string]interface{}, error)
    49  }
    50  
    51  // ToServerSchedulerHintsMap builds the scheduler hints into a serializable format.
    52  func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interface{}, error) {
    53  	sh := make(map[string]interface{})
    54  
    55  	uuidRegex, _ := regexp.Compile("^[a-z0-9]{8}-[a-z0-9]{4}-[1-5][a-z0-9]{3}-[a-z0-9]{4}-[a-z0-9]{12}$")
    56  
    57  	if opts.Group != "" {
    58  		if !uuidRegex.MatchString(opts.Group) {
    59  			err := golangsdk.ErrInvalidInput{}
    60  			err.Argument = "schedulerhints.SchedulerHints.Group"
    61  			err.Value = opts.Group
    62  			err.Info = "Group must be a UUID"
    63  			return nil, err
    64  		}
    65  		sh["group"] = opts.Group
    66  	}
    67  
    68  	if len(opts.DifferentHost) > 0 {
    69  		for _, diffHost := range opts.DifferentHost {
    70  			if !uuidRegex.MatchString(diffHost) {
    71  				err := golangsdk.ErrInvalidInput{}
    72  				err.Argument = "schedulerhints.SchedulerHints.DifferentHost"
    73  				err.Value = opts.DifferentHost
    74  				err.Info = "The hosts must be in UUID format."
    75  				return nil, err
    76  			}
    77  		}
    78  		sh["different_host"] = opts.DifferentHost
    79  	}
    80  
    81  	if len(opts.SameHost) > 0 {
    82  		for _, sameHost := range opts.SameHost {
    83  			if !uuidRegex.MatchString(sameHost) {
    84  				err := golangsdk.ErrInvalidInput{}
    85  				err.Argument = "schedulerhints.SchedulerHints.SameHost"
    86  				err.Value = opts.SameHost
    87  				err.Info = "The hosts must be in UUID format."
    88  				return nil, err
    89  			}
    90  		}
    91  		sh["same_host"] = opts.SameHost
    92  	}
    93  
    94  	/*
    95  		Query can be something simple like:
    96  			 [">=", "$free_ram_mb", 1024]
    97  
    98  			Or more complex like:
    99  				['and',
   100  					['>=', '$free_ram_mb', 1024],
   101  					['>=', '$free_disk_mb', 200 * 1024]
   102  				]
   103  
   104  		Because of the possible complexity, just make sure the length is a minimum of 3.
   105  	*/
   106  	if len(opts.Query) > 0 {
   107  		if len(opts.Query) < 3 {
   108  			err := golangsdk.ErrInvalidInput{}
   109  			err.Argument = "schedulerhints.SchedulerHints.Query"
   110  			err.Value = opts.Query
   111  			err.Info = "Must be a conditional statement in the format of [op,variable,value]"
   112  			return nil, err
   113  		}
   114  		sh["query"] = opts.Query
   115  	}
   116  
   117  	if opts.TargetCell != "" {
   118  		sh["target_cell"] = opts.TargetCell
   119  	}
   120  
   121  	if opts.BuildNearHostIP != "" {
   122  		if _, _, err := net.ParseCIDR(opts.BuildNearHostIP); err != nil {
   123  			err := golangsdk.ErrInvalidInput{}
   124  			err.Argument = "schedulerhints.SchedulerHints.BuildNearHostIP"
   125  			err.Value = opts.BuildNearHostIP
   126  			err.Info = "Must be a valid subnet in the form 192.168.1.1/24"
   127  			return nil, err
   128  		}
   129  		ipParts := strings.Split(opts.BuildNearHostIP, "/")
   130  		sh["build_near_host_ip"] = ipParts[0]
   131  		sh["cidr"] = "/" + ipParts[1]
   132  	}
   133  
   134  	if opts.AdditionalProperties != nil {
   135  		for k, v := range opts.AdditionalProperties {
   136  			sh[k] = v
   137  		}
   138  	}
   139  
   140  	if opts.Tenancy != "" {
   141  		sh["tenancy"] = opts.Tenancy
   142  	}
   143  
   144  	if opts.DedicatedHostID != "" {
   145  		sh["dedicated_host_id"] = opts.DedicatedHostID
   146  	}
   147  
   148  	return sh, nil
   149  }
   150  
   151  // CreateOptsExt adds a SchedulerHints option to the base CreateOpts.
   152  type CreateOptsExt struct {
   153  	servers.CreateOptsBuilder
   154  
   155  	// SchedulerHints provides a set of hints to the scheduler.
   156  	SchedulerHints CreateOptsBuilder
   157  }
   158  
   159  // ToServerCreateMap adds the SchedulerHints option to the base server creation options.
   160  func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) {
   161  	base, err := opts.CreateOptsBuilder.ToServerCreateMap()
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  
   166  	schedulerHints, err := opts.SchedulerHints.ToServerSchedulerHintsCreateMap()
   167  	if err != nil {
   168  		return nil, err
   169  	}
   170  
   171  	if len(schedulerHints) == 0 {
   172  		return base, nil
   173  	}
   174  
   175  	base["os:scheduler_hints"] = schedulerHints
   176  
   177  	return base, nil
   178  }