mirror of
https://github.com/hanzozt/zt.git
synced 2026-10-30 15:04:55 +00:00
197 lines
5.9 KiB
Go
197 lines
5.9 KiB
Go
/*
|
|
Copyright NetFoundry Inc.
|
|
|
|
Licensed 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
|
|
|
|
https://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 event
|
|
|
|
import (
|
|
"crypto/x509"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
type ClusterEventType string
|
|
|
|
const (
|
|
ClusterEventNS = "cluster"
|
|
|
|
ClusterPeerConnected ClusterEventType = "peer.connected"
|
|
ClusterPeerDisconnected ClusterEventType = "peer.disconnected"
|
|
ClusterMembersChanged ClusterEventType = "members.changed"
|
|
ClusterLeadershipGained ClusterEventType = "leadership.gained"
|
|
ClusterLeadershipLost ClusterEventType = "leadership.lost"
|
|
ClusterHasLeader ClusterEventType = "state.has_leader"
|
|
ClusterIsLeaderless ClusterEventType = "state.is_leaderless"
|
|
ClusterStateReadOnly ClusterEventType = "state.ro"
|
|
ClusterStateReadWrite ClusterEventType = "state.rw"
|
|
ClusterPeerNotMember ClusterEventType = "peer.not_member"
|
|
)
|
|
|
|
// A ClusterPeer represents a controller which is a member of the cluster.
|
|
type ClusterPeer struct {
|
|
// The controller id.
|
|
Id string `json:"id,omitempty"`
|
|
|
|
// The address at which the controller can be reached.
|
|
Addr string `json:"addr,omitempty"`
|
|
|
|
// The version of the controller.
|
|
Version string `json:"version,omitempty"`
|
|
|
|
ServerCert []*x509.Certificate `json:"-"`
|
|
|
|
// The set of api addresses presented by the controller.
|
|
ApiAddresses map[string][]ApiAddress `json:"apiAddresses"`
|
|
}
|
|
|
|
// An ApiAddress represents an endpoint on a controller. This may include things
|
|
// like REST management services and health checks.
|
|
type ApiAddress struct {
|
|
// The URL of the API endpoint.
|
|
Url string `json:"url"`
|
|
|
|
// The version of the API endpoint. Endpoints are versioned independently of
|
|
// the controller version as these are expected to be stable over long periods.
|
|
Version string `json:"version"`
|
|
}
|
|
|
|
func (self *ClusterPeer) String() string {
|
|
return fmt.Sprintf("id=%v addr=%v version=%v", self.Id, self.Addr, self.Version)
|
|
}
|
|
|
|
// A ClusterEvent marks a change to the controller HA cluster.
|
|
// ClusterEvents can be of the following types:
|
|
// - peer.connected - a peer connected
|
|
// - peer.disconnected - a peer disconnected
|
|
// - peer.not_member - a peer connected, but was not a member and didn't join the cluster
|
|
// - members.changed - A peer was added to or removed from the cluster
|
|
// - leadership.gained - The node become the cluster leader
|
|
// - leadership.lost - The node lost cluster leadership
|
|
// - state.has_leader - The cluster gained a leader
|
|
// - state.is_leaderless - The cluster became leaderless
|
|
// - state.ro - The cluster is not accepting state changes, likely due to version mismatches in cluster members
|
|
// - state.rw - The cluster is accepting state changes
|
|
//
|
|
// Example: Cluster Members Changed Event
|
|
//
|
|
// {
|
|
// "namespace": "cluster",
|
|
// "event_src_id": "ctrl1",
|
|
// "timestamp": "2025-01-17T13:41:25.817205826-05:00",
|
|
// "eventType": "members.changed",
|
|
// "index": 7,
|
|
// "peers": [
|
|
// {
|
|
// "id": "ctrl1",
|
|
// "addr": "tls:localhost:6262",
|
|
// "apiAddresses": null
|
|
// },
|
|
// {
|
|
// "id": "ctrl2",
|
|
// "addr": "tls:localhost:6363",
|
|
// "apiAddresses": null
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
// Example: Peer Connected Event
|
|
//
|
|
// {
|
|
// "namespace": "cluster",
|
|
// "event_src_id": "ctrl1",
|
|
// "timestamp": "2025-01-17T13:41:25.838625953-05:00",
|
|
// "eventType": "peer.connected",
|
|
// "peers": [
|
|
// {
|
|
// "id": "ctrl2",
|
|
// "addr": "tls:localhost:6363",
|
|
// "version": "v0.0.0",
|
|
// "apiAddresses": {
|
|
// "edge-client": [
|
|
// {
|
|
// "url": "https://127.0.0.1:1380/edge/client/v1",
|
|
// "version": "v1"
|
|
// }
|
|
// ],
|
|
// "edge-management": [
|
|
// {
|
|
// "url": "https://127.0.0.1:1380/edge/management/v1",
|
|
// "version": "v1"
|
|
// }
|
|
// ],
|
|
// "edge-oidc": [
|
|
// {
|
|
// "url": "https://127.0.0.1:1380/oidc",
|
|
// "version": "v1"
|
|
// }
|
|
// ],
|
|
// "fabric": [
|
|
// {
|
|
// "url": "https://127.0.0.1:1380/fabric/v1",
|
|
// "version": "v1"
|
|
// }
|
|
// ],
|
|
// "health-checks": [
|
|
// {
|
|
// "url": "https://127.0.0.1:1380/health-checks",
|
|
// "version": "v1"
|
|
// }
|
|
// ]
|
|
// }
|
|
// }
|
|
// ]
|
|
// }
|
|
type ClusterEvent struct {
|
|
Namespace string `json:"namespace"`
|
|
EventSrcId string `json:"event_src_id"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
|
|
// The cluster event type. See above for set of valid types.
|
|
EventType ClusterEventType `json:"eventType"`
|
|
|
|
// The raft index associated with the event.
|
|
Index uint64 `json:"index,omitempty"`
|
|
|
|
// This field is populated with all peers when membership change events
|
|
// or leadership is gained. It is populated with the connecting peer for connect events and the
|
|
// disconnecting peer for disconnect events. For other types it is omitted.
|
|
Peers []*ClusterPeer `json:"peers,omitempty"`
|
|
|
|
// The leader id. Only populated for state.has_leader events.
|
|
LeaderId string `json:"leaderId,omitempty"`
|
|
}
|
|
|
|
func (event *ClusterEvent) String() string {
|
|
return fmt.Sprintf("%v.%v time=%v peers=%v", event.Namespace, event.EventType, event.Timestamp, event.Peers)
|
|
}
|
|
|
|
type ClusterEventHandler interface {
|
|
AcceptClusterEvent(event *ClusterEvent)
|
|
}
|
|
|
|
type ClusterEventHandlerF func(event *ClusterEvent)
|
|
|
|
func (f ClusterEventHandlerF) AcceptClusterEvent(event *ClusterEvent) {
|
|
f(event)
|
|
}
|
|
|
|
func NewClusterEvent(eventType ClusterEventType) *ClusterEvent {
|
|
return &ClusterEvent{
|
|
Namespace: ClusterEventNS,
|
|
EventType: eventType,
|
|
Timestamp: time.Now(),
|
|
}
|
|
}
|