Skip to content

Commit

Permalink
feat: initial implementation of ticket list command
Browse files Browse the repository at this point in the history
  • Loading branch information
nobbs committed Dec 29, 2023
1 parent 083462b commit 8043689
Show file tree
Hide file tree
Showing 15 changed files with 1,006 additions and 0 deletions.
44 changes: 44 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Continous Integration

on:
push:
branches:
- main
pull_request:
branches:
- main

permissions:
contents: read

jobs:
golangci-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
cache: false

- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: latest

test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: ./go.mod

- name: Run tests
run: go test -v ./...
34 changes: 34 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Release Please

on:
push:
branches:
- main
workflow_dispatch:

concurrency:
group: release-please

jobs:
release-please:
name: Release Please

runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Create GitHub App Token
uses: actions/create-github-app-token@v1
id: token
with:
app-id: ${{ secrets.RELEASE_PLEASE_APP_ID }}
private-key: ${{ secrets.RELEASE_PLEASE_PRIVATE_KEY }}

- name: Run Release Please
uses: google-github-actions/release-please-action@v4
with:
token: ${{ steps.token.outputs.token }}
26 changes: 26 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# docs: <https://golangci-lint.run/usage/configuration/>
linters:
enable:
- gofmt
- gci
- errorlint
- dogsled
- nilnil
- gocyclo
- gocognit
- funlen
- dupl
- gocritic

linters-settings:
gocyclo:
min-complexity: 10
gocognit:
min-complexity: 20
funlen:
lines: 120
statements: 120
gofmt:
rewrite-rules:
- pattern: "interface{}"
replacement: "any"
1 change: 1 addition & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
128 changes: 128 additions & 0 deletions cmd/cli/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package cli

import (
"github.com/nobbs/kubectl-mapr-ticket/internal/ticket"
"github.com/spf13/cobra"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericiooptions"
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/client-go/kubernetes"
)

type listOptions struct {
configFlags *genericclioptions.ConfigFlags
IOStreams genericiooptions.IOStreams

AllNamespaces bool

client kubernetes.Interface
}

func NewListOptions(streams genericiooptions.IOStreams) *listOptions {
return &listOptions{
configFlags: genericclioptions.NewConfigFlags(true),
IOStreams: streams,
}
}

func newListCmd(streams genericiooptions.IOStreams) *cobra.Command {
o := NewListOptions(streams)

cmd := &cobra.Command{
Use: "list",
Aliases: []string{"ls"},
Short: "List all secrets containing MapR tickets in the current namespace",
Long: `List all secrets containing MapR tickets in the current namespace and print
some information about them.`,
RunE: func(cmd *cobra.Command, args []string) error {
if err := o.Complete(cmd, args); err != nil {
return err
}

if err := o.Validate(); err != nil {
return err
}

if err := o.Run(cmd, args); err != nil {
return err
}

return nil
},
}

// set IOStreams for the command
cmd.SetIn(o.IOStreams.In)
cmd.SetOut(o.IOStreams.Out)
cmd.SetErr(o.IOStreams.ErrOut)

// add flags
o.configFlags.AddFlags(cmd.Flags())
cmd.Flags().BoolVarP(&o.AllNamespaces, "all-namespaces", "A", false, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")

return cmd
}

func (o *listOptions) Complete(cmd *cobra.Command, args []string) error {
config, err := o.configFlags.ToRESTConfig()
if err != nil {
return err
}

o.client, err = kubernetes.NewForConfig(config)
if err != nil {
return err
}

if o.configFlags.Namespace == nil || *o.configFlags.Namespace == "" {
namespace, err := getNamespace(o.configFlags)
if err != nil {
return err
}

o.configFlags.Namespace = &namespace
}

if o.AllNamespaces {
namespaceAll := metaV1.NamespaceAll
o.configFlags.Namespace = &namespaceAll
}

return nil
}

func (o *listOptions) Validate() error {
return nil
}

func (o *listOptions) Run(cmd *cobra.Command, args []string) error {
secretGetter := o.client.CoreV1().Secrets(*o.configFlags.Namespace)

ticketSecrets, err := ticket.NewList(secretGetter).Run()
if err != nil {
return err
}

// generate table for output
table, err := ticket.GenerateTable(cmd, ticketSecrets)
if err != nil {
return err
}

// print table
printer := printers.NewTablePrinter(printers.PrintOptions{
WithNamespace: o.AllNamespaces,
})
return printer.PrintObj(table, o.IOStreams.Out)
}

// getNamespace returns the namespace from the kubeconfig or the default flag
func getNamespace(flags *genericclioptions.ConfigFlags) (string, error) {
namespace, _, err := flags.ToRawKubeConfigLoader().Namespace()
if err != nil {
return "", err
}

return namespace, nil
}
44 changes: 44 additions & 0 deletions cmd/cli/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package cli

import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
)

