1/* 2Copyright 2014 The go-marathon Authors All rights reserved. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package marathon 18 19import ( 20 "errors" 21 "fmt" 22 "net" 23 "net/url" 24 "reflect" 25 "strings" 26 "sync/atomic" 27 "time" 28 29 "github.com/google/go-querystring/query" 30) 31 32type atomicSwitch int64 33 34func (r *atomicSwitch) IsSwitched() bool { 35 return atomic.LoadInt64((*int64)(r)) != 0 36} 37 38func (r *atomicSwitch) SwitchOn() { 39 atomic.StoreInt64((*int64)(r), 1) 40} 41 42func (r *atomicSwitch) SwitchedOff() { 43 atomic.StoreInt64((*int64)(r), 0) 44} 45 46func validateID(id string) string { 47 if !strings.HasPrefix(id, "/") { 48 return fmt.Sprintf("/%s", id) 49 } 50 return id 51} 52 53func trimRootPath(id string) string { 54 if strings.HasPrefix(id, "/") { 55 return strings.TrimPrefix(id, "/") 56 } 57 return id 58} 59 60func deadline(timeout time.Duration, work func(chan bool) error) error { 61 result := make(chan error) 62 timer := time.After(timeout) 63 stopChannel := make(chan bool, 1) 64 65 // allow the method to attempt 66 go func() { 67 result <- work(stopChannel) 68 }() 69 for { 70 select { 71 case err := <-result: 72 return err 73 case <-timer: 74 stopChannel <- true 75 return ErrTimeoutError 76 } 77 } 78} 79 80func getInterfaceAddress(name string) (string, error) { 81 interfaces, err := net.Interfaces() 82 if err != nil { 83 return "", err 84 } 85 for _, iface := range interfaces { 86 // step: get only the interface we're interested in 87 if iface.Name == name { 88 addrs, err := iface.Addrs() 89 if err != nil { 90 return "", err 91 } 92 // step: return the first address 93 if len(addrs) > 0 { 94 return parseIPAddr(addrs[0]), nil 95 } 96 } 97 } 98 99 return "", errors.New("Unable to determine or find the interface") 100} 101 102func contains(elements []string, value string) bool { 103 for _, element := range elements { 104 if element == value { 105 return true 106 } 107 } 108 return false 109} 110 111func parseIPAddr(addr net.Addr) string { 112 return strings.SplitN(addr.String(), "/", 2)[0] 113} 114 115// addOptions adds the parameters in opt as URL query parameters to s. 116// opt must be a struct whose fields may contain "url" tags. 117func addOptions(s string, opt interface{}) (string, error) { 118 v := reflect.ValueOf(opt) 119 if v.Kind() == reflect.Ptr && v.IsNil() { 120 return s, nil 121 } 122 123 u, err := url.Parse(s) 124 if err != nil { 125 return s, err 126 } 127 128 qs, err := query.Values(opt) 129 if err != nil { 130 return s, err 131 } 132 133 u.RawQuery = qs.Encode() 134 return u.String(), nil 135} 136