/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests.go

https://github.com/kubeup/archon · Go · 156 lines · 108 code · 20 blank · 28 comment · 26 complexity · 8646ca5a1cdb06b18ef3222210e9b1cd MD5 · raw file

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