Documentation ¶
Overview ¶
PulseHA - HA Cluster Daemon Copyright (C) 2017-2020 Andrew Zak <andrew@linux.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
PulseHA - HA Cluster Daemon Copyright (C) 2017-2020 Andrew Zak <andrew@linux.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
PulseHA - HA Cluster Daemon Copyright (C) 2017-2020 Andrew Zak <andrew@linux.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
PulseHA - HA Cluster Daemon Copyright (C) 2017-2020 Andrew Zak <andrew@linux.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
PulseHA - HA Cluster Daemon Copyright (C) 2017-2020 Andrew Zak <andrew@linux.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
PulseHA - HA Cluster Daemon Copyright (C) 2017-2020 Andrew Zak <andrew@linux.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
PulseHA - HA Cluster Daemon Copyright (C) 2017-2020 Andrew Zak <andrew@linux.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
PulseHA - HA Cluster Daemon Copyright (C) 2017-2020 Andrew Zak <andrew@linux.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
PulseHA - HA Cluster Daemon Copyright (C) 2017-2020 Andrew Zak <andrew@linux.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
Index ¶
- Constants
- Variables
- func BringDownIPs(iface string, ips []string) error
- func BringUpIPs(iface string, ips []string) error
- func CanCommunicate(ctx context.Context) bool
- func GetFailOverCountWinner(members []*rpc.MemberlistMember) string
- func InformMLSChange()
- func MakeLocalActive() error
- func MakeLocalPassive()
- func MyCaller() string
- type CLIServer
- func (s *CLIServer) Config(ctx context.Context, in *rpc.PulseConfig) (*rpc.PulseConfig, error)
- func (s *CLIServer) Create(ctx context.Context, in *rpc.PulseCreate) (*rpc.PulseCreate, error)
- func (s *CLIServer) DeleteGroup(ctx context.Context, in *rpc.PulseGroupDelete) (*rpc.PulseGroupDelete, error)
- func (s *CLIServer) Describe(ctx context.Context, in *rpc.PulseDescribe) (*rpc.PulseDescribe, error)
- func (s *CLIServer) GroupAssign(ctx context.Context, in *rpc.PulseGroupAssign) (*rpc.PulseGroupAssign, error)
- func (s *CLIServer) GroupIPAdd(ctx context.Context, in *rpc.PulseGroupAdd) (*rpc.PulseGroupAdd, error)
- func (s *CLIServer) GroupIPRemove(ctx context.Context, in *rpc.PulseGroupRemove) (*rpc.PulseGroupRemove, error)
- func (s *CLIServer) GroupList(ctx context.Context, in *rpc.GroupTable) (*rpc.GroupTable, error)
- func (s *CLIServer) GroupUnassign(ctx context.Context, in *rpc.PulseGroupUnassign) (*rpc.PulseGroupUnassign, error)
- func (s *CLIServer) Join(ctx context.Context, in *rpc.PulseJoin) (*rpc.PulseJoin, error)
- func (s *CLIServer) Leave(ctx context.Context, in *rpc.PulseLeave) (*rpc.PulseLeave, error)
- func (s *CLIServer) Network(ctx context.Context, in *rpc.PulseNetwork) (*rpc.PulseNetwork, error)
- func (s *CLIServer) NewGroup(ctx context.Context, in *rpc.PulseGroupNew) (*rpc.PulseGroupNew, error)
- func (s *CLIServer) Promote(ctx context.Context, in *rpc.PulsePromote) (*rpc.PulsePromote, error)
- func (s *CLIServer) Remove(ctx context.Context, in *rpc.PulseRemove) (*rpc.PulseRemove, error)
- func (s *CLIServer) Setup()
- func (s *CLIServer) Status(ctx context.Context, in *rpc.PulseStatus) (*rpc.PulseStatus, error)
- func (s *CLIServer) TLS(ctx context.Context, in *rpc.PulseCert) (*rpc.PulseCert, error)
- func (s *CLIServer) Token(ctx context.Context, in *rpc.PulseToken) (*rpc.PulseToken, error)
- type Database
- type Member
- func (m *Member) BringUpIPs(ips []string, group string) bool
- func (m *Member) Close()
- func (m *Member) Connect() error
- func (m *Member) GetHCBusy() bool
- func (m *Member) GetHostname() string
- func (m *Member) GetLastHCResponse() time.Time
- func (m *Member) GetLatency() string
- func (m *Member) GetStatus() rpc.MemberStatus_Status
- func (m *Member) Lock()
- func (m *Member) MakeActive() bool
- func (m *Member) MakePassive() error
- func (m *Member) MonitorReceivedHCs() bool
- func (m *Member) RoutineHC(data *rpc.PulseHealthCheck)
- func (m *Member) SendHealthCheck(data *rpc.PulseHealthCheck) (interface{}, error)
- func (m *Member) SetClient(client *client.Client)
- func (m *Member) SetHCBusy(busy bool)
- func (m *Member) SetHostname(hostname string)
- func (m *Member) SetLastHCResponse(time time.Time)
- func (m *Member) SetLatency(latency string)
- func (m *Member) SetStatus(status rpc.MemberStatus_Status)
- func (m *Member) Unlock()
- type MemberList
- func (m *MemberList) AddHealthCheckHandler() bool
- func (m *MemberList) AddMember(hostname string, client *client.Client)
- func (m *MemberList) Broadcast(funcName client.ProtoFunction, data interface{})
- func (m *MemberList) GetActiveMember() (string, *Member)
- func (m *MemberList) GetLocalMember() (*Member, error)
- func (m *MemberList) GetMemberByHostname(hostname string) *Member
- func (m *MemberList) GetNextActiveMember() (*Member, error)
- func (m *MemberList) LoadMembers()
- func (m *MemberList) Lock()
- func (m *MemberList) MemberExists(hostname string) bool
- func (m *MemberList) MemberGetStatus(hostname string) (rpc.MemberStatus_Status, error)
- func (m *MemberList) MemberRemoveByHostname(hostname string)
- func (m *MemberList) MonitorClientConns() bool
- func (m *MemberList) PromoteMember(hostname string) error
- func (m *MemberList) Reload()
- func (m *MemberList) Reset()
- func (m *MemberList) Setup()
- func (m *MemberList) SyncConfig() error
- func (m *MemberList) Unlock()
- func (m *MemberList) Update(memberlist []*rpc.MemberlistMember)
- type Plugin
- type PluginGen
- type PluginHC
- type PluginNet
- type Plugins
- type Server
- func (s *Server) BringDownIP(ctx context.Context, in *rpc.PulseBringIP) (*rpc.PulseBringIP, error)
- func (s *Server) BringUpIP(ctx context.Context, in *rpc.PulseBringIP) (*rpc.PulseBringIP, error)
- func (s *Server) ConfigSync(ctx context.Context, in *rpc.PulseConfigSync) (*rpc.PulseConfigSync, error)
- func (s *Server) Describe(ctx context.Context, in *rpc.PulseDescribe) (*rpc.PulseDescribe, error)
- func (s *Server) HealthCheck(ctx context.Context, in *rpc.PulseHealthCheck) (*rpc.PulseHealthCheck, error)
- func (s *Server) Init(db *Database)
- func (s *Server) Join(ctx context.Context, in *rpc.PulseJoin) (*rpc.PulseJoin, error)
- func (s *Server) Leave(ctx context.Context, in *rpc.PulseLeave) (*rpc.PulseLeave, error)
- func (s *Server) Logs(ctx context.Context, in *rpc.PulseLogs) (*rpc.PulseLogs, error)
- func (s *Server) MakePassive(ctx context.Context, in *rpc.PulsePromote) (*rpc.PulsePromote, error)
- func (s *Server) Promote(ctx context.Context, in *rpc.PulsePromote) (*rpc.PulsePromote, error)
- func (s *Server) Remove(ctx context.Context, in *rpc.PulseRemove) (*rpc.PulseRemove, error)
- func (s *Server) Setup()
- func (s *Server) Shutdown()
Constants ¶
const ( PluginHealthCheck pluginType = 1 + iota PluginNetworking PluginGeneral )
Variables ¶
var (
CLUSTER_REQUIRED_MESSAGE = "You must be in a configured cluster to complete this action."
)
Functions ¶
func BringDownIPs ¶
* Bring down an []ips for a specific interface
func BringUpIPs ¶
* Bring up an []ips for a specific interface
func CanCommunicate ¶
* Determine if a connection is coming in is a member of our config
func GetFailOverCountWinner ¶
func GetFailOverCountWinner(members []*rpc.MemberlistMember) string
* Determine who is the correct active node if more than one active is brought online
func InformMLSChange ¶
func InformMLSChange()
* Inform our plugins that our member list state has changed
func MakeLocalActive ¶
func MakeLocalActive() error
* Networking - Bring up the groups on the current node
func MakeLocalPassive ¶
func MakeLocalPassive()
* Networking - Bring down the ip groups on the current node
Types ¶
type CLIServer ¶
* Server struct type
func (*CLIServer) Config ¶
func (s *CLIServer) Config(ctx context.Context, in *rpc.PulseConfig) (*rpc.PulseConfig, error)
Config - Update any key's value in the pulseha section of the config
func (*CLIServer) Create ¶
func (s *CLIServer) Create(ctx context.Context, in *rpc.PulseCreate) (*rpc.PulseCreate, error)
* Create new PulseHA cluster
func (*CLIServer) DeleteGroup ¶
func (s *CLIServer) DeleteGroup(ctx context.Context, in *rpc.PulseGroupDelete) (*rpc.PulseGroupDelete, error)
* Delete floating IP group
func (*CLIServer) Describe ¶
func (s *CLIServer) Describe(ctx context.Context, in *rpc.PulseDescribe) (*rpc.PulseDescribe, error)
func (*CLIServer) GroupAssign ¶
func (s *CLIServer) GroupAssign(ctx context.Context, in *rpc.PulseGroupAssign) (*rpc.PulseGroupAssign, error)
* Assign group to interface
func (*CLIServer) GroupIPAdd ¶
func (s *CLIServer) GroupIPAdd(ctx context.Context, in *rpc.PulseGroupAdd) (*rpc.PulseGroupAdd, error)
* Add IP to group
func (*CLIServer) GroupIPRemove ¶
func (s *CLIServer) GroupIPRemove(ctx context.Context, in *rpc.PulseGroupRemove) (*rpc.PulseGroupRemove, error)
* Remove IP from group
func (*CLIServer) GroupList ¶
func (s *CLIServer) GroupList(ctx context.Context, in *rpc.GroupTable) (*rpc.GroupTable, error)
* Show all groups
func (*CLIServer) GroupUnassign ¶
func (s *CLIServer) GroupUnassign(ctx context.Context, in *rpc.PulseGroupUnassign) (*rpc.PulseGroupUnassign, error)
* Unassign group from interface
func (*CLIServer) Join ¶
* Attempt to join a configured cluster Notes: We create a new client in attempt to communicate with our peer.
If successful we acknowledge it and update our memberlist.
func (*CLIServer) Leave ¶
func (s *CLIServer) Leave(ctx context.Context, in *rpc.PulseLeave) (*rpc.PulseLeave, error)
* Break cluster / Leave from cluster TODO: Remember to reassign active role on leave
func (*CLIServer) Network ¶
func (s *CLIServer) Network(ctx context.Context, in *rpc.PulseNetwork) (*rpc.PulseNetwork, error)
Network -
func (*CLIServer) NewGroup ¶
func (s *CLIServer) NewGroup(ctx context.Context, in *rpc.PulseGroupNew) (*rpc.PulseGroupNew, error)
* Add a new floating IP group
func (*CLIServer) Promote ¶
func (s *CLIServer) Promote(ctx context.Context, in *rpc.PulsePromote) (*rpc.PulsePromote, error)
* Handle CLI promote request
func (*CLIServer) Remove ¶
func (s *CLIServer) Remove(ctx context.Context, in *rpc.PulseRemove) (*rpc.PulseRemove, error)
Remove - Remove node from cluster by hostname
func (*CLIServer) Status ¶
func (s *CLIServer) Status(ctx context.Context, in *rpc.PulseStatus) (*rpc.PulseStatus, error)
* Return the status for each node within the cluster
func (*CLIServer) Token ¶
func (s *CLIServer) Token(ctx context.Context, in *rpc.PulseToken) (*rpc.PulseToken, error)
Token - Generate a new cluster token
type Database ¶
type Database struct { Config *config.Config Plugins *Plugins MemberList *MemberList Logging logging.Logging StartDelay bool StartInterval int }
var (
DB *Database
)
type Member ¶
type Member struct { // The hostname of the repented node Hostname string // The status of the local member Status rpc.MemberStatus_Status // The last time a health check was received LastHCResponse time.Time // The latency between the active and the current passive member Latency string // Determines if the health check is being made. HCBusy bool // The client for the member that is used to send GRPC calls *client.Client // The mutex to lock the member object sync.Mutex }
* Member struct type
func (*Member) BringUpIPs ¶
* Used to bring up a single IP on member Note: We need to know the group to work out what interface to bring it up on. TODO: Return an error instead of a boolean
func (*Member) Connect ¶
* Note: Hostname is required for TLS as the certs are named after the hostname.
func (*Member) GetLastHCResponse ¶
* Get the last time this member received a health check
func (*Member) MakeActive ¶
Make the node active (bring up its groups)
func (*Member) MakePassive ¶
* Make the node passive (take down its groups)
func (*Member) MonitorReceivedHCs ¶
* Monitor the last time we received a health check and or failover
func (*Member) RoutineHC ¶
func (m *Member) RoutineHC(data *rpc.PulseHealthCheck)
* Send health check via a go routine and mark the HC busy/not
func (*Member) SendHealthCheck ¶
func (m *Member) SendHealthCheck(data *rpc.PulseHealthCheck) (interface{}, error)
* Active function - Send GRPC health check to current member
func (*Member) SetStatus ¶
func (m *Member) SetStatus(status rpc.MemberStatus_Status)
* Set member status
type MemberList ¶
*
- MemberList struct type
func (*MemberList) AddHealthCheckHandler ¶
func (m *MemberList) AddHealthCheckHandler() bool
* Send health checks to users who have a healthy connection
func (*MemberList) AddMember ¶
func (m *MemberList) AddMember(hostname string, client *client.Client)
*
- Add a member to the client list
func (*MemberList) Broadcast ¶
func (m *MemberList) Broadcast(funcName client.ProtoFunction, data interface{})
*
- Attempt to broadcast a client function to other nodes (clients) within the memberlist
func (*MemberList) GetActiveMember ¶
func (m *MemberList) GetActiveMember() (string, *Member)
Return the hostname of the active member or empty string if non are active
func (*MemberList) GetLocalMember ¶
func (m *MemberList) GetLocalMember() (*Member, error)
*
Get the local member node
func (*MemberList) GetMemberByHostname ¶
func (m *MemberList) GetMemberByHostname(hostname string) *Member
*
- Return Member by hostname
func (*MemberList) GetNextActiveMember ¶
func (m *MemberList) GetNextActiveMember() (*Member, error)
* Calculate who's next to become active in the memberlist
func (*MemberList) LoadMembers ¶
func (m *MemberList) LoadMembers()
* load the nodes in our config into our memberlist
func (*MemberList) MemberExists ¶
func (m *MemberList) MemberExists(hostname string) bool
*
- Return true/false whether a member exists or not.
func (*MemberList) MemberGetStatus ¶
func (m *MemberList) MemberGetStatus(hostname string) (rpc.MemberStatus_Status, error)
* Get status of a specific member by hostname
func (*MemberList) MemberRemoveByHostname ¶
func (m *MemberList) MemberRemoveByHostname(hostname string)
*
- Remove a member from the client list by hostname
func (*MemberList) MonitorClientConns ¶
func (m *MemberList) MonitorClientConns() bool
*
Function is only to be run on the active appliance Note: THis is not the final function name.. or not sure if this is where this logic will stay.. just playing around at this point. monitors the connections states for each member
func (*MemberList) PromoteMember ¶
func (m *MemberList) PromoteMember(hostname string) error
* Promote a member within the memberlist to become the active node
func (*MemberList) Reset ¶
func (m *MemberList) Reset()
* Reset the memberlist when we are no longer in a cluster.
func (*MemberList) SyncConfig ¶
func (m *MemberList) SyncConfig() error
* Sync local config with each member in the cluster.
func (*MemberList) Update ¶
func (m *MemberList) Update(memberlist []*rpc.MemberlistMember)
* Update the local memberlist statuses based on the proto memberlist message
type PluginNet ¶
type PluginNet interface { Name() string Version() float64 BringUpIPs(iface string, ips []string) error BringDownIPs(iface string, ips []string) error }
* Networking plugin type
type Plugins ¶
type Plugins struct {
// contains filtered or unexported fields
}
* Plugins struct
func (*Plugins) GetGeneralPlugin ¶
* Returns a slice of general plugins
func (*Plugins) GetHealthCheckPlugins ¶
* Returns a slice of health check plugins
func (*Plugins) GetNetworkingPlugin ¶
* Returns a single networking plugin (as you should only ever have one loaded)
type Server ¶
*
- Server struct type
func (*Server) BringDownIP ¶
func (s *Server) BringDownIP(ctx context.Context, in *rpc.PulseBringIP) (*rpc.PulseBringIP, error)
*
func (*Server) BringUpIP ¶
func (s *Server) BringUpIP(ctx context.Context, in *rpc.PulseBringIP) (*rpc.PulseBringIP, error)
*
func (*Server) ConfigSync ¶
func (s *Server) ConfigSync(ctx context.Context, in *rpc.PulseConfigSync) (*rpc.PulseConfigSync, error)
* Update our local config from a Resync request
func (*Server) Describe ¶
func (s *Server) Describe(ctx context.Context, in *rpc.PulseDescribe) (*rpc.PulseDescribe, error)
func (*Server) HealthCheck ¶
func (s *Server) HealthCheck(ctx context.Context, in *rpc.PulseHealthCheck) (*rpc.PulseHealthCheck, error)
* Perform appr. health checks
func (*Server) Leave ¶
func (s *Server) Leave(ctx context.Context, in *rpc.PulseLeave) (*rpc.PulseLeave, error)
* Update our local config from a Resync request
func (*Server) MakePassive ¶
func (s *Server) MakePassive(ctx context.Context, in *rpc.PulsePromote) (*rpc.PulsePromote, error)
* Make a member passive
func (*Server) Promote ¶
func (s *Server) Promote(ctx context.Context, in *rpc.PulsePromote) (*rpc.PulsePromote, error)
* Network action functions
func (*Server) Remove ¶
func (s *Server) Remove(ctx context.Context, in *rpc.PulseRemove) (*rpc.PulseRemove, error)
Remove - Remove node from cluster by hostname