Skip to content

Commit

Permalink
Add liqoctl info command
Browse files Browse the repository at this point in the history
This patch introduces `liqoctl info`command to retrieve the status
of the current Liqo instance, plus some brief info about the
active peerings.
  • Loading branch information
claudiolor authored and adamjensenbot committed Sep 16, 2024
1 parent 4992cda commit 84a08ba
Show file tree
Hide file tree
Showing 21 changed files with 1,893 additions and 12 deletions.
129 changes: 129 additions & 0 deletions cmd/liqoctl/cmd/info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright 2019-2024 The Liqo Authors
//
// 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 (
"context"
"os"

"github.com/spf13/cobra"

"github.com/liqotech/liqo/pkg/liqoctl/completion"
"github.com/liqotech/liqo/pkg/liqoctl/factory"
"github.com/liqotech/liqo/pkg/liqoctl/info"
"github.com/liqotech/liqo/pkg/liqoctl/info/localstatus"
"github.com/liqotech/liqo/pkg/liqoctl/output"
"github.com/liqotech/liqo/pkg/utils/args"
)

var outputFormat = args.NewEnum([]string{"json", "yaml"}, "")

const liqoctlInfoLongHelp = `Show info about the current Liqo instance.
Liqoctl provides a set of commands to verify the status of the Liqo control
plane, its configuration, as well as the characteristics of the currently
active peerings, and reports the outcome in human-readable or
machine-readable format (either JSON or YAML).
Additionally, via '--get', it allows to retrieve each single field of the reports
using a query in dot notation (e.g. '--get field.subfield')
This command shows information about the local cluster and checks the presence
and the sanity of the Liqo namespace and the Liqo pods and some brief info about
the active peerings and their status.
Examples:
$ {{ .Executable }} info
$ {{ .Executable }} info --namespace liqo-system
show the output in YAML format
$ {{ .Executable }} info -o yaml
get a specific field
$ {{ .Executable }} info --get clusterid
$ {{ .Executable }} info --get network.podcidr
`

func infoPreRun(options *info.Options) {
// When the output is redirected to a file is desiderable that errors ends in the stderr output.
options.Printer.Error.Writer = os.Stderr
options.Printer.Warning.Writer = os.Stderr
// Configure output according to the provided parameter
options.Format = info.OutputFormat(outputFormat.Value)
// Force verbose when `get` is used to allow to retrieve also
// the info in the verbose output also when "--verbose" is not provided
if options.GetQuery != "" {
options.Verbose = true
}
}

func newPeerInfoCommand(ctx context.Context, f *factory.Factory, options *info.Options) *cobra.Command {
cmd := &cobra.Command{
Use: "peer",
Short: "Show additional info about one or more specific peerings",
Long: WithTemplate(""),
Args: cobra.MinimumNArgs(1),
ValidArgsFunction: completion.ClusterIDs(ctx, f, completion.NoLimit),

PreRun: func(_ *cobra.Command, _ []string) {
infoPreRun(options)
},

Run: func(_ *cobra.Command, clusterIds []string) {
output.ExitOnErr(options.RunPeerInfo(ctx, clusterIds))
},
}

return cmd
}

