blob: e954862b230d382d55e5f764dc190e8e2c3b4260 [file] [log] [blame]
/*
* 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
}