diff --git a/pkg/plugin/builder.go b/pkg/plugin/builder.go index fe5350e..0ee29fd 100644 --- a/pkg/plugin/builder.go +++ b/pkg/plugin/builder.go @@ -14,6 +14,7 @@ type Looper interface { BuildContainerSpec(container v1.Container, info BuilderInformation) ([][]Cell, error) BuildEphemeralContainerSpec(container v1.EphemeralContainer, info BuilderInformation) ([][]Cell, error) BuildContainerStatus(container v1.ContainerStatus, info BuilderInformation) ([][]Cell, error) + BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) Headers() []string HideColumns(info BuilderInformation) []int } @@ -36,6 +37,7 @@ type RowBuilder struct { ShowInitContainers bool ShowContainerType bool ShowNodeTree bool // show the tree view with the nodes at the root level rather than just the resource sets at root + DontListContainers bool // dont loop through containers, only the main pod FilterList map[string]matchValue // used to filter out rows from the table during Print function CalcFiltered bool // the filterd out rows are included in the branch calculations DefaultHeaderLen int @@ -344,7 +346,7 @@ func (b *RowBuilder) setValuesAnnotationLabel(pod v1.Pod) { } func (b *RowBuilder) populateAnnotationsLabels(podList []v1.Pod) error { - log := logger{location: "RowBuilder:BuildContainerTable"} + log := logger{location: "RowBuilder:populateAnnotationsLabels"} log.Debug("Start") // type kind pod label value b.annotationLabel = make(map[string]map[string]map[string]map[string]string) @@ -567,6 +569,9 @@ func (b *RowBuilder) setVisibleColumns(info *BuilderInformation) { b.Table.HideColumn(3) } + if b.DontListContainers { + b.Table.HideColumn(4) + } } // PodLoop given a pod we loop over all containers adding to the table as we go @@ -578,6 +583,26 @@ func (b *RowBuilder) podLoop(loop Looper, info BuilderInformation, pod v1.Pod, i log := logger{location: "RowBuilder:PodLoop"} log.Debug("Start") + if b.DontListContainers { + log.Debug("skipping containers") + info.ContainerType = TypeIDPod + info.TypeName = TypeNamePod + + allRows, err := loop.BuildPodRow(pod, info) + if err != nil { + return [][]Cell{}, err + } + for _, row := range allRows { + rowsOut := b.makeFullRow(&info, indentLevel, row) + if !b.matchShouldExclude(rowsOut) { + b.Table.AddRow(rowsOut...) + } + } + podRowsOut = append(podRowsOut, allRows...) + + return podRowsOut, nil + } + if b.ShowInitContainers { log.Debug("loop init Container") info.ContainerType = TypeIDInitContainer @@ -795,6 +820,10 @@ func (b *RowBuilder) getDefaultHead(info *BuilderInformation) []string { headList = []string{ "T", "NAMESPACE", "NODE", } + // } else if b.DontListContainers { + // headList = []string{ + // "T", "NAMESPACE", "NODE", "PODNAME", + // } } else { headList = []string{ "T", "NAMESPACE", "NODE", "PODNAME", "CONTAINER", diff --git a/pkg/plugin/capabilities.go b/pkg/plugin/capabilities.go index 2f5c31a..ce565ca 100644 --- a/pkg/plugin/capabilities.go +++ b/pkg/plugin/capabilities.go @@ -154,3 +154,7 @@ func (s *capabilities) capabilitiesBuildRow(securityContext *v1.SecurityContext, return cellList } + +func (s *capabilities) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +} diff --git a/pkg/plugin/commands.go b/pkg/plugin/commands.go index 581a10d..3d82b5d 100644 --- a/pkg/plugin/commands.go +++ b/pkg/plugin/commands.go @@ -146,3 +146,7 @@ func (s *commands) commandsBuildRow(cmdLine commandLine, info BuilderInformation return cellList } + +func (s *commands) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +} diff --git a/pkg/plugin/environment.go b/pkg/plugin/environment.go index 0382d05..716f07e 100644 --- a/pkg/plugin/environment.go +++ b/pkg/plugin/environment.go @@ -201,3 +201,7 @@ func (s *environment) buildEnvFromEphemeral(container v1.EphemeralContainer) []v } return container.Env } + +func (s *environment) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +} diff --git a/pkg/plugin/image.go b/pkg/plugin/image.go index 60a3fbf..f7e8487 100644 --- a/pkg/plugin/image.go +++ b/pkg/plugin/image.go @@ -201,3 +201,7 @@ func (s *image) imageBuildRow(info BuilderInformation, imageName string, pullPol return cellList } + +func (s *image) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +} diff --git a/pkg/plugin/ip.go b/pkg/plugin/ip.go index dcdced6..4aafb67 100644 --- a/pkg/plugin/ip.go +++ b/pkg/plugin/ip.go @@ -1,10 +1,5 @@ package plugin -import ( - "github.com/spf13/cobra" - "k8s.io/cli-runtime/pkg/genericclioptions" -) - var ipShort = "List ip addresses of all pods in the namespace listed" var ipDescription = ` Prints the known IP addresses of the specified pod(s). if no pod is specified the IP address of @@ -25,48 +20,4 @@ var ipExample = ` # List IP address of pods # List IP address of all pods where the pod label app is either web or mail %[1]s ip -l "app in (web,mail)"` -func IP(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args []string) error { - var podname []string - - connect := Connector{} - if err := connect.LoadConfig(kubeFlags); err != nil { - return err - } - - // if a single pod is selected we dont need to show its name - if len(args) >= 1 { - podname = args - } - commonFlagList, err := processCommonFlags(cmd) - if err != nil { - return err - } - connect.Flags = commonFlagList - - podList, err := connect.GetPods(podname) - if err != nil { - return err - } - table := Table{} - table.ColourOutput = commonFlagList.outputAsColour - table.CustomColours = commonFlagList.useTheseColours - table.SetHeader( - "NAME", "IP", - ) - - for _, pod := range podList { - - table.AddRow( - NewCellText(pod.Name), - NewCellText(pod.Status.PodIP), - ) - } - - if err := table.SortByNames(commonFlagList.sortList...); err != nil { - return err - } - - outputTableAs(table, commonFlagList.outputAs) - return nil - -} +// IP subcommand now points to ports command with useIP bool set to true diff --git a/pkg/plugin/lifecycle.go b/pkg/plugin/lifecycle.go index 8c6bc47..a846378 100644 --- a/pkg/plugin/lifecycle.go +++ b/pkg/plugin/lifecycle.go @@ -211,3 +211,7 @@ func (s *lifecycle) buildLifecycleAction(lifecycle *v1.LifecycleHandler) lifecyc return lifecycleAction{} } + +func (s *lifecycle) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +} diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go index 9b5a08f..80fbf18 100644 --- a/pkg/plugin/plugin.go +++ b/pkg/plugin/plugin.go @@ -50,6 +50,9 @@ func InitSubCommands(rootCmd *cobra.Command) { var includeInitShort string = "include init container(s) in the output, by default init containers are hidden" var odditiesShort string = "show only the outlier rows that dont fall within the computed range" var sizeShort string = "allows conversion to the selected size rather then the default megabyte output" + var treeShort string = "Display tree like view instead of the standard list" + var nodetreeShort string = "Displays the tree with the nodes as the root" + var showIPShort string = "Show the pods IP address column" // var treeShort string = "Display tree like view instead of the standard list" log := logger{location: "InitSubCommands"} @@ -75,6 +78,8 @@ func InitSubCommands(rootCmd *cobra.Command) { }, } KubernetesConfigFlags.AddFlags(cmdCapabilities.Flags()) + cmdCapabilities.Flags().BoolP("tree", "t", false, treeShort) + cmdCapabilities.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdCapabilities) rootCmd.AddCommand(cmdCapabilities) @@ -95,6 +100,8 @@ func InitSubCommands(rootCmd *cobra.Command) { }, } KubernetesConfigFlags.AddFlags(cmdCommands.Flags()) + cmdCommands.Flags().BoolP("tree", "t", false, treeShort) + cmdCommands.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdCommands) rootCmd.AddCommand(cmdCommands) @@ -117,6 +124,8 @@ func InitSubCommands(rootCmd *cobra.Command) { cmdCPU.Flags().BoolP("include-init", "i", false, includeInitShort) cmdCPU.Flags().BoolP("oddities", "", false, odditiesShort) cmdCPU.Flags().BoolP("raw", "r", false, "show raw values") + cmdCPU.Flags().BoolP("tree", "t", false, treeShort) + cmdCPU.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdCPU) rootCmd.AddCommand(cmdCPU) @@ -138,6 +147,8 @@ func InitSubCommands(rootCmd *cobra.Command) { } KubernetesConfigFlags.AddFlags(cmdEnvironment.Flags()) cmdEnvironment.Flags().BoolP("translate", "", false, "read the configmap show its values") + cmdEnvironment.Flags().BoolP("tree", "t", false, treeShort) + cmdEnvironment.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdEnvironment) rootCmd.AddCommand(cmdEnvironment) @@ -149,7 +160,7 @@ func InitSubCommands(rootCmd *cobra.Command) { Example: fmt.Sprintf(ipExample, rootCmd.CommandPath()), // SuggestFor: []string{""}, RunE: func(cmd *cobra.Command, args []string) error { - if err := IP(cmd, KubernetesConfigFlags, args); err != nil { + if err := Ports(cmd, KubernetesConfigFlags, args, true); err != nil { return err } @@ -178,6 +189,8 @@ func InitSubCommands(rootCmd *cobra.Command) { } KubernetesConfigFlags.AddFlags(cmdImage.Flags()) cmdImage.Flags().BoolP("id", "", false, "Show running containers id") + cmdImage.Flags().BoolP("tree", "t", false, treeShort) + cmdImage.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdImage) rootCmd.AddCommand(cmdImage) @@ -198,6 +211,8 @@ func InitSubCommands(rootCmd *cobra.Command) { }, } KubernetesConfigFlags.AddFlags(cmdLifecycle.Flags()) + cmdLifecycle.Flags().BoolP("tree", "t", false, treeShort) + cmdLifecycle.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdLifecycle) rootCmd.AddCommand(cmdLifecycle) @@ -223,6 +238,8 @@ func InitSubCommands(rootCmd *cobra.Command) { cmdMemory.Flags().BoolP("oddities", "", false, odditiesShort) cmdMemory.Flags().BoolP("raw", "r", false, "show raw values") cmdMemory.Flags().String("size", "Mi", sizeShort) + cmdMemory.Flags().BoolP("tree", "t", false, treeShort) + cmdMemory.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdMemory) rootCmd.AddCommand(cmdMemory) @@ -235,7 +252,7 @@ func InitSubCommands(rootCmd *cobra.Command) { Aliases: []string{"port", "po"}, // SuggestFor: []string{""}, RunE: func(cmd *cobra.Command, args []string) error { - if err := Ports(cmd, KubernetesConfigFlags, args); err != nil { + if err := Ports(cmd, KubernetesConfigFlags, args, false); err != nil { return err } @@ -243,6 +260,9 @@ func InitSubCommands(rootCmd *cobra.Command) { }, } KubernetesConfigFlags.AddFlags(cmdPorts.Flags()) + cmdPorts.Flags().BoolP("tree", "t", false, treeShort) + cmdPorts.Flags().BoolP("node-tree", "", false, nodetreeShort) + cmdPorts.Flags().BoolP("show-ip", "", false, showIPShort) addCommonFlags(cmdPorts) rootCmd.AddCommand(cmdPorts) @@ -263,6 +283,8 @@ func InitSubCommands(rootCmd *cobra.Command) { }, } KubernetesConfigFlags.AddFlags(cmdProbes.Flags()) + cmdProbes.Flags().BoolP("tree", "t", false, treeShort) + cmdProbes.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdProbes) rootCmd.AddCommand(cmdProbes) @@ -285,6 +307,8 @@ func InitSubCommands(rootCmd *cobra.Command) { } KubernetesConfigFlags.AddFlags(cmdRestart.Flags()) cmdRestart.Flags().BoolP("oddities", "", false, odditiesShort) + cmdRestart.Flags().BoolP("tree", "t", false, treeShort) + cmdRestart.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdRestart) rootCmd.AddCommand(cmdRestart) @@ -306,6 +330,8 @@ func InitSubCommands(rootCmd *cobra.Command) { } KubernetesConfigFlags.AddFlags(cmdSecurity.Flags()) cmdSecurity.Flags().BoolP("selinux", "", false, "show the SELinux context thats applied to the containers") + cmdSecurity.Flags().BoolP("tree", "t", false, treeShort) + cmdSecurity.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdSecurity) rootCmd.AddCommand(cmdSecurity) @@ -333,6 +359,8 @@ func InitSubCommands(rootCmd *cobra.Command) { cmdStatus.Flags().BoolP("oddities", "", false, odditiesShort) cmdStatus.Flags().BoolP("previous", "p", false, "Show previous state") cmdStatus.Flags().BoolP("id", "", false, "Show running containers id") + cmdStatus.Flags().BoolP("tree", "t", false, treeShort) + cmdStatus.Flags().BoolP("node-tree", "", false, nodetreeShort) // TODO: check if I can add labels for service/replicaset/configmap etc. addCommonFlags(cmdStatus) rootCmd.AddCommand(cmdStatus) @@ -366,6 +394,8 @@ func InitSubCommands(rootCmd *cobra.Command) { } KubernetesConfigFlags.AddFlags(cmdVolume.Flags()) cmdVolume.Flags().BoolP("device", "d", false, "show raw block device mappings within a container") + cmdVolume.Flags().BoolP("tree", "t", false, treeShort) + cmdVolume.Flags().BoolP("node-tree", "", false, nodetreeShort) addCommonFlags(cmdVolume) rootCmd.AddCommand(cmdVolume) @@ -385,8 +415,6 @@ func addCommonFlags(cmdObj *cobra.Command) { cmdObj.Flags().BoolP("show-node", "", false, `Show the node name column`) cmdObj.Flags().BoolP("show-type", "T", false, `Show the container type column, where: I=init container, C=container, E=ephemerial container, P=Pod, D=Deployment, R=ReplicaSet, A=DaemonSet, S=StatefulSet, N=Node`) - cmdObj.Flags().BoolP("tree", "t", false, `Display tree like view instead of the standard list`) - cmdObj.Flags().BoolP("node-tree", "", false, `Displayes the tree with the nodes as the root`) cmdObj.Flags().StringP("node-label", "", "", `Show the selected node label as a column`) cmdObj.Flags().StringP("pod-label", "", "", `Show the selected pod label as a column`) cmdObj.Flags().StringP("annotation", "", "", `Show the selected annotation as a column`) diff --git a/pkg/plugin/ports.go b/pkg/plugin/ports.go index a8dbfd6..a3b81a0 100644 --- a/pkg/plugin/ports.go +++ b/pkg/plugin/ports.go @@ -43,15 +43,33 @@ var portsExample = ` # List containers port info from pods # List container port info from all pods where the pod label app is either web or mail %[1]s ports -l "app in (web,mail)"` -func Ports(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args []string) error { +// Ports show the port infor for each container +// +// runip - true = show ip details only +// - false = show all port info except ip info +func Ports(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args []string, runip bool) error { log := logger{location: "Ports"} log.Debug("Start") loopinfo := ports{} builder := RowBuilder{} - builder.LoopSpec = true + + if runip { + builder.DontListContainers = true + loopinfo.DontListContainers = builder.DontListContainers + } + + if cmd.Flag("show-ip") != nil { + if cmd.Flag("show-ip").Value.String() == "true" { + log.Debug("loopinfo.ShowIPAddress = true") + loopinfo.ShowIPAddress = true + } + } + builder.ShowInitContainers = true + builder.LoopSpec = true + builder.PodName = args connect := Connector{} @@ -88,11 +106,13 @@ func Ports(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args [] } type ports struct { + DontListContainers bool + ShowIPAddress bool } func (s *ports) Headers() []string { return []string{ - "PORTNAME", "PORT", "PROTO", "HOSTPORT", + "PORTNAME", "PORT", "PROTO", "HOSTPORT", "IP", } } @@ -105,7 +125,14 @@ func (s *ports) BuildEphemeralContainerStatus(container v1.ContainerStatus, info } func (s *ports) HideColumns(info BuilderInformation) []int { - return []int{} + if s.ShowIPAddress { + return []int{} + } + if s.DontListContainers { + return []int{0, 1, 2, 3} + } else { + return []int{4} + } } func (s *ports) BuildBranch(info BuilderInformation, rows [][]Cell) ([]Cell, error) { @@ -114,6 +141,7 @@ func (s *ports) BuildBranch(info BuilderInformation, rows [][]Cell) ([]Cell, err NewCellText(""), NewCellText(""), NewCellText(""), + NewCellText(""), } return out, nil } @@ -154,6 +182,19 @@ func (s *ports) portsBuildRow(info BuilderInformation, port v1.ContainerPort) [] NewCellInt(fmt.Sprintf("%d", port.ContainerPort), int64(port.ContainerPort)), NewCellText(string(port.Protocol)), hostPort, + NewCellText(info.Data.pod.Status.PodIP), ) return cellList } + +func (s *ports) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + out := make([][]Cell, 1) + out[0] = append([]Cell{}, + NewCellEmpty(), + NewCellEmpty(), + NewCellEmpty(), + NewCellEmpty(), + NewCellText(info.Data.pod.Status.PodIP), + ) + return out, nil +} diff --git a/pkg/plugin/probes.go b/pkg/plugin/probes.go index 621c0cf..770232a 100644 --- a/pkg/plugin/probes.go +++ b/pkg/plugin/probes.go @@ -255,3 +255,7 @@ func (s *probes) buildProbeAction(name string, probe *v1.Probe) []probeAction { return probeList } + +func (s *probes) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +} diff --git a/pkg/plugin/resources.go b/pkg/plugin/resources.go index 4d1c3bb..18c02be 100644 --- a/pkg/plugin/resources.go +++ b/pkg/plugin/resources.go @@ -405,3 +405,7 @@ func (s *resource) podMetrics2Hashtable(stateList []v1beta1.PodMetrics) map[stri } return podState } + +func (s *resource) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +} diff --git a/pkg/plugin/restarts.go b/pkg/plugin/restarts.go index df6e75f..e4ca94b 100644 --- a/pkg/plugin/restarts.go +++ b/pkg/plugin/restarts.go @@ -150,3 +150,7 @@ func (s restarts) restartsBuildRow(info BuilderInformation, restartCount int32) return cellList } + +func (s restarts) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +} diff --git a/pkg/plugin/security.go b/pkg/plugin/security.go index d237683..9c6c8a4 100644 --- a/pkg/plugin/security.go +++ b/pkg/plugin/security.go @@ -286,3 +286,7 @@ func (s *security) seLinuxBuildRow(info BuilderInformation, csc *v1.SecurityCont return cellList } + +func (s *security) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +} diff --git a/pkg/plugin/status.go b/pkg/plugin/status.go index 4761711..85a2754 100644 --- a/pkg/plugin/status.go +++ b/pkg/plugin/status.go @@ -389,3 +389,7 @@ func (s *status) trimStatusMessage(message string, podName string, containerName } return strings.TrimSpace(newMessage) } + +func (s *status) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +} diff --git a/pkg/plugin/volumes.go b/pkg/plugin/volumes.go index b5cf18d..8de62dd 100644 --- a/pkg/plugin/volumes.go +++ b/pkg/plugin/volumes.go @@ -340,3 +340,7 @@ func (s *volumes) mountsBuildRow(mountInfo v1.VolumeDevice) []Cell { return cellList } + +func (s *volumes) BuildPodRow(pod v1.Pod, info BuilderInformation) ([][]Cell, error) { + return [][]Cell{}, nil +}