func newInfoCommand(ctx context.Context, f *factory.Factory) *cobra.Command {
options := info.NewOptions(f)

maincmd := &cobra.Command{
Use: "info",
Short: "Show info about the current Liqo instance",
Long: WithTemplate(liqoctlInfoLongHelp),
Args: cobra.NoArgs,

PreRun: func(_ *cobra.Command, _ []string) {
infoPreRun(options)
},

Run: func(_ *cobra.Command, _ []string) {
// Set up checkers
checkers := []info.Checker{
&localstatus.InstallationChecker{},
&localstatus.HealthChecker{},
}
if options.Verbose {
checkers = append(checkers, &localstatus.NetworkChecker{})
}
checkers = append(checkers, &localstatus.PeeringChecker{})
output.ExitOnErr(options.RunInfo(ctx, checkers))
},
}

f.AddLiqoNamespaceFlag(maincmd.PersistentFlags())
maincmd.PersistentFlags().BoolVarP(&options.Verbose, "verbose", "v", false, "Make info more verbose")
maincmd.PersistentFlags().VarP(outputFormat, "output", "o", "Output format. Supported formats: json, yaml")
maincmd.PersistentFlags().StringVarP(&options.GetQuery, "get", "g", "",
"Path to the desired subfield in dot notation. Each part of the path corresponds to a key of the output structure")

f.Printer.CheckErr(maincmd.RegisterFlagCompletionFunc(factory.FlagNamespace, completion.Namespaces(ctx, f, completion.NoLimit)))
f.Printer.CheckErr(maincmd.RegisterFlagCompletionFunc("output", completion.Enumeration(outputFormat.Allowed)))

maincmd.AddCommand(newPeerInfoCommand(ctx, f, options))

return maincmd
}
1 change: 1 addition & 0 deletions cmd/liqoctl/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ func NewRootCommand(ctx context.Context) *cobra.Command {
cmd.AddCommand(generate.NewGenerateCommand(ctx, liqoResources, f))
cmd.AddCommand(get.NewGetCommand(ctx, liqoResources, f))
cmd.AddCommand(delete.NewDeleteCommand(ctx, liqoResources, f))
cmd.AddCommand(newInfoCommand(ctx, f))
cmd.AddCommand(newTestCommand(ctx, f))

return cmd
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ require (
sigs.k8s.io/aws-iam-authenticator v0.6.19
sigs.k8s.io/controller-runtime v0.18.5
sigs.k8s.io/sig-storage-lib-external-provisioner/v7 v7.0.1
sigs.k8s.io/yaml v1.4.0
)

require (
Expand Down Expand Up @@ -258,5 +259,4 @@ require (
sigs.k8s.io/kustomize/api v0.16.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.16.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
50 changes: 50 additions & 0 deletions pkg/liqoctl/info/checker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2019-2024 The Liqo Authors
//
// 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 info

import "context"

// Checker is the interface to be implemented by all the checkers that
// collect info about the current instance of Liqo.
type Checker interface {
// Collect the data from the Liqo installation
Collect(ctx context.Context, options Options)
// Return the collected data using a user friendly output
Format(options Options) string
// Get the title of the section retrieve by the checker
GetTitle() string
// Get the id to be shown of machine readable output
GetID() string
// Get the data collected by the checker
GetData() interface{}
// Return the errors occurred during the collection of the data.
GetCollectionErrors() []error
}

// CheckerBase contains the common attributes and functions of the checkers.
type CheckerBase struct {
collectionErrors []error
}

// AddCollectionError adds an error to the list of errors occurred while
// collecting the info about a Liqo component.
func (c *CheckerBase) AddCollectionError(err error) {
c.collectionErrors = append(c.collectionErrors, err)
}

// GetCollectionErrors returns the errors occurred during the collection of the data.
func (c *CheckerBase) GetCollectionErrors() []error {
return c.collectionErrors
}
17 changes: 17 additions & 0 deletions pkg/liqoctl/info/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2019-2024 The Liqo Authors
//
// 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 info contains the logic to show info about the current Liqo instance
package info
100 changes: 100 additions & 0 deletions pkg/liqoctl/info/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2019-2024 The Liqo Authors
//
// 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 info

import (
"context"
"fmt"

"github.com/liqotech/liqo/pkg/liqoctl/factory"
)

// OutputFormat represents the format of the output of the command.
type OutputFormat string

const (
// JSON indicates that the output will be in JSON format.
JSON OutputFormat = "json"
// YAML indicates that the output will be in YAML format.
YAML OutputFormat = "yaml"
)

// LocalInfoQueryShortcuts contains shortcuts for the paths in the local info data.
var LocalInfoQueryShortcuts = map[string]string{
"clusterid": "local.clusterid",
}

// Options encapsulates the arguments of the info command.
type Options struct {
*factory.Factory

Verbose bool
Format OutputFormat
GetQuery string
}

// NewOptions returns a new Options struct.
func NewOptions(f *factory.Factory) *Options {
return &Options{
Factory: f,
}
}

// RunInfo execute the `info` command.
func (o *Options) RunInfo(ctx context.Context, checkers []Checker) error {
// Check whether Liqo is installed in the current cluster
if err := o.installationCheck(ctx); err != nil {
return err
}

// Start collecting the data via the checkers
for i := range checkers {
checkers[i].Collect(ctx, *o)
for _, err := range checkers[i].GetCollectionErrors() {
o.Printer.Warning.Println(err)
}
}

var err error
var output string
switch {
// If no format is specified, format and print a user-friendly output
case o.Format == "" && o.GetQuery == "":
for i := range checkers {
o.Printer.BoxSetTitle(checkers[i].GetTitle())
o.Printer.BoxPrintln(checkers[i].Format(*o))
}
return nil
// If query specified try to retrieve the field from the output
case o.GetQuery != "":
output, err = o.sPrintField(o.GetQuery, checkers, LocalInfoQueryShortcuts)
default:
output, err = o.sPrintMachineReadable(checkers)
}

if err != nil {
o.Printer.Error.Println(err)
} else {
fmt.Println(output)
}

return err
}

// RunPeerInfo execute the `info peer` command.
func (o *Options) RunPeerInfo(_ context.Context, _ []string) error {
panic("Not implemented")
}
17 changes: 17 additions & 0 deletions pkg/liqoctl/info/localstatus/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2019-2024 The Liqo Authors
//
// 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 localstatus contains the logic to retrieve info about the local Liqo instance
package localstatus
Loading

0 comments on commit 84a08ba

Please sign in to comment.