Skip to content

Commit

Permalink
Add support for cluster and node information
Browse files Browse the repository at this point in the history
  • Loading branch information
SaaldjorMike committed Nov 4, 2019
1 parent 6fe03d4 commit 46d04b6
Show file tree
Hide file tree
Showing 9 changed files with 534 additions and 0 deletions.
160 changes: 160 additions & 0 deletions api/cluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package api

import "github.com/shurcooL/graphql"

type Clusters struct {
client *Client
}

type ClusterNode struct {
Id int
Name string
Uri string
Uuid string
ClusterInfoAgeSeconds float64
InboundSegmentSize float64
OutboundSegmentSize float64
StorageDivergence float64
CanBeSafelyUnregistered bool
CurrentSize float64
PrimarySize float64
SecondarySize float64
TotalSizeOfPrimary float64
TotalSizeOfSecondary float64
FreeOnPrimary float64
FreeOnSecondary float64
WipSize float64
TargetSize float64
Reapply_targetSize float64
SolitarySegmentSize float64
IsAvailable bool
LastHeartbeat string
}

type IngestPartition struct {
Id int
NodeIds []int
}

type StoragePartition struct {
Id int
NodeIds []int
}

type Cluster struct {
Nodes []ClusterNode
ClusterInfoAgeSeconds float64
UnderReplicatedSegmentSize float64
OverReplicatedSegmentSize float64
MissingSegmentSize float64
ProperlyReplicatedSegmentSize float64
TargetUnderReplicatedSegmentSize float64
TargetOverReplicatedSegmentSize float64
TargetMissingSegmentSize float64
TargetProperlyReplicatedSegmentSize float64
IngestPartitions []IngestPartition
StoragePartitions []StoragePartition
}

func (c *Client) Clusters() *Clusters { return &Clusters{client: c} }

func (c *Clusters) Get() (Cluster, error) {
var q struct {
Cluster Cluster
}

graphqlErr := c.client.Query(&q, nil)

return q.Cluster, graphqlErr
}

type StoragePartitionInput struct {
ID graphql.Int `json:"id"`
NodeIDs []graphql.Int `json:"nodeIds"`
}

type IngestPartitionInput struct {
ID graphql.Int `json:"id"`
NodeIDs []graphql.Int `json:"nodeIds"`
}

func (c *Clusters) UpdateStoragePartitionScheme(desired []StoragePartitionInput) error {
var m struct {
UpdateStoragePartitionScheme struct {
// We have to make a selection, so just take __typename
Typename graphql.String `graphql:"__typename"`
} `graphql:"updateStoragePartitionScheme(partitions: $partitions)"`
}

variables := map[string]interface{}{
"partitions": desired,
}

graphqlErr := c.client.Mutate(&m, variables)

return graphqlErr
}

func (c *Clusters) UpdateIngestPartitionScheme(desired []IngestPartitionInput) error {
var m struct {
UpdateStoragePartitionScheme struct {
// We have to make a selection, so just take __typename
Typename graphql.String `graphql:"__typename"`
} `graphql:"updateIngestPartitionScheme(partitions: $partitions)"`
}

variables := map[string]interface{}{
"partitions": desired,
}

graphqlErr := c.client.Mutate(&m, variables)

return graphqlErr
}

func (c *Clusters) StartDataRedistribution() error {
var m struct {
StartDataRedistribution struct {
// We have to make a selection, so just take __typename
Typename graphql.String `graphql:"__typename"`
} `graphql:"startDataRedistribution"`
}

graphqlErr := c.client.Mutate(&m, nil)

return graphqlErr
}

func (c *Clusters) ClusterMoveStorageRouteAwayFromNode(nodeID int) error {
var m struct {
ClusterMoveStorageRouteAwayFromNode struct {
// We have to make a selection, so just take __typename
Typename graphql.String `graphql:"__typename"`
} `graphql:"clusterMoveStorageRouteAwayFromNode(nodeID: $id)"`
}

variables := map[string]interface{}{
"id": graphql.Int(nodeID),
}

graphqlErr := c.client.Mutate(&m, variables)

return graphqlErr
}

func (c *Clusters) ClusterMoveIngestRoutesAwayFromNode(nodeID int) error {
var m struct {
ClusterMoveIngestRoutesAwayFromNode struct {
// We have to make a selection, so just take __typename
Typename graphql.String `graphql:"__typename"`
} `graphql:"clusterMoveIngestRoutesAwayFromNode(nodeID: $id)"`
}

variables := map[string]interface{}{
"id": graphql.Int(nodeID),
}

graphqlErr := c.client.Mutate(&m, variables)

return graphqlErr
}
64 changes: 64 additions & 0 deletions api/nodes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package api

