-
Notifications
You must be signed in to change notification settings - Fork 21
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
Showing
5 changed files
with
207 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
## gardenctl info | ||
|
||
Get landscape informations and shows the number of shoots per seed, e.g. "gardenctl info" | ||
|
||
``` | ||
gardenctl info [flags] | ||
``` | ||
|
||
### Options | ||
|
||
``` | ||
-h, --help help for info | ||
``` | ||
|
||
### Options inherited from parent commands | ||
|
||
``` | ||
--add-dir-header If true, adds the file directory to the header of the log messages | ||
--alsologtostderr log to standard error as well as files | ||
--config string config file (default is ~/.garden/gardenctl-v2.yaml) | ||
--control-plane target control plane of shoot, use together with shoot argument | ||
--garden string target the given garden cluster | ||
--log-backtrace-at traceLocation when logging hits line file:N, emit a stack trace (default :0) | ||
--log-dir string If non-empty, write log files in this directory | ||
--log-file string If non-empty, use this log file | ||
--log-file-max-size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) | ||
--logtostderr log to standard error instead of files (default true) | ||
--one-output If true, only write logs to their native severity level (vs also writing to each lower severity level) | ||
--project string target the given project | ||
--seed string target the given seed cluster | ||
--shoot string target the given shoot cluster | ||
--skip-headers If true, avoid header prefixes in the log messages | ||
--skip-log-headers If true, avoid headers when opening log files | ||
--stderrthreshold severity logs at or above this threshold go to stderr (default 2) | ||
-v, --v Level number for the log level verbosity | ||
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging | ||
``` | ||
|
||
### SEE ALSO | ||
|
||
* [gardenctl](gardenctl.md) - Gardenctl is a utility to interact with Gardener installations | ||
|
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,26 @@ | ||
/* | ||
SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Gardener contributors | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package info | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/gardener/gardenctl-v2/internal/util" | ||
"github.com/gardener/gardenctl-v2/pkg/cmd/base" | ||
) | ||
|
||
// NewCmdInfo returns a new info command. | ||
func NewCmdInfo(f util.Factory, o *InfoOptions) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "info", | ||
Short: "Get landscape informations and shows the number of shoots per seed, e.g. \"gardenctl info\"", | ||
Args: cobra.NoArgs, | ||
RunE: base.WrapRunE(o, f), | ||
} | ||
|
||
return cmd | ||
} |
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,136 @@ | ||
/* | ||
SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Gardener contributors | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package info | ||
|
||
import ( | ||
"fmt" | ||
"sort" | ||
"strings" | ||
"text/tabwriter" | ||
|
||
"github.com/gardener/gardenctl-v2/internal/util" | ||
"github.com/gardener/gardenctl-v2/pkg/cmd/base" | ||
) | ||
|
||
// InfoOptions is a struct to support Info command | ||
// nolint | ||
type InfoOptions struct { | ||
base.Options | ||
Allocatable int64 | ||
Capacity int64 | ||
} | ||
|
||
// NewInfoOptions returns initialized InfoOptions | ||
func NewInfoOptions(ioStreams util.IOStreams) *InfoOptions { | ||
return &InfoOptions{ | ||
Options: base.Options{ | ||
IOStreams: ioStreams, | ||
}, | ||
} | ||
} | ||
|
||
// Run does the actual work of the command | ||
func (o *InfoOptions) Run(f util.Factory) error { | ||
manager, err := f.Manager() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
infoTarget, err := manager.CurrentTarget() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// create client for the garden cluster | ||
gardenClient, err := manager.GardenClient(infoTarget.GardenName()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
shootList, err := gardenClient.ListShoots(f.Context(), infoTarget.WithShootName("").AsListOption()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
seedList, err := gardenClient.ListSeeds(f.Context(), infoTarget.WithSeedName("").AsListOption()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var ( | ||
unscheduled = 0 | ||
hibernatedShootsCount = 0 | ||
totalShootsCountPerSeed = make(map[string]int) | ||
hibernatedShootsCountPerSeed = make(map[string]int) | ||
unscheduledList = make([]string, 0) | ||
infoOptions = make(map[string]InfoOptions) | ||
valAllocatable int64 | ||
valCapacity int64 | ||
) | ||
|
||
for _, seed := range seedList.Items { | ||
allocatable := seed.Status.Allocatable["shoots"] | ||
capacity := seed.Status.Capacity["shoots"] | ||
|
||
if v, ok := allocatable.AsInt64(); ok { | ||
valAllocatable = v | ||
} else { | ||
return fmt.Errorf("allocatable conversion is not possible") | ||
} | ||
|
||
if v, ok := capacity.AsInt64(); ok { | ||
valCapacity = v | ||
} else { | ||
return fmt.Errorf("capacity conversion is not possible") | ||
} | ||
|
||
infoOptions[seed.Name] = InfoOptions{Allocatable: valAllocatable, Capacity: valCapacity} | ||
} | ||
|
||
for _, shoot := range shootList.Items { | ||
if shoot.Spec.SeedName == nil { | ||
// unscheduledList usually list pending clusters during creation | ||
unscheduledList = append(unscheduledList, shoot.Name) | ||
unscheduled++ | ||
|
||
continue | ||
} | ||
totalShootsCountPerSeed[*shoot.Spec.SeedName]++ | ||
|
||
if shoot.Status.IsHibernated { | ||
hibernatedShootsCountPerSeed[*shoot.Spec.SeedName]++ | ||
hibernatedShootsCount++ | ||
} | ||
} | ||
|
||
var sortedSeeds []string | ||
for seed := range totalShootsCountPerSeed { | ||
sortedSeeds = append(sortedSeeds, seed) | ||
} | ||
|
||
sort.Strings(sortedSeeds) | ||
fmt.Fprintf(o.IOStreams.Out, "Garden: %s\n", infoTarget.GardenName()) | ||
|
||
w := tabwriter.NewWriter(o.IOStreams.Out, 6, 0, 20, ' ', 0) | ||
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", "Seed", "Total", "Active", "Hibernated", "Allocatable", "Capacity") | ||
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", "----", "-----", "------", "----------", "-----------", "--------") | ||
|
||
for _, seed := range sortedSeeds { | ||
if v, found := infoOptions[seed]; found { | ||
fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\t%d\n", seed, totalShootsCountPerSeed[seed], totalShootsCountPerSeed[seed]-hibernatedShootsCountPerSeed[seed], hibernatedShootsCountPerSeed[seed], v.Allocatable, v.Capacity) | ||
} | ||
} | ||
|
||
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", "----", "-----", "------", "----------", "-----------", "--------") | ||
fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%s\t%s\n", "TOTAL", len(shootList.Items), len(shootList.Items)-hibernatedShootsCount-unscheduled, hibernatedShootsCount, "-", "-") | ||
fmt.Fprintf(w, "%s\t%d\n", "Unscheduled", unscheduled) | ||
fmt.Fprintf(w, "%s\t%s\n", "Unscheduled List", strings.Join(unscheduledList, ",")) | ||
fmt.Fprintln(w) | ||
w.Flush() | ||
|
||
return nil | ||
} |