| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 serf |
| |
| import ( |
| "fmt" |
| "strconv" |
| |
| "github.com/apache/servicecomb-service-center/syncer/pkg/utils" |
| "github.com/hashicorp/memberlist" |
| "github.com/hashicorp/serf/cmd/serf/command/agent" |
| "github.com/hashicorp/serf/serf" |
| ) |
| |
| const ( |
| DefaultBindPort = 30190 |
| DefaultRPCPort = 30191 |
| DefaultClusterPort = 30192 |
| ModeSingle = "single" |
| ModeCluster = "cluster" |
| retryMaxAttempts = 3 |
| groupExpect = 3 |
| tagKeyClusterName = "syncer-cluster-name" |
| TagKeyClusterPort = "syncer-cluster-port" |
| TagKeyRPCPort = "syncer-rpc-port" |
| TagKeyTLSEnabled = "syncer-tls-enabled" |
| ) |
| |
| // DefaultConfig default config |
| func DefaultConfig() *Config { |
| agentConf := agent.DefaultConfig() |
| agentConf.BindAddr = fmt.Sprintf("0.0.0.0:%d", DefaultBindPort) |
| agentConf.RPCAddr = fmt.Sprintf("0.0.0.0:%d", DefaultRPCPort) |
| return &Config{ |
| Mode: ModeSingle, |
| Config: agentConf, |
| ClusterPort: DefaultClusterPort, |
| } |
| } |
| |
| // Config struct |
| type Config struct { |
| // config from serf agent |
| *agent.Config |
| Mode string `json:"mode"` |
| |
| // name to group members into cluster |
| ClusterName string `json:"cluster_name"` |
| |
| // port to communicate between cluster members |
| ClusterPort int `yaml:"cluster_port"` |
| RPCPort int `yaml:"-"` |
| TLSEnabled bool `json:"-"` |
| } |
| |
| // readConfigFile reads configuration from config file |
| func (c *Config) readConfigFile(filepath string) error { |
| if filepath != "" { |
| // todo: |
| } |
| return nil |
| } |
| |
| // convertToSerf convert Config to serf.Config |
| func (c *Config) convertToSerf() (*serf.Config, error) { |
| serfConf := serf.DefaultConfig() |
| |
| bindIP, bindPort, err := utils.SplitHostPort(c.BindAddr, DefaultBindPort) |
| if err != nil { |
| return nil, fmt.Errorf("invalid bind address: %s", err) |
| } |
| |
| switch c.Profile { |
| case "lan": |
| serfConf.MemberlistConfig = memberlist.DefaultLANConfig() |
| case "wan": |
| serfConf.MemberlistConfig = memberlist.DefaultWANConfig() |
| case "local": |
| serfConf.MemberlistConfig = memberlist.DefaultLocalConfig() |
| default: |
| serfConf.MemberlistConfig = memberlist.DefaultLANConfig() |
| } |
| |
| serfConf.MemberlistConfig.BindAddr = bindIP |
| serfConf.MemberlistConfig.BindPort = bindPort |
| serfConf.NodeName = c.NodeName |
| serfConf.Tags = map[string]string{ |
| TagKeyRPCPort: strconv.Itoa(c.RPCPort), |
| TagKeyTLSEnabled: strconv.FormatBool(c.TLSEnabled), |
| } |
| |
| if c.ClusterName != "" { |
| serfConf.Tags[tagKeyClusterName] = c.ClusterName |
| serfConf.Tags[TagKeyClusterPort] = strconv.Itoa(c.ClusterPort) |
| } |
| |
| if c.Mode == ModeCluster && c.RetryMaxAttempts <= 0 { |
| c.RetryMaxAttempts = retryMaxAttempts |
| } |
| return serfConf, nil |
| } |