package schema import ( "encoding/json" "errors" "fmt" "sort" ) /* healthCheckNodePort */ const Version = "v1" type ProxyProtocol string const ( ProxyProtocolV1 ProxyProtocol = "v1" ProxyProtocolV2 = "v2" ) type LoadBalancer struct { Name string `json:"name,omitempty"` IP string `json:"ip,omitempty"` CIDR string `json:"cidr,omitempty"` Options Options `json:"options,omitempty"` Ports Ports `json:"ports,omitempty"` } func NewLoadBalancerFromBytes(b []byte) (lb *LoadBalancer, err error) { lb = new(LoadBalancer) err = json.Unmarshal(b, lb) return } type Options struct { Frontend []string `json:"frontend,omitempty"` Backend []string `json:"backend,omitempty"` ProxyProtocol ProxyProtocol `json:"proxyProtocol,omitempty"` CheckProxyProtocol bool `json:"checkProxyProtocol,omitempty"` DefaultServer string `json:"defaultServer,omitempty` } type Port struct { Port int `json:"port,omitempty"` Servers Servers `json:"servers,omitempty"` } type Ports []Port func (p Ports) Len() int { return len(p) } func (p Ports) Less(i, j int) bool { return p[i].Port < p[j].Port } func (p Ports) Swap(i, j int) { p[i], p[j] = p[j], p[i] } type Server struct { Name string `json:"name,omitempty"` IP string `json:"ip,omitempty"` Port int `json:"port,omitempty"` } type Servers []Server func (s Servers) Len() int { return len(s) } func (s Servers) Less(i, j int) bool { return s[i].Name < s[j].Name } func (s Servers) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (o Servers) Equal(n Servers) bool { if len(o) != len(n) { return false } for i, v := range o { if v.Name != n[i].Name || v.IP != n[i].IP || v.Port != n[i].Port { return false } } return true } func (o Servers) ContainsIP(ip string) bool { return o.IndexOfIP(ip) != -1 } func (o Servers) IndexOfIP(ip string) int { for i, v := range o { if v.IP == ip { return i } } return -1 } func (o Servers) RemoveByIP(ip string) Servers { index := o.IndexOfIP(ip) if index == -1 { return o } return append(o[:index], o[index+1:]...) } func (o Servers) ContainsName(name string) bool { return o.IndexOfName(name) != -1 } func (o Servers) IndexOfName(name string) int { for i, v := range o { if v.Name == name { return i } } return -1 } func (o Servers) RemoveByName(name string) Servers { index := o.IndexOfName(name) if index == -1 { return o } return append(o[:index], o[index+1:]...) } func (lb LoadBalancer) ValidateClient() error { for i, p := range lb.Ports { if p.Port < 0 || p.Port > 65535 { return fmt.Errorf("LoadBalancer.Ports[%d].Port is invalid (range 0-65535", i) } for j, s := range p.Servers { if s.Name == "" { return fmt.Errorf("LoadBalancer.Ports[%d].Servers[%d].Name can not be empty", i, j) } if s.IP == "" { return fmt.Errorf("LoadBalancer.Ports[%d].Servers[%d].IP can not be empty", i, j) } if s.Port < 0 || s.Port > 65535 { return fmt.Errorf("LoadBalancer.Ports[%d].Servers[%d].Port is invalid (range 0-65535)", i, j) } } } return nil } func (lb LoadBalancer) ValidateServer() error { if lb.Name == "" { return errors.New("LoadBalancer.Name can not be empty") } if lb.IP == "" { return errors.New("LoadBalancer.IP can not be empty") } if lb.CIDR == "" { return errors.New("LoadBalancer.CIDR can not be empty") } switch lb.Options.ProxyProtocol { case "", ProxyProtocolV1, ProxyProtocolV2: default: return errors.New(`LoadBalancer.Options.ProxyProtocol invalid value. (allowed: "", "v1", "v2")`) } err := lb.ValidateClient() if err != nil { return err } sort.Sort(lb.Ports) for _, p := range lb.Ports { sort.Sort(p.Servers) } return nil } func (lb LoadBalancer) JSON() ([]byte, error) { return json.Marshal(lb) }