-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c5a9d8f
commit 99aa666
Showing
8 changed files
with
244 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
package status | ||
|
||
import ( | ||
"fmt" | ||
"net/url" | ||
"os" | ||
|
||
"github.com/andydunstall/kite" | ||
"github.com/andydunstall/pico/status/client" | ||
"github.com/andydunstall/pico/status/config" | ||
yaml "github.com/goccy/go-yaml" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func newGossipCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "gossip", | ||
Short: "inspect gossip state", | ||
} | ||
|
||
cmd.AddCommand(newGossipMembersCommand()) | ||
cmd.AddCommand(newGossipMemberCommand()) | ||
|
||
return cmd | ||
} | ||
|
||
func newGossipMembersCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "members", | ||
Short: "inspect gossip members", | ||
Long: `Inspect gossip members. | ||
Queries the server for the metadata for each known gossip member in the | ||
cluster. | ||
Examples: | ||
pico status gossip members | ||
`, | ||
} | ||
|
||
var conf config.Config | ||
|
||
cmd.Flags().StringVar( | ||
&conf.Server.URL, | ||
"server.url", | ||
"http://localhost:8081", | ||
` | ||
Pico server URL. This URL should point to the server admin port. | ||
`, | ||
) | ||
|
||
cmd.Run = func(cmd *cobra.Command, args []string) { | ||
if err := conf.Validate(); err != nil { | ||
fmt.Printf("invalid config: %s\n", err.Error()) | ||
os.Exit(1) | ||
} | ||
|
||
showGossipMembers(&conf) | ||
} | ||
|
||
return cmd | ||
} | ||
|
||
type gossipMembersOutput struct { | ||
Members []*kite.MemberMeta `json:"members"` | ||
} | ||
|
||
func showGossipMembers(conf *config.Config) { | ||
// The URL has already been validated in conf. | ||
url, _ := url.Parse(conf.Server.URL) | ||
client := client.NewClient(url) | ||
defer client.Close() | ||
|
||
members, err := client.GossipMembers() | ||
if err != nil { | ||
fmt.Printf("failed to get gossip members: %s\n", err.Error()) | ||
os.Exit(1) | ||
} | ||
|
||
output := gossipMembersOutput{ | ||
Members: members, | ||
} | ||
b, _ := yaml.Marshal(output) | ||
fmt.Println(string(b)) | ||
} | ||
|
||
func newGossipMemberCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "member", | ||
Args: cobra.ExactArgs(1), | ||
Short: "inspect a gossip member", | ||
Long: `Inspect a gossip member. | ||
Queries the server for the known state of the gossip member with the given ID. | ||
Examples: | ||
pico status gossip member bbc69214 | ||
`, | ||
} | ||
|
||
var conf config.Config | ||
|
||
cmd.Flags().StringVar( | ||
&conf.Server.URL, | ||
"server.url", | ||
"http://localhost:8081", | ||
` | ||
Pico server URL. This URL should point to the server admin port. | ||
`, | ||
) | ||
|
||
cmd.Run = func(cmd *cobra.Command, args []string) { | ||
if err := conf.Validate(); err != nil { | ||
fmt.Printf("invalid config: %s\n", err.Error()) | ||
os.Exit(1) | ||
} | ||
|
||
showGossipMember(args[0], &conf) | ||
} | ||
|
||
return cmd | ||
} | ||
|
||
func showGossipMember(memberID string, conf *config.Config) { | ||
// The URL has already been validated in conf. | ||
url, _ := url.Parse(conf.Server.URL) | ||
client := client.NewClient(url) | ||
defer client.Close() | ||
|
||
member, err := client.GossipMember(memberID) | ||
if err != nil { | ||
fmt.Printf("failed to get gossip member: %s: %s\n", memberID, err.Error()) | ||
os.Exit(1) | ||
} | ||
|
||
b, _ := yaml.Marshal(member) | ||
fmt.Println(string(b)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package gossip | ||
|
||
import ( | ||
"net/http" | ||
"sort" | ||
|
||
"github.com/andydunstall/kite" | ||
"github.com/andydunstall/pico/server/status" | ||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
type Status struct { | ||
gossip *Gossip | ||
} | ||
|
||
func NewStatus(gossip *Gossip) *Status { | ||
return &Status{ | ||
gossip: gossip, | ||
} | ||
} | ||
|
||
func (s *Status) Register(group *gin.RouterGroup) { | ||
group.GET("/members", s.listMembersRoute) | ||
group.GET("/members/:id", s.getMemberRoute) | ||
} | ||
|
||
func (s *Status) listMembersRoute(c *gin.Context) { | ||
members := s.gossip.MembersMetadata(kite.MemberFilter{ | ||
Local: true, | ||
}) | ||
c.JSON(http.StatusOK, members) | ||
} | ||
|
||
func (s *Status) getMemberRoute(c *gin.Context) { | ||
id := c.Param("id") | ||
state, ok := s.gossip.MemberState(id) | ||
if !ok { | ||
c.Status(http.StatusNotFound) | ||
return | ||
} | ||
|
||
// Sort state by version. | ||
sort.Slice(state.State, func(i, j int) bool { | ||
return state.State[i].Version < state.State[j].Version | ||
}) | ||
|
||
c.JSON(http.StatusOK, state) | ||
} | ||
|
||
var _ status.Handler = &Status{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters