Merge pull request #5732 from lblackstone/openstack-schedulerhints

OpenStack: vendor schedulerhints
This commit is contained in:
k8s-ci-robot 2018-08-31 09:41:56 -07:00 committed by GitHub
commit 218b43c51a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 283 additions and 1 deletions

4
Gopkg.lock generated
View File

@ -610,13 +610,14 @@
revision = "0c5108395e2debce0d731cf0287ddf7242066aba"
[[projects]]
digest = "1:5df55e3834b01308cf93fdaf6118fc1ad8418a3bb954bcfaa4b060545a94d4ca"
digest = "1:dc8be055c0a43584d2b728953be6d507c8a48a9b6e055c2dffdb8d8414eb703b"
name = "github.com/gophercloud/gophercloud"
packages = [
".",
"openstack",
"openstack/blockstorage/v2/volumes",
"openstack/compute/v2/extensions/keypairs",
"openstack/compute/v2/extensions/schedulerhints",
"openstack/compute/v2/extensions/servergroups",
"openstack/compute/v2/flavors",
"openstack/compute/v2/images",
@ -2150,6 +2151,7 @@
"github.com/gophercloud/gophercloud/openstack",
"github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes",
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs",
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints",
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups",
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers",
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups",

View File

@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"instance.go",
"network.go",
"network_fitask.go",
"router.go",
@ -28,6 +29,7 @@ go_library(
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules:go_default_library",

View File

@ -0,0 +1,22 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package openstacktasks
import "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints"
// TODO(lmb): Remove after implementing. Using this to pull in the vendor dep.
var _ schedulerhints.SchedulerHints

View File

@ -0,0 +1,16 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"requests.go",
],
importmap = "vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints",
importpath = "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",
],
)

View File

@ -0,0 +1,76 @@
/*
Package schedulerhints extends the server create request with the ability to
specify additional parameters which determine where the server will be
created in the OpenStack cloud.
Example to Add a Server to a Server Group
schedulerHints := schedulerhints.SchedulerHints{
Group: "servergroup-uuid",
}
serverCreateOpts := servers.CreateOpts{
Name: "server_name",
ImageRef: "image-uuid",
FlavorRef: "flavor-uuid",
}
createOpts := schedulerhints.CreateOptsExt{
CreateOptsBuilder: serverCreateOpts,
SchedulerHints: schedulerHints,
}
server, err := servers.Create(computeClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Place Server B on a Different Host than Server A
schedulerHints := schedulerhints.SchedulerHints{
DifferentHost: []string{
"server-a-uuid",
}
}
serverCreateOpts := servers.CreateOpts{
Name: "server_b",
ImageRef: "image-uuid",
FlavorRef: "flavor-uuid",
}
createOpts := schedulerhints.CreateOptsExt{
CreateOptsBuilder: serverCreateOpts,
SchedulerHints: schedulerHints,
}
server, err := servers.Create(computeClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Place Server B on the Same Host as Server A
schedulerHints := schedulerhints.SchedulerHints{
SameHost: []string{
"server-a-uuid",
}
}
serverCreateOpts := servers.CreateOpts{
Name: "server_b",
ImageRef: "image-uuid",
FlavorRef: "flavor-uuid",
}
createOpts := schedulerhints.CreateOptsExt{
CreateOptsBuilder: serverCreateOpts,
SchedulerHints: schedulerHints,
}
server, err := servers.Create(computeClient, createOpts).Extract()
if err != nil {
panic(err)
}
*/
package schedulerhints

View File

@ -0,0 +1,164 @@
package schedulerhints
import (
"net"
"regexp"
"strings"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
)
// SchedulerHints represents a set of scheduling hints that are passed to the
// OpenStack scheduler.
type SchedulerHints struct {
// Group specifies a Server Group to place the instance in.
Group string
// DifferentHost will place the instance on a compute node that does not
// host the given instances.
DifferentHost []string
// SameHost will place the instance on a compute node that hosts the given
// instances.
SameHost []string
// Query is a conditional statement that results in compute nodes able to
// host the instance.
Query []interface{}
// TargetCell specifies a cell name where the instance will be placed.
TargetCell string `json:"target_cell,omitempty"`
// BuildNearHostIP specifies a subnet of compute nodes to host the instance.
BuildNearHostIP string
// AdditionalProperies are arbitrary key/values that are not validated by nova.
AdditionalProperties map[string]interface{}
}
// CreateOptsBuilder builds the scheduler hints into a serializable format.
type CreateOptsBuilder interface {
ToServerSchedulerHintsCreateMap() (map[string]interface{}, error)
}
// ToServerSchedulerHintsMap builds the scheduler hints into a serializable format.
func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interface{}, error) {
sh := make(map[string]interface{})
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}$")
if opts.Group != "" {
if !uuidRegex.MatchString(opts.Group) {
err := gophercloud.ErrInvalidInput{}
err.Argument = "schedulerhints.SchedulerHints.Group"
err.Value = opts.Group
err.Info = "Group must be a UUID"
return nil, err
}
sh["group"] = opts.Group
}
if len(opts.DifferentHost) > 0 {
for _, diffHost := range opts.DifferentHost {
if !uuidRegex.MatchString(diffHost) {
err := gophercloud.ErrInvalidInput{}
err.Argument = "schedulerhints.SchedulerHints.DifferentHost"
err.Value = opts.DifferentHost
err.Info = "The hosts must be in UUID format."
return nil, err
}
}
sh["different_host"] = opts.DifferentHost
}
if len(opts.SameHost) > 0 {
for _, sameHost := range opts.SameHost {
if !uuidRegex.MatchString(sameHost) {
err := gophercloud.ErrInvalidInput{}
err.Argument = "schedulerhints.SchedulerHints.SameHost"
err.Value = opts.SameHost
err.Info = "The hosts must be in UUID format."
return nil, err
}
}
sh["same_host"] = opts.SameHost
}
/*
Query can be something simple like:
[">=", "$free_ram_mb", 1024]
Or more complex like:
['and',
['>=', '$free_ram_mb', 1024],
['>=', '$free_disk_mb', 200 * 1024]
]
Because of the possible complexity, just make sure the length is a minimum of 3.
*/
if len(opts.Query) > 0 {
if len(opts.Query) < 3 {
err := gophercloud.ErrInvalidInput{}
err.Argument = "schedulerhints.SchedulerHints.Query"
err.Value = opts.Query
err.Info = "Must be a conditional statement in the format of [op,variable,value]"
return nil, err
}
sh["query"] = opts.Query
}
if opts.TargetCell != "" {
sh["target_cell"] = opts.TargetCell
}
if opts.BuildNearHostIP != "" {
if _, _, err := net.ParseCIDR(opts.BuildNearHostIP); err != nil {
err := gophercloud.ErrInvalidInput{}
err.Argument = "schedulerhints.SchedulerHints.BuildNearHostIP"
err.Value = opts.BuildNearHostIP
err.Info = "Must be a valid subnet in the form 192.168.1.1/24"
return nil, err
}
ipParts := strings.Split(opts.BuildNearHostIP, "/")
sh["build_near_host_ip"] = ipParts[0]
sh["cidr"] = "/" + ipParts[1]
}
if opts.AdditionalProperties != nil {
for k, v := range opts.AdditionalProperties {
sh[k] = v
}
}
return sh, nil
}
// CreateOptsExt adds a SchedulerHints option to the base CreateOpts.
type CreateOptsExt struct {
servers.CreateOptsBuilder
// SchedulerHints provides a set of hints to the scheduler.
SchedulerHints CreateOptsBuilder
}
// ToServerCreateMap adds the SchedulerHints option to the base server creation options.
func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) {
base, err := opts.CreateOptsBuilder.ToServerCreateMap()
if err != nil {
return nil, err
}
schedulerHints, err := opts.SchedulerHints.ToServerSchedulerHintsCreateMap()
if err != nil {
return nil, err
}
if len(schedulerHints) == 0 {
return base, nil
}
base["os:scheduler_hints"] = schedulerHints
return base, nil
}