import (
"fmt"

"github.com/shurcooL/graphql"
)

type Nodes struct {
client *Client
}

func (n *Client) Nodes() *Nodes { return &Nodes{client: n} }

func (n *Nodes) List() ([]ClusterNode, error) {
var q struct {
Cluster struct {
Nodes []ClusterNode
}
}

graphqlErr := n.client.Query(&q, nil)

return q.Cluster.Nodes, graphqlErr
}

func (n *Nodes) Get(nodeID int) (ClusterNode, error) {
var q struct {
Cluster struct {
Nodes []ClusterNode
}
}

graphqlErr := n.client.Query(&q, nil)
if graphqlErr != nil {
return ClusterNode{}, graphqlErr
}

for _, node := range q.Cluster.Nodes {
if node.Id == nodeID {
return node, nil
}
}

return ClusterNode{}, fmt.Errorf("node id not found in cluster")
}

func (n *Nodes) Unregister(nodeID int64, force bool) error {
var m struct {
ClusterUnregisterNode struct {
// We have to make a selection, so just take __typename
Typename graphql.String `graphql:"__typename"`
} `graphql:"clusterUnregisterNode(force: $force, nodeID: $id)"`
}

variables := map[string]interface{}{
"id": graphql.Int(nodeID),
"force": graphql.Boolean(false),
}

graphqlErr := n.client.Mutate(&m, variables)

return graphqlErr
}
30 changes: 30 additions & 0 deletions cmd/cluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright © 2019 Humio Ltd.
//
// 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
//
// 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 cmd

import (
"github.com/spf13/cobra"
)

func newClusterCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "cluster",
Short: "Manage cluster",
}

cmd.AddCommand(newClusterShowCmd())

return cmd
}
68 changes: 68 additions & 0 deletions cmd/cluster_show.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright © 2019 Humio Ltd.
//
// 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
//
// 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 cmd

import (
"github.com/humio/cli/api"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
)

func newClusterShowCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "show",
Short: "Show the information about the current Humio cluster",
Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
client := NewApiClient(cmd)
cluster, apiErr := client.Clusters().Get()
exitOnError(cmd, apiErr, "error fetching cluster information")
printClusterInfo(cmd, cluster)
cmd.Println()
},
}

return cmd
}

func printClusterInfo(cmd *cobra.Command, cluster api.Cluster) {
cmd.Printf("Cluster information is %.3f seconds old. \nCluster currently consists of %d nodes.\n\n", cluster.ClusterInfoAgeSeconds, len(cluster.Nodes))

header := []string{"Description", "Current", "Target"}
data := [][]string{
[]string{
"Under replicated segment (Size)",
ByteCountDecimal(int64(cluster.UnderReplicatedSegmentSize)),
ByteCountDecimal(int64(cluster.TargetUnderReplicatedSegmentSize))},
[]string{
"Over replicated segment (Size)",
ByteCountDecimal(int64(cluster.OverReplicatedSegmentSize)),
ByteCountDecimal(int64(cluster.TargetOverReplicatedSegmentSize))},
[]string{
"Missing segment (Size)",
ByteCountDecimal(int64(cluster.MissingSegmentSize)),
ByteCountDecimal(int64(cluster.TargetMissingSegmentSize))},
[]string{
"Properly replicated segment (Size)",
ByteCountDecimal(int64(cluster.ProperlyReplicatedSegmentSize)),
ByteCountDecimal(int64(cluster.TargetProperlyReplicatedSegmentSize))},
}

w := tablewriter.NewWriter(cmd.OutOrStdout())
w.AppendBulk(data)
w.SetHeader(header)
w.SetColumnAlignment([]int{tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_LEFT})
w.Render()
}
32 changes: 32 additions & 0 deletions cmd/nodes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright © 2019 Humio Ltd.
//
// 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
//
// 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 cmd

import (
"github.com/spf13/cobra"
)

func newNodesCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "nodes",
Short: "Manage nodes",
}

cmd.AddCommand(newNodesListCmd())
cmd.AddCommand(newNodesShowCmd())
cmd.AddCommand(newNodesUnregisterCmd())

return cmd
}
Loading

0 comments on commit 46d04b6

Please sign in to comment.