Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/danger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
pull-requests: write # to be able to comment on released pull requests
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-tags: true
- name: Setup Node.js
Expand All @@ -32,7 +32,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.25.4'
go-version: '1.26.0'
- name: Install quill CLI
run: curl -sSfL https://raw.githubusercontent.com/anchore/quill/main/install.sh | sh -s -- -b /usr/local/bin
- name: Check if snapshot build
Expand All @@ -50,7 +50,7 @@ jobs:
QUILL_NOTARY_KEY_ID: ${{ secrets.QUILL_NOTARY_KEY_ID }}
QUILL_NOTARY_ISSUER: ${{ secrets.QUILL_NOTARY_ISSUER }}
- name: Upload dist artifacts to GitHub when not on main
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
if: "!contains(github.ref, 'main')"
with:
name: gpcore
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6

- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.25.4'
go-version: '1.26.0'

- name: Install dependencies
run: go mod download
Expand Down
27 changes: 14 additions & 13 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@ builds:
ldflags:
- "-s -w -X '{{ .ModulePath }}/cmd.version={{.Tag}}' -X '{{ .ModulePath }}/cmd.commit={{.Commit}}' -X '{{ .ModulePath }}/cmd.date={{.Date}}'"

- id: gpcore-macos
goos:
- darwin
ldflags:
- "-s -w -X '{{ .ModulePath }}/cmd.version={{.Tag}}' -X '{{ .ModulePath }}/cmd.commit={{.Commit}}' -X '{{ .ModulePath }}/cmd.date={{.Date}}'"
goarch:
- amd64
- arm64
hooks:
post:
- cmd: quill sign-and-notarize "{{ .Path }}" --dry-run={{ .IsSnapshot }} --ad-hoc={{ .IsSnapshot }} -vv
env:
- QUILL_LOG_FILE=/tmp/quill-{{ .Target }}.log
# TODO: Disabled for now due to a missing agreement from apple developer account.
# - id: gpcore-macos
# goos:
# - darwin
# ldflags:
# - "-s -w -X '{{ .ModulePath }}/cmd.version={{.Tag}}' -X '{{ .ModulePath }}/cmd.commit={{.Commit}}' -X '{{ .ModulePath }}/cmd.date={{.Date}}'"
# goarch:
# - amd64
# - arm64
# hooks:
# post:
# - cmd: quill sign-and-notarize "{{ .Path }}" --dry-run={{ .IsSnapshot }} --ad-hoc={{ .IsSnapshot }} -vv
# env:
# - QUILL_LOG_FILE=/tmp/quill-{{ .Target }}.log

archives:
- formats:
Expand Down
4 changes: 4 additions & 0 deletions cmd/agent/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ func New() *cobra.Command {
rootCmd.PersistentFlags().BoolVarP(&config.Verbose, "verbose", "v", false, "verbose mode")
rootCmd.PersistentFlags().BoolVarP(&config.JSONOutput, "json", "j", false, "output as JSON")
rootCmd.PersistentFlags().BoolVarP(&config.CSVOutput, "csv", "x", false, "output as CSV")
rootCmd.MarkFlagsMutuallyExclusive("json", "csv")

// Disable file completions globally (no flag in this CLI takes a file path)
rootCmd.CompletionOptions.DisableDefaultCmd = true

// Special client commands
cmd.SelfupdateCommand(&rootCmd)
Expand Down
4 changes: 2 additions & 2 deletions cmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ func CompletionCommand(rootCmd *cobra.Command) {
RunE: func(cmd *cobra.Command, args []string) error {
switch args[0] {
case "bash":
_ = rootCmd.GenBashCompletion(cmd.OutOrStdout())
_ = rootCmd.GenBashCompletionV2(cmd.OutOrStdout(), true)
case "zsh":
_ = rootCmd.GenZshCompletion(cmd.OutOrStdout())
case "fish":
_ = rootCmd.GenFishCompletion(cmd.OutOrStdout(), true)
case "powershell":
_ = rootCmd.GenPowerShellCompletion(cmd.OutOrStdout())
_ = rootCmd.GenPowerShellCompletionWithDesc(cmd.OutOrStdout())
}

return nil
Expand Down
4 changes: 2 additions & 2 deletions cmd/node/change_rescue_mode.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ var changeRescueModeCmd = &cobra.Command{
func init() {
changeRescueModeCmd.Flags().StringVar(&changeRescueModeId, "id", "", "Node ID (required)")
changeRescueModeCmd.Flags().StringVar(&changeRescueModeProjectId, "project-id", "", "Project ID (required)")
changeRescueModeCmd.Flags().BoolVar(&changeRescueModeEnabled, "enabled", false, "Enable or disable rescue mode (required)")
changeRescueModeCmd.Flags().StringVar(&changeRescueModePassword, "password", "", "Password for rescue mode (required)")
changeRescueModeCmd.Flags().BoolVar(&changeRescueModeEnabled, "enabled", false, "Enable or disable rescue mode")
changeRescueModeCmd.Flags().StringVar(&changeRescueModePassword, "password", "", "Password for rescue mode")

changeRescueModeCmd.MarkFlagRequired("id")
changeRescueModeCmd.MarkFlagRequired("project-id")
Expand Down
1 change: 1 addition & 0 deletions cmd/node/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var RootNodeCommand = &cobra.Command{
Use: "node",
Short: "Utility to combine multiple nodes api actions",
Long: `Utility to combine multiple nodes api actions`,
GroupID: "resources",
DisableFlagsInUseLine: true,
Args: cobra.MatchAll(cobra.ExactArgs(0), cobra.OnlyValidArgs),
PersistentPreRunE: func(cobraCmd *cobra.Command, args []string) error {
Expand Down
89 changes: 9 additions & 80 deletions cmd/project/_network_create.go
Original file line number Diff line number Diff line change
@@ -1,82 +1,11 @@
package project

import (
"buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/admin/v1/adminv1grpc"
adminv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/admin/v1"
cloudv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/cloud/v1"
"encoding/json"
"github.com/G-PORTAL/gpcore-cli/pkg/client"
"github.com/G-PORTAL/gpcore-cli/pkg/config"
"github.com/G-PORTAL/gpcore-cli/pkg/protobuf"
"github.com/spf13/cobra"
"google.golang.org/grpc"
)

// This command is disabled at the moment because the ListSubnets endpoint is
// missing on gRPC (which is needed to get the subnets from the IDs).

var networkCreateProjectId string
var networkCreateName string
var networkCreateType string
var networkCreateSubnets []string
var networkCreateVlanId int32
var networkCreateDatacenter string

var networkCreateCmd = &cobra.Command{
Args: cobra.OnlyValidArgs,
DisableFlagsInUseLine: true,
Long: "",
RunE: func(cobraCmd *cobra.Command, args []string) error {
ctx := client.ExtractContext(cobraCmd)
grpcConn := ctx.Value("conn").(*grpc.ClientConn)
client := adminv1grpc.NewAdminServiceClient(grpcConn)

networkCreateSubnetStructs := make([]*cloudv1.Subnet, 0)
// TODO: Get subnets from networkCreateSubnetUUIDList IDs
// TODO: ListSubnets endpoint missing on gRPC

networkCreateDatacenterStruct := &cloudv1.Datacenter{
Id: networkCreateDatacenter,
}

resp, err := client.CreateProjectNetwork(cobraCmd.Context(), &adminv1.CreateProjectNetworkRequest{
Name: networkCreateName,
ProjectId: networkCreateProjectId,
Subnets: networkCreateSubnetStructs,
Datacenter: networkCreateDatacenterStruct,
Type: protobuf.NetworkTypeToProto(networkCreateType),
VlanId: &networkCreateVlanId,
})
if err != nil {
return err
}
respData := resp
if config.JSONOutput {
jsonData, err := protobuf.MarshalIndent(respData)
if err != nil {
return err
}
cobraCmd.Println(string(jsonData))
}
return nil
},
Short: "",
Use: "network-create",
ValidArgs: []string{"project-id", "name", "type", "subnet-ids", "datacenter-id", "vlan-id"},
}

func init() {
networkCreateCmd.Flags().StringVar(&networkCreateProjectId, "project-id", "", "Project ID (required)")
networkCreateCmd.Flags().StringVar(&networkCreateName, "name", "", "Network name (required)")
networkCreateCmd.Flags().StringVar(&networkCreateType, "type", "PRIVATE", "Network type (default:\"cloudv1.NETWORK_TYPE_PRIVATE\")")
networkCreateCmd.Flags().StringSliceVar(&networkCreateSubnets, "subnet-ids", []string{}, "Subnets (required)")
networkCreateCmd.Flags().StringVar(&networkCreateDatacenter, "datacenter-id", "", "Datacenter ID (required)")
networkCreateCmd.Flags().Int32Var(&networkCreateVlanId, "vlan-id", int32(0), "VLAN ID")

networkCreateCmd.MarkFlagRequired("project-id")
networkCreateCmd.MarkFlagRequired("name")
networkCreateCmd.MarkFlagRequired("type")
networkCreateCmd.MarkFlagRequired("subnets")

RootProjectCommand.AddCommand(networkCreateCmd)
}
// This command is disabled because the ListSubnets endpoint is missing on
// gRPC (which is needed to resolve subnet IDs). It will be re-enabled once
// the endpoint is available.
//
// TODO: Re-enable once admin.ListSubnets is available in the gRPC API.
// The command should:
// - Accept --subnet-ids and resolve them via ListSubnets
// - Register itself with RootProjectCommand.AddCommand(networkCreateCmd)
// - Fix MarkFlagRequired to use "subnet-ids" (not "subnets")
1 change: 1 addition & 0 deletions cmd/project/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var RootProjectCommand = &cobra.Command{
Use: "project",
Short: "Utility to combine multiple project api actions",
Long: `Utility to combine multiple project api actions`,
GroupID: "admin",
DisableFlagsInUseLine: true,
Args: cobra.MatchAll(cobra.ExactArgs(0), cobra.OnlyValidArgs),
RunE: func(cobraCmd *cobra.Command, args []string) error {
Expand Down
72 changes: 37 additions & 35 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,88 +1,90 @@
module github.com/G-PORTAL/gpcore-cli

go 1.24.6
go 1.26.0

// For development
//replace github.com/G-PORTAL/gpcore-go => ../gpcore-go

require (
buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2
buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.9-20250804091548-289250b42883.1
buf.build/gen/go/gportal/gpcore/grpc/go v1.6.1-20260115091005-9b1a7a0cbe2d.1
buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260115091005-9b1a7a0cbe2d.1
github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f
github.com/Nerzal/gocloak/v13 v13.9.0
github.com/charmbracelet/log v0.4.2
github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309
github.com/charmbracelet/wish v1.4.7
github.com/creativeprojects/go-selfupdate v1.5.1
github.com/creativeprojects/go-selfupdate v1.5.2
github.com/dave/jennifer v1.7.1
github.com/gertd/go-pluralize v0.2.1
github.com/jedib0t/go-pretty/v6 v6.6.8
github.com/melbahja/goph v1.4.0
github.com/spf13/cobra v1.10.1
github.com/jedib0t/go-pretty/v6 v6.7.8
github.com/melbahja/goph v1.5.0
github.com/spf13/cobra v1.10.2
github.com/stoewer/go-strcase v1.3.1
github.com/zalando/go-keyring v0.2.6
golang.org/x/crypto v0.42.0
google.golang.org/grpc v1.75.1
google.golang.org/protobuf v1.36.9
golang.org/x/crypto v0.48.0
google.golang.org/grpc v1.79.1
google.golang.org/protobuf v1.36.11
gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7
gopkg.in/yaml.v3 v3.0.1
)

require (
al.essio.dev/pkg/shellescape v1.6.0 // indirect
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1 // indirect
code.gitea.io/sdk/gitea v0.22.0 // indirect
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 // indirect
code.gitea.io/sdk/gitea v0.22.1 // indirect
github.com/42wim/httpsig v1.2.3 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/bubbletea v1.3.10 // indirect
github.com/charmbracelet/colorprofile v0.3.2 // indirect
github.com/charmbracelet/keygen v0.5.3 // indirect
github.com/charmbracelet/colorprofile v0.4.1 // indirect
github.com/charmbracelet/keygen v0.5.4 // indirect
github.com/charmbracelet/lipgloss v1.1.0 // indirect
github.com/charmbracelet/x/ansi v0.10.1 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
github.com/charmbracelet/x/conpty v0.1.1 // indirect
github.com/charmbracelet/x/errors v0.0.0-20250922100529-c9afca5d6f21 // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/charmbracelet/x/ansi v0.11.3 // indirect
github.com/charmbracelet/x/cellbuf v0.0.14 // indirect
github.com/charmbracelet/x/conpty v0.2.0 // indirect
github.com/charmbracelet/x/term v0.2.2 // indirect
github.com/charmbracelet/x/termios v0.1.1 // indirect
github.com/clipperhouse/displaywidth v0.6.2 // indirect
github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
github.com/creack/pty v1.1.24 // indirect
github.com/danieljoos/wincred v1.2.2 // indirect
github.com/danieljoos/wincred v1.2.3 // indirect
github.com/davidmz/go-pageant v1.0.2 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/go-fed/httpsig v1.1.0 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/go-resty/resty/v2 v2.16.5 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/go-logfmt/logfmt v0.6.1 // indirect
github.com/go-resty/resty/v2 v2.17.1 // indirect
github.com/godbus/dbus/v5 v5.2.0 // indirect
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/google/go-github/v30 v30.1.0 // indirect
github.com/google/go-github/v74 v74.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/hashicorp/go-version v1.8.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.9 // indirect
github.com/pkg/sftp v1.13.10 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/segmentio/ksuid v1.0.4 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/ulikunitz/xz v0.5.15 // indirect
github.com/xanzy/go-gitlab v0.115.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect
golang.org/x/net v0.44.0 // indirect
golang.org/x/oauth2 v0.31.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/text v0.29.0 // indirect
golang.org/x/time v0.13.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 // indirect
gitlab.com/gitlab-org/api/client-go v1.9.1 // indirect
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect
golang.org/x/net v0.49.0 // indirect
golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/text v0.34.0 // indirect
golang.org/x/time v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect
)
Loading
Loading