mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
Moved functions to helper from structs
This commit is contained in:
@@ -238,7 +238,7 @@ func NewClient(cfg *config.Config, consulSyncer *consul.Syncer, logger *log.Logg
|
||||
c.configLock.RUnlock()
|
||||
|
||||
// Setup Consul discovery if enabled
|
||||
if c.configCopy.ConsulConfig.ClientAutoJoin {
|
||||
if c.configCopy.ConsulConfig.ClientAutoJoin != nil && *c.configCopy.ConsulConfig.ClientAutoJoin {
|
||||
go c.consulDiscovery()
|
||||
if len(c.servers.all()) == 0 {
|
||||
// No configured servers; trigger discovery manually
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
"github.com/hashicorp/nomad/helper/tlsutil"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
"github.com/hashicorp/nomad/nomad/structs/config"
|
||||
@@ -142,9 +143,9 @@ func (c *Config) Copy() *Config {
|
||||
nc := new(Config)
|
||||
*nc = *c
|
||||
nc.Node = nc.Node.Copy()
|
||||
nc.Servers = structs.CopySliceString(nc.Servers)
|
||||
nc.Options = structs.CopyMapStringString(nc.Options)
|
||||
nc.GloballyReservedPorts = structs.CopySliceInt(c.GloballyReservedPorts)
|
||||
nc.Servers = helper.CopySliceString(nc.Servers)
|
||||
nc.Options = helper.CopyMapStringString(nc.Options)
|
||||
nc.GloballyReservedPorts = helper.CopySliceInt(c.GloballyReservedPorts)
|
||||
nc.ConsulConfig = c.ConsulConfig.Copy()
|
||||
nc.VaultConfig = c.VaultConfig.Copy()
|
||||
return nc
|
||||
|
||||
@@ -420,10 +420,10 @@ func runnerConfig(config *config.Config, vaultToken string) (*ctconf.Config, err
|
||||
conf.Token = config.ConsulConfig.Token
|
||||
set([]string{"consul", "token"})
|
||||
|
||||
if config.ConsulConfig.EnableSSL {
|
||||
if config.ConsulConfig.EnableSSL != nil && *config.ConsulConfig.EnableSSL {
|
||||
conf.SSL = &ctconf.SSLConfig{
|
||||
Enabled: true,
|
||||
Verify: config.ConsulConfig.VerifySSL,
|
||||
Verify: *config.ConsulConfig.VerifySSL,
|
||||
Cert: config.ConsulConfig.CertFile,
|
||||
Key: config.ConsulConfig.KeyFile,
|
||||
CaCert: config.ConsulConfig.CAFile,
|
||||
|
||||
@@ -174,7 +174,7 @@ func (a *Agent) serverConfig() (*nomad.Config, error) {
|
||||
conf.HeartbeatGrace = dur
|
||||
}
|
||||
|
||||
if a.config.Consul.AutoAdvertise && a.config.Consul.ServerServiceName == "" {
|
||||
if *a.config.Consul.AutoAdvertise && a.config.Consul.ServerServiceName == "" {
|
||||
return nil, fmt.Errorf("server_service_name must be set when auto_advertise is enabled")
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ func (a *Agent) clientConfig() (*clientconfig.Config, error) {
|
||||
conf.Version = fmt.Sprintf("%s%s", a.config.Version, a.config.VersionPrerelease)
|
||||
conf.Revision = a.config.Revision
|
||||
|
||||
if a.config.Consul.AutoAdvertise && a.config.Consul.ClientServiceName == "" {
|
||||
if *a.config.Consul.AutoAdvertise && a.config.Consul.ClientServiceName == "" {
|
||||
return nil, fmt.Errorf("client_service_name must be set when auto_advertise is enabled")
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ func (a *Agent) setupServer() error {
|
||||
httpCheckAddr := a.config.normalizedAddrs.HTTP
|
||||
rpcCheckAddr := a.config.normalizedAddrs.RPC
|
||||
serfCheckAddr := a.config.normalizedAddrs.Serf
|
||||
if a.config.Consul.ChecksUseAdvertise {
|
||||
if *a.config.Consul.ChecksUseAdvertise {
|
||||
httpCheckAddr = a.config.AdvertiseAddrs.HTTP
|
||||
rpcCheckAddr = a.config.AdvertiseAddrs.RPC
|
||||
serfCheckAddr = a.config.AdvertiseAddrs.Serf
|
||||
@@ -326,7 +326,7 @@ func (a *Agent) setupServer() error {
|
||||
|
||||
// Create the Nomad Server services for Consul
|
||||
// TODO re-introduce HTTP/S checks when Consul 0.7.1 comes out
|
||||
if a.config.Consul.AutoAdvertise {
|
||||
if *a.config.Consul.AutoAdvertise {
|
||||
httpServ := &structs.Service{
|
||||
Name: a.config.Consul.ServerServiceName,
|
||||
PortLabel: a.config.AdvertiseAddrs.HTTP,
|
||||
@@ -439,14 +439,14 @@ func (a *Agent) setupClient() error {
|
||||
|
||||
// Resolve the http check address
|
||||
httpCheckAddr := a.config.normalizedAddrs.HTTP
|
||||
if a.config.Consul.ChecksUseAdvertise {
|
||||
if *a.config.Consul.ChecksUseAdvertise {
|
||||
httpCheckAddr = a.config.AdvertiseAddrs.HTTP
|
||||
}
|
||||
|
||||
// Create the Nomad Client services for Consul
|
||||
// TODO think how we can re-introduce HTTP/S checks when Consul 0.7.1 comes
|
||||
// out
|
||||
if a.config.Consul.AutoAdvertise {
|
||||
if *a.config.Consul.AutoAdvertise {
|
||||
httpServ := &structs.Service{
|
||||
Name: a.config.Consul.ClientServiceName,
|
||||
PortLabel: a.config.AdvertiseAddrs.HTTP,
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
client "github.com/hashicorp/nomad/client/config"
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
"github.com/hashicorp/nomad/nomad"
|
||||
"github.com/hashicorp/nomad/nomad/structs/config"
|
||||
)
|
||||
@@ -452,7 +453,7 @@ func DevConfig() *Config {
|
||||
conf.DevMode = true
|
||||
conf.EnableDebug = true
|
||||
conf.DisableAnonymousSignature = true
|
||||
conf.Consul.AutoAdvertise = true
|
||||
conf.Consul.AutoAdvertise = helper.BoolToPtr(true)
|
||||
if runtime.GOOS == "darwin" {
|
||||
conf.Client.NetworkInterface = "lo0"
|
||||
} else if runtime.GOOS == "linux" {
|
||||
|
||||
141
helper/funcs.go
Normal file
141
helper/funcs.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package helper
|
||||
|
||||
// boolToPtr returns the pointer to a boolean
|
||||
func BoolToPtr(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
// MapStringStringSliceValueSet returns the set of values in a map[string][]string
|
||||
func MapStringStringSliceValueSet(m map[string][]string) []string {
|
||||
set := make(map[string]struct{})
|
||||
for _, slice := range m {
|
||||
for _, v := range slice {
|
||||
set[v] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
flat := make([]string, 0, len(set))
|
||||
for k := range set {
|
||||
flat = append(flat, k)
|
||||
}
|
||||
return flat
|
||||
}
|
||||
|
||||
func SliceStringToSet(s []string) map[string]struct{} {
|
||||
m := make(map[string]struct{}, (len(s)+1)/2)
|
||||
for _, k := range s {
|
||||
m[k] = struct{}{}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// SliceStringIsSubset returns whether the smaller set of strings is a subset of
|
||||
// the larger. If the smaller slice is not a subset, the offending elements are
|
||||
// returned.
|
||||
func SliceStringIsSubset(larger, smaller []string) (bool, []string) {
|
||||
largerSet := make(map[string]struct{}, len(larger))
|
||||
for _, l := range larger {
|
||||
largerSet[l] = struct{}{}
|
||||
}
|
||||
|
||||
subset := true
|
||||
var offending []string
|
||||
for _, s := range smaller {
|
||||
if _, ok := largerSet[s]; !ok {
|
||||
subset = false
|
||||
offending = append(offending, s)
|
||||
}
|
||||
}
|
||||
|
||||
return subset, offending
|
||||
}
|
||||
|
||||
func SliceSetDisjoint(first, second []string) (bool, []string) {
|
||||
contained := make(map[string]struct{}, len(first))
|
||||
for _, k := range first {
|
||||
contained[k] = struct{}{}
|
||||
}
|
||||
|
||||
offending := make(map[string]struct{})
|
||||
for _, k := range second {
|
||||
if _, ok := contained[k]; ok {
|
||||
offending[k] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
if len(offending) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
flattened := make([]string, 0, len(offending))
|
||||
for k := range offending {
|
||||
flattened = append(flattened, k)
|
||||
}
|
||||
return false, flattened
|
||||
}
|
||||
|
||||
// Helpers for copying generic structures.
|
||||
func CopyMapStringString(m map[string]string) map[string]string {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make(map[string]string, l)
|
||||
for k, v := range m {
|
||||
c[k] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func CopyMapStringInt(m map[string]int) map[string]int {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make(map[string]int, l)
|
||||
for k, v := range m {
|
||||
c[k] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func CopyMapStringFloat64(m map[string]float64) map[string]float64 {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make(map[string]float64, l)
|
||||
for k, v := range m {
|
||||
c[k] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func CopySliceString(s []string) []string {
|
||||
l := len(s)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make([]string, l)
|
||||
for i, v := range s {
|
||||
c[i] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func CopySliceInt(s []int) []int {
|
||||
l := len(s)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make([]int, l)
|
||||
for i, v := range s {
|
||||
c[i] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
37
helper/funcs_test.go
Normal file
37
helper/funcs_test.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package helper
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSliceStringIsSubset(t *testing.T) {
|
||||
l := []string{"a", "b", "c"}
|
||||
s := []string{"d"}
|
||||
|
||||
sub, offending := SliceStringIsSubset(l, l[:1])
|
||||
if !sub || len(offending) != 0 {
|
||||
t.Fatalf("bad %v %v", sub, offending)
|
||||
}
|
||||
|
||||
sub, offending = SliceStringIsSubset(l, s)
|
||||
if sub || len(offending) == 0 || offending[0] != "d" {
|
||||
t.Fatalf("bad %v %v", sub, offending)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapStringStringSliceValueSet(t *testing.T) {
|
||||
m := map[string][]string{
|
||||
"foo": []string{"1", "2"},
|
||||
"bar": []string{"3"},
|
||||
"baz": nil,
|
||||
}
|
||||
|
||||
act := MapStringStringSliceValueSet(m)
|
||||
exp := []string{"1", "2", "3"}
|
||||
sort.Strings(act)
|
||||
if !reflect.DeepEqual(act, exp) {
|
||||
t.Fatalf("Bad; got %v; want %v", act, exp)
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/hashicorp/go-memdb"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/nomad/client/driver"
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
"github.com/hashicorp/nomad/nomad/watch"
|
||||
"github.com/hashicorp/nomad/scheduler"
|
||||
@@ -116,7 +117,7 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
|
||||
// If we are given a root token it can access all policies
|
||||
if !lib.StrContains(allowedPolicies, "root") {
|
||||
flatPolicies := structs.VaultPoliciesSet(policies)
|
||||
subset, offending := structs.SliceStringIsSubset(allowedPolicies, flatPolicies)
|
||||
subset, offending := helper.SliceStringIsSubset(allowedPolicies, flatPolicies)
|
||||
if !subset {
|
||||
return fmt.Errorf("Passed Vault Token doesn't allow access to the following policies: %s",
|
||||
strings.Join(offending, ", "))
|
||||
@@ -218,7 +219,7 @@ func setImplicitConstraints(j *structs.Job) {
|
||||
}
|
||||
|
||||
// Flatten the signals
|
||||
required := structs.MapStringStringSliceValueSet(tgSignals)
|
||||
required := helper.MapStringStringSliceValueSet(tgSignals)
|
||||
sigConstraint := getSignalConstraint(required)
|
||||
|
||||
found := false
|
||||
@@ -899,8 +900,8 @@ func validateDispatchRequest(req *structs.JobDispatchRequest, job *structs.Job)
|
||||
keys[k] = struct{}{}
|
||||
}
|
||||
|
||||
required := structs.SliceStringToSet(job.Constructor.MetaRequired)
|
||||
optional := structs.SliceStringToSet(job.Constructor.MetaOptional)
|
||||
required := helper.SliceStringToSet(job.Constructor.MetaRequired)
|
||||
optional := helper.SliceStringToSet(job.Constructor.MetaOptional)
|
||||
|
||||
// Check the metadata key constraints are met
|
||||
unpermitted := make(map[string]struct{})
|
||||
|
||||
@@ -574,7 +574,7 @@ func (s *Server) setupBootstrapHandler() error {
|
||||
// setupConsulSyncer creates Server-mode consul.Syncer which periodically
|
||||
// executes callbacks on a fixed interval.
|
||||
func (s *Server) setupConsulSyncer() error {
|
||||
if s.config.ConsulConfig.ServerAutoJoin {
|
||||
if s.config.ConsulConfig.ServerAutoJoin != nil && *s.config.ConsulConfig.ServerAutoJoin {
|
||||
if err := s.setupBootstrapHandler(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
consul "github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
)
|
||||
|
||||
// ConsulConfig contains the configuration information necessary to
|
||||
@@ -31,11 +32,11 @@ type ConsulConfig struct {
|
||||
// AutoAdvertise determines if this Nomad Agent will advertise its
|
||||
// services via Consul. When true, Nomad Agent will register
|
||||
// services with Consul.
|
||||
AutoAdvertise bool `mapstructure:"auto_advertise"`
|
||||
AutoAdvertise *bool `mapstructure:"auto_advertise"`
|
||||
|
||||
// ChecksUseAdvertise specifies that Consul checks should use advertise
|
||||
// address instead of bind address
|
||||
ChecksUseAdvertise bool `mapstructure:"checks_use_advertise"`
|
||||
ChecksUseAdvertise *bool `mapstructure:"checks_use_advertise"`
|
||||
|
||||
// Addr is the address of the local Consul agent
|
||||
Addr string `mapstructure:"address"`
|
||||
@@ -51,11 +52,11 @@ type ConsulConfig struct {
|
||||
Auth string `mapstructure:"auth"`
|
||||
|
||||
// EnableSSL sets the transport scheme to talk to the Consul agent as https
|
||||
EnableSSL bool `mapstructure:"ssl"`
|
||||
EnableSSL *bool `mapstructure:"ssl"`
|
||||
|
||||
// VerifySSL enables or disables SSL verification when the transport scheme
|
||||
// for the consul api client is https
|
||||
VerifySSL bool `mapstructure:"verify_ssl"`
|
||||
VerifySSL *bool `mapstructure:"verify_ssl"`
|
||||
|
||||
// CAFile is the path to the ca certificate used for Consul communication
|
||||
CAFile string `mapstructure:"ca_file"`
|
||||
@@ -68,23 +69,26 @@ type ConsulConfig struct {
|
||||
|
||||
// ServerAutoJoin enables Nomad servers to find peers by querying Consul and
|
||||
// joining them
|
||||
ServerAutoJoin bool `mapstructure:"server_auto_join"`
|
||||
ServerAutoJoin *bool `mapstructure:"server_auto_join"`
|
||||
|
||||
// ClientAutoJoin enables Nomad servers to find addresses of Nomad servers
|
||||
// and register with them
|
||||
ClientAutoJoin bool `mapstructure:"client_auto_join"`
|
||||
ClientAutoJoin *bool `mapstructure:"client_auto_join"`
|
||||
}
|
||||
|
||||
// DefaultConsulConfig() returns the canonical defaults for the Nomad
|
||||
// `consul` configuration.
|
||||
func DefaultConsulConfig() *ConsulConfig {
|
||||
return &ConsulConfig{
|
||||
ServerServiceName: "nomad",
|
||||
ClientServiceName: "nomad-client",
|
||||
AutoAdvertise: true,
|
||||
ServerAutoJoin: true,
|
||||
ClientAutoJoin: true,
|
||||
Timeout: 5 * time.Second,
|
||||
ServerServiceName: "nomad",
|
||||
ClientServiceName: "nomad-client",
|
||||
AutoAdvertise: helper.BoolToPtr(true),
|
||||
ChecksUseAdvertise: helper.BoolToPtr(false),
|
||||
EnableSSL: helper.BoolToPtr(false),
|
||||
VerifySSL: helper.BoolToPtr(false),
|
||||
ServerAutoJoin: helper.BoolToPtr(true),
|
||||
ClientAutoJoin: helper.BoolToPtr(true),
|
||||
Timeout: 5 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,8 +102,8 @@ func (a *ConsulConfig) Merge(b *ConsulConfig) *ConsulConfig {
|
||||
if b.ClientServiceName != "" {
|
||||
result.ClientServiceName = b.ClientServiceName
|
||||
}
|
||||
if !b.AutoAdvertise {
|
||||
result.AutoAdvertise = false
|
||||
if b.AutoAdvertise != nil {
|
||||
result.AutoAdvertise = b.AutoAdvertise
|
||||
}
|
||||
if b.Addr != "" {
|
||||
result.Addr = b.Addr
|
||||
@@ -113,11 +117,11 @@ func (a *ConsulConfig) Merge(b *ConsulConfig) *ConsulConfig {
|
||||
if b.Auth != "" {
|
||||
result.Auth = b.Auth
|
||||
}
|
||||
if b.EnableSSL {
|
||||
result.EnableSSL = true
|
||||
if b.EnableSSL != nil {
|
||||
result.EnableSSL = b.EnableSSL
|
||||
}
|
||||
if b.VerifySSL {
|
||||
result.VerifySSL = true
|
||||
if b.VerifySSL != nil {
|
||||
result.VerifySSL = b.EnableSSL
|
||||
}
|
||||
if b.CAFile != "" {
|
||||
result.CAFile = b.CAFile
|
||||
@@ -128,11 +132,11 @@ func (a *ConsulConfig) Merge(b *ConsulConfig) *ConsulConfig {
|
||||
if b.KeyFile != "" {
|
||||
result.KeyFile = b.KeyFile
|
||||
}
|
||||
if b.ServerAutoJoin {
|
||||
result.ServerAutoJoin = true
|
||||
if b.ServerAutoJoin != nil {
|
||||
result.ServerAutoJoin = b.ServerAutoJoin
|
||||
}
|
||||
if b.ClientAutoJoin {
|
||||
result.ClientAutoJoin = true
|
||||
if b.ClientAutoJoin != nil {
|
||||
result.ClientAutoJoin = b.ServerAutoJoin
|
||||
}
|
||||
return &result
|
||||
}
|
||||
@@ -165,14 +169,16 @@ func (c *ConsulConfig) ApiConfig() (*consul.Config, error) {
|
||||
Password: password,
|
||||
}
|
||||
}
|
||||
if c.EnableSSL {
|
||||
if c.EnableSSL != nil && *c.EnableSSL {
|
||||
config.Scheme = "https"
|
||||
tlsConfig := consul.TLSConfig{
|
||||
Address: config.Address,
|
||||
CAFile: c.CAFile,
|
||||
CertFile: c.CertFile,
|
||||
KeyFile: c.KeyFile,
|
||||
InsecureSkipVerify: !c.VerifySSL,
|
||||
Address: config.Address,
|
||||
CAFile: c.CAFile,
|
||||
CertFile: c.CertFile,
|
||||
KeyFile: c.KeyFile,
|
||||
}
|
||||
if c.VerifySSL != nil {
|
||||
tlsConfig.InsecureSkipVerify = !*c.VerifySSL
|
||||
}
|
||||
tlsClientCfg, err := consul.SetupTLSConfig(&tlsConfig)
|
||||
if err != nil {
|
||||
@@ -182,7 +188,7 @@ func (c *ConsulConfig) ApiConfig() (*consul.Config, error) {
|
||||
TLSClientConfig: tlsClientCfg,
|
||||
}
|
||||
}
|
||||
if c.EnableSSL && !c.VerifySSL {
|
||||
if c.EnableSSL != nil && !*c.VerifySSL {
|
||||
config.HttpClient.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
|
||||
@@ -169,72 +169,6 @@ func GenerateUUID() string {
|
||||
buf[10:16])
|
||||
}
|
||||
|
||||
// Helpers for copying generic structures.
|
||||
func CopyMapStringString(m map[string]string) map[string]string {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make(map[string]string, l)
|
||||
for k, v := range m {
|
||||
c[k] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func CopyMapStringInt(m map[string]int) map[string]int {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make(map[string]int, l)
|
||||
for k, v := range m {
|
||||
c[k] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func CopyMapStringFloat64(m map[string]float64) map[string]float64 {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make(map[string]float64, l)
|
||||
for k, v := range m {
|
||||
c[k] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func CopySliceString(s []string) []string {
|
||||
l := len(s)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make([]string, l)
|
||||
for i, v := range s {
|
||||
c[i] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func CopySliceInt(s []int) []int {
|
||||
l := len(s)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := make([]int, l)
|
||||
for i, v := range s {
|
||||
c[i] = v
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func CopySliceConstraints(s []*Constraint) []*Constraint {
|
||||
l := len(s)
|
||||
if l == 0 {
|
||||
@@ -248,51 +182,6 @@ func CopySliceConstraints(s []*Constraint) []*Constraint {
|
||||
return c
|
||||
}
|
||||
|
||||
// SliceStringIsSubset returns whether the smaller set of strings is a subset of
|
||||
// the larger. If the smaller slice is not a subset, the offending elements are
|
||||
// returned.
|
||||
func SliceStringIsSubset(larger, smaller []string) (bool, []string) {
|
||||
largerSet := make(map[string]struct{}, len(larger))
|
||||
for _, l := range larger {
|
||||
largerSet[l] = struct{}{}
|
||||
}
|
||||
|
||||
subset := true
|
||||
var offending []string
|
||||
for _, s := range smaller {
|
||||
if _, ok := largerSet[s]; !ok {
|
||||
subset = false
|
||||
offending = append(offending, s)
|
||||
}
|
||||
}
|
||||
|
||||
return subset, offending
|
||||
}
|
||||
|
||||
func SliceSetDisjoint(first, second []string) (bool, []string) {
|
||||
contained := make(map[string]struct{}, len(first))
|
||||
for _, k := range first {
|
||||
contained[k] = struct{}{}
|
||||
}
|
||||
|
||||
offending := make(map[string]struct{})
|
||||
for _, k := range second {
|
||||
if _, ok := contained[k]; ok {
|
||||
offending[k] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
if len(offending) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
flattened := make([]string, 0, len(offending))
|
||||
for k := range offending {
|
||||
flattened = append(flattened, k)
|
||||
}
|
||||
return false, flattened
|
||||
}
|
||||
|
||||
// VaultPoliciesSet takes the structure returned by VaultPolicies and returns
|
||||
// the set of required policies
|
||||
func VaultPoliciesSet(policies map[string]map[string]*Vault) []string {
|
||||
@@ -312,27 +201,3 @@ func VaultPoliciesSet(policies map[string]map[string]*Vault) []string {
|
||||
}
|
||||
return flattened
|
||||
}
|
||||
|
||||
// MapStringStringSliceValueSet returns the set of values in a map[string][]string
|
||||
func MapStringStringSliceValueSet(m map[string][]string) []string {
|
||||
set := make(map[string]struct{})
|
||||
for _, slice := range m {
|
||||
for _, v := range slice {
|
||||
set[v] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
flat := make([]string, 0, len(set))
|
||||
for k := range set {
|
||||
flat = append(flat, k)
|
||||
}
|
||||
return flat
|
||||
}
|
||||
|
||||
func SliceStringToSet(s []string) map[string]struct{} {
|
||||
m := make(map[string]struct{}, (len(s)+1)/2)
|
||||
for _, k := range s {
|
||||
m[k] = struct{}{}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ package structs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -271,33 +269,3 @@ func TestGenerateUUID(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceStringIsSubset(t *testing.T) {
|
||||
l := []string{"a", "b", "c"}
|
||||
s := []string{"d"}
|
||||
|
||||
sub, offending := SliceStringIsSubset(l, l[:1])
|
||||
if !sub || len(offending) != 0 {
|
||||
t.Fatalf("bad %v %v", sub, offending)
|
||||
}
|
||||
|
||||
sub, offending = SliceStringIsSubset(l, s)
|
||||
if sub || len(offending) == 0 || offending[0] != "d" {
|
||||
t.Fatalf("bad %v %v", sub, offending)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapStringStringSliceValueSet(t *testing.T) {
|
||||
m := map[string][]string{
|
||||
"foo": []string{"1", "2"},
|
||||
"bar": []string{"3"},
|
||||
"baz": nil,
|
||||
}
|
||||
|
||||
act := MapStringStringSliceValueSet(m)
|
||||
exp := []string{"1", "2", "3"}
|
||||
sort.Strings(act)
|
||||
if !reflect.DeepEqual(act, exp) {
|
||||
t.Fatalf("Bad; got %v; want %v", act, exp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
"github.com/hashicorp/nomad/helper/args"
|
||||
"github.com/mitchellh/copystructure"
|
||||
"github.com/ugorji/go/codec"
|
||||
@@ -763,11 +764,11 @@ func (n *Node) Copy() *Node {
|
||||
}
|
||||
nn := new(Node)
|
||||
*nn = *n
|
||||
nn.Attributes = CopyMapStringString(nn.Attributes)
|
||||
nn.Attributes = helper.CopyMapStringString(nn.Attributes)
|
||||
nn.Resources = nn.Resources.Copy()
|
||||
nn.Reserved = nn.Reserved.Copy()
|
||||
nn.Links = CopyMapStringString(nn.Links)
|
||||
nn.Meta = CopyMapStringString(nn.Meta)
|
||||
nn.Links = helper.CopyMapStringString(nn.Links)
|
||||
nn.Meta = helper.CopyMapStringString(nn.Meta)
|
||||
return nn
|
||||
}
|
||||
|
||||
@@ -1183,7 +1184,7 @@ func (j *Job) Copy() *Job {
|
||||
}
|
||||
nj := new(Job)
|
||||
*nj = *j
|
||||
nj.Datacenters = CopySliceString(nj.Datacenters)
|
||||
nj.Datacenters = helper.CopySliceString(nj.Datacenters)
|
||||
nj.Constraints = CopySliceConstraints(nj.Constraints)
|
||||
|
||||
if j.TaskGroups != nil {
|
||||
@@ -1195,7 +1196,7 @@ func (j *Job) Copy() *Job {
|
||||
}
|
||||
|
||||
nj.Periodic = nj.Periodic.Copy()
|
||||
nj.Meta = CopyMapStringString(nj.Meta)
|
||||
nj.Meta = helper.CopyMapStringString(nj.Meta)
|
||||
nj.Constructor = nj.Constructor.Copy()
|
||||
return nj
|
||||
}
|
||||
@@ -1309,7 +1310,7 @@ func (j *Job) CombinedTaskMeta(groupName, taskName string) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
meta := CopyMapStringString(task.Meta)
|
||||
meta := helper.CopyMapStringString(task.Meta)
|
||||
if meta == nil {
|
||||
meta = make(map[string]string, len(group.Meta)+len(j.Meta))
|
||||
}
|
||||
@@ -1660,7 +1661,7 @@ func (d *ConstructorConfig) Validate() error {
|
||||
}
|
||||
|
||||
// Check that the meta configurations are disjoint sets
|
||||
disjoint, offending := SliceSetDisjoint(d.MetaRequired, d.MetaOptional)
|
||||
disjoint, offending := helper.SliceSetDisjoint(d.MetaRequired, d.MetaOptional)
|
||||
if !disjoint {
|
||||
multierror.Append(&mErr, fmt.Errorf("Required and optional meta keys should be disjoint. Following keys exist in both: %v", offending))
|
||||
}
|
||||
@@ -1680,8 +1681,8 @@ func (d *ConstructorConfig) Copy() *ConstructorConfig {
|
||||
}
|
||||
nd := new(ConstructorConfig)
|
||||
*nd = *d
|
||||
nd.MetaOptional = CopySliceString(nd.MetaOptional)
|
||||
nd.MetaRequired = CopySliceString(nd.MetaRequired)
|
||||
nd.MetaOptional = helper.CopySliceString(nd.MetaOptional)
|
||||
nd.MetaRequired = helper.CopySliceString(nd.MetaRequired)
|
||||
return nd
|
||||
}
|
||||
|
||||
@@ -1850,7 +1851,7 @@ func (tg *TaskGroup) Copy() *TaskGroup {
|
||||
ntg.Tasks = tasks
|
||||
}
|
||||
|
||||
ntg.Meta = CopyMapStringString(ntg.Meta)
|
||||
ntg.Meta = helper.CopyMapStringString(ntg.Meta)
|
||||
|
||||
if tg.EphemeralDisk != nil {
|
||||
ntg.EphemeralDisk = tg.EphemeralDisk.Copy()
|
||||
@@ -2113,7 +2114,7 @@ func (s *Service) Copy() *Service {
|
||||
}
|
||||
ns := new(Service)
|
||||
*ns = *s
|
||||
ns.Tags = CopySliceString(ns.Tags)
|
||||
ns.Tags = helper.CopySliceString(ns.Tags)
|
||||
|
||||
if s.Checks != nil {
|
||||
checks := make([]*ServiceCheck, len(ns.Checks))
|
||||
@@ -2295,7 +2296,7 @@ func (t *Task) Copy() *Task {
|
||||
}
|
||||
nt := new(Task)
|
||||
*nt = *t
|
||||
nt.Env = CopyMapStringString(nt.Env)
|
||||
nt.Env = helper.CopyMapStringString(nt.Env)
|
||||
|
||||
if t.Services != nil {
|
||||
services := make([]*Service, len(nt.Services))
|
||||
@@ -2309,7 +2310,7 @@ func (t *Task) Copy() *Task {
|
||||
|
||||
nt.Vault = nt.Vault.Copy()
|
||||
nt.Resources = nt.Resources.Copy()
|
||||
nt.Meta = CopyMapStringString(nt.Meta)
|
||||
nt.Meta = helper.CopyMapStringString(nt.Meta)
|
||||
nt.DispatchInput = nt.DispatchInput.Copy()
|
||||
|
||||
if t.Artifacts != nil {
|
||||
@@ -2979,7 +2980,7 @@ func (ta *TaskArtifact) Copy() *TaskArtifact {
|
||||
}
|
||||
nta := new(TaskArtifact)
|
||||
*nta = *ta
|
||||
nta.GetterOptions = CopyMapStringString(ta.GetterOptions)
|
||||
nta.GetterOptions = helper.CopyMapStringString(ta.GetterOptions)
|
||||
return nta
|
||||
}
|
||||
|
||||
@@ -3531,12 +3532,12 @@ func (a *AllocMetric) Copy() *AllocMetric {
|
||||
}
|
||||
na := new(AllocMetric)
|
||||
*na = *a
|
||||
na.NodesAvailable = CopyMapStringInt(na.NodesAvailable)
|
||||
na.ClassFiltered = CopyMapStringInt(na.ClassFiltered)
|
||||
na.ConstraintFiltered = CopyMapStringInt(na.ConstraintFiltered)
|
||||
na.ClassExhausted = CopyMapStringInt(na.ClassExhausted)
|
||||
na.DimensionExhausted = CopyMapStringInt(na.DimensionExhausted)
|
||||
na.Scores = CopyMapStringFloat64(na.Scores)
|
||||
na.NodesAvailable = helper.CopyMapStringInt(na.NodesAvailable)
|
||||
na.ClassFiltered = helper.CopyMapStringInt(na.ClassFiltered)
|
||||
na.ConstraintFiltered = helper.CopyMapStringInt(na.ConstraintFiltered)
|
||||
na.ClassExhausted = helper.CopyMapStringInt(na.ClassExhausted)
|
||||
na.DimensionExhausted = helper.CopyMapStringInt(na.DimensionExhausted)
|
||||
na.Scores = helper.CopyMapStringFloat64(na.Scores)
|
||||
return na
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user