type cmdOptions struct {
configFlags *genericclioptions.ConfigFlags
IOStreams genericclioptions.IOStreams
}

func NewCmdOptions(streams genericclioptions.IOStreams) *cmdOptions {
return &cmdOptions{
configFlags: genericclioptions.NewConfigFlags(true),
IOStreams: streams,
}
}

func NewRootCmd(streams genericclioptions.IOStreams) *cobra.Command {
o := NewCmdOptions(streams)

cmd := &cobra.Command{
Use: "kubectl-mapr-ticket",
Short: "A brief description of your application",
Long: `A longer description that spans multiple lines and likely contains examples and usage of using your application.`,
}

// set IOStreams for the command
cmd.SetIn(o.IOStreams.In)
cmd.SetOut(o.IOStreams.Out)
cmd.SetErr(o.IOStreams.ErrOut)

// add flags
o.configFlags.AddFlags(cmd.PersistentFlags())

// add subcommands
cmd.AddCommand(
newListCmd(streams),
newVersionCmd(streams),
)

return cmd
}
45 changes: 45 additions & 0 deletions cmd/cli/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package cli

import (
"github.com/nobbs/kubectl-mapr-ticket/internal/version"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericiooptions"
)

type versionOptions struct {
configFlags *genericclioptions.ConfigFlags
IOStreams genericiooptions.IOStreams
}

func newVersionOptions(streams genericiooptions.IOStreams) *versionOptions {
return &versionOptions{
configFlags: genericclioptions.NewConfigFlags(true),
IOStreams: streams,
}
}

func newVersionCmd(streams genericiooptions.IOStreams) *cobra.Command {
o := newVersionOptions(streams)

cmd := &cobra.Command{
Use: "version",
Aliases: []string{"v"},
Short: "Print the version of kubectl-mapr-ticket and exit",
Run: func(cmd *cobra.Command, args []string) {
o.PrintVersionInfo(cmd)
},
}

// set IOStreams for the command
cmd.SetIn(o.IOStreams.In)
cmd.SetOut(o.IOStreams.Out)
cmd.SetErr(o.IOStreams.ErrOut)

return cmd
}

func (o *versionOptions) PrintVersionInfo(cmd *cobra.Command) {
versionInfo := version.NewVersion()
cmd.Println(versionInfo)
}
21 changes: 21 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package main

import (
"os"

"github.com/nobbs/kubectl-mapr-ticket/cmd/cli"
"github.com/spf13/pflag"
"k8s.io/cli-runtime/pkg/genericiooptions"
)

func main() {
// Create a set of flags to pass to the CLI
flags := pflag.NewFlagSet("kubectl-mapr-ticket", pflag.ExitOnError)
pflag.CommandLine = flags

// Create the root command and execute it
root := cli.NewRootCmd(genericiooptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr})
if err := root.Execute(); err != nil {
os.Exit(1)
}
}
Loading

0 comments on commit 8043689

Please sign in to comment.