Skip to content
Merged
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
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
push:
branches:
- main
- dev
- next

permissions:
contents: read # for checkout
Expand Down Expand Up @@ -32,15 +32,15 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.22.x'
go-version: '1.24.x'
- 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
if: "!contains(github.ref, 'main')"
run: echo "flags=--snapshot" >> $GITHUB_ENV
- uses: goreleaser/goreleaser-action@v6
with:
version: v1.25.1
version: '~> v2'
args: release --clean ${{ env.flags }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
22 changes: 7 additions & 15 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com

# The lines bellow are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/need to use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2

project_name: gpcore

Expand All @@ -14,18 +8,14 @@ before:
- go generate ./...

builds:
- env:
- CGO_ENABLED=0
id: gpcore
- id: gpcore
goos:
- linux
- windows
ldflags:
- "-s -w -X '{{ .ModulePath }}/cmd.version={{.Tag}}' -X '{{ .ModulePath }}/cmd.commit={{.Commit}}' -X '{{ .ModulePath }}/cmd.date={{.Date}}'"

- env:
- CGO_ENABLED=0
id: gpcore-macos
- id: gpcore-macos
goos:
- darwin
ldflags:
Expand All @@ -40,7 +30,8 @@ builds:
- QUILL_LOG_FILE=/tmp/quill-{{ .Target }}.log

archives:
- format: tar.gz
- formats:
- tar.gz
# this name template makes the OS and Arch compatible with the results of `uname`.
name_template: >-
{{ .ProjectName }}_
Expand All @@ -52,7 +43,8 @@ archives:
# use zip for windows archives
format_overrides:
- goos: windows
format: zip
formats:
- zip

changelog:
sort: asc
Expand Down
54 changes: 37 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ latest release from GitHub and replace the current binary.

To use shell completion for the gpcore command, you can generate the completion
script with the ```gpcore completion``` command. Supported shells are bash, zsh
fish and powershell. It will print the script to stdout, so pipe it in a file
fish and PowerShell. It will print the script to stdout, so pipe it in a file
and source it in your shell.

```
Expand All @@ -31,23 +31,45 @@ to the server and sends commands to it. The server executes the commands and
returns the result to the client. With this architecture, the client does not
open up a new connection for every command, which saves time and resources.

On first run, it asks for credentials (client-id, client-secret, username and
On the first run, it asks for credentials (client-id, client-secret, username and
password). Non-critical information will be stored in a config file
( ~/.config/gportal/config.json ). Sensitive information will be stored in the
(~/.config/gportal/config.json). Sensitive information will be stored in the
keyring (if supported by the OS). The keyring is encrypted with the user's
password. To secure the connection between client and server, a SSH public/private
password. To secure the connection between client and server, an SSH public/private
key pair will be generated and secured with a passphrase. The passphrase is
the same as the password for the GPCORE account. This way, the connection
between client and server is secured and no other ssh client can connect to it.
between client and server is secured, and no other ssh client can connect to it.

If you messed up your config, the sensitive data in the keyring or the public/private
key, you can reset everything with the ```gpcore agent setup``` command. Use the
```--admin``` flag to setup the admin credentials as well.
key, you can reset everything with the ```gpcore agent setup``` command.

The agent (SSH server) will start automatically and place it in the background,
### Admin permissions

The GPCORE API has a concept of admin permissions. Several actions can only
be executed with admin permissions. Use the ```--admin``` flag on the agent
setup to set the admin credentials as well. Use your normal GPCORE account
credentials for that. The admin credentials will be stored in the keyring
and used to execute admin actions.

NOTE: The tool does not support 2FA at the moment, so you have to disable it
for your GPCORE account to use the CLI. You still can use Passkey.

To make sure that you have admin permissions, you can use the ```user details```
command, which will show the admin flag. You also see more actions with
the ```help``` command, if you have admin permissions. If you have the admin
flag but get an unauthorized error, you probably have to set the ```super-admin```
role on your service account in Keycloak. Ask a GPCORE administrator for help.

If you logged in as a normal user and want to switch to admin mode, you first
need to stop the agent with ```gpcore agent stop```, then run the agent setup
again with ```gpcore agent setup --admin```.

The agent (SSH server) will start automatically and place itself in the background,
until the user actively stops it with ```gpcore agent stop```. So the first command will
take a little longer (because the agent has to start), but all following commands
will be executed immediately.
will be executed immediately. If you want to see the output of the agent,
you can run the agent in the foreground with ```gpcore agent start``` in a separate
terminal.

The client itself is a simple SSH client. It connects to the agent and sends
commands to it. The result is printed to stdout. You can use the standard
Expand All @@ -64,8 +86,12 @@ just the subcommand without any arguments, you will get a list of all available
actions for that subcommand.

Some commands need flags or specific parameters. To get a list of all flags and
parameters, run ```gpcore help <subcommand> <action>```. For example, to change
the active project, run ```gpcore project set-active --id <project-uuid>```.
parameters, run ```gpcore help <subcommand> <action>```.

A lot of commands need a project ID to work with. To make the commandline tool
more convenient, you can set the active project with the
```gpcore project use --id <project-uuid>``` command. This will set the active
project for all commands which need a project ID.

By default, the output is formatted as a ASCII table. If you want to pass the
output to other tools for processing, you can append the flag ```--csv``` or
Expand All @@ -91,9 +117,3 @@ action but before the output is printed. As an example, see ```project/list_post

To increase the log level verbosity, you can set it with the ```loglevel```
command (```gpcore loglevel debug```).

### Ongoing tasks

* catch unauthorized error and ask for user/pass
* Pagination support for long lists (pending because of Jennifer migration)
* Complete the API endpoints, so everything is accessible through the CLI tool
3 changes: 2 additions & 1 deletion cmd/help/help.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package help

import (
"errors"
"fmt"
"github.com/spf13/cobra"
)
Expand All @@ -22,5 +23,5 @@ func UnknownSubcommandAction(cobraCmd *cobra.Command, args []string) error {
}
cobraCmd.Println(err)

return fmt.Errorf(err)
return errors.New(err)
}
10 changes: 4 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
module github.com/G-PORTAL/gpcore-cli

go 1.23.0

toolchain go1.24.0
go 1.24.0

require (
buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2
Expand Down Expand Up @@ -39,10 +37,10 @@ require (
github.com/charmbracelet/colorprofile v0.3.1 // indirect
github.com/charmbracelet/keygen v0.5.3 // indirect
github.com/charmbracelet/lipgloss v1.1.0 // indirect
github.com/charmbracelet/x/ansi v0.9.3 // 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.0 // indirect
github.com/charmbracelet/x/errors v0.0.0-20250725211024-d60e1b0112b2 // indirect
github.com/charmbracelet/x/errors v0.0.0-20250805141217-38fb69db254f // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/charmbracelet/x/termios v0.1.1 // indirect
github.com/creack/pty v1.1.24 // indirect
Expand Down Expand Up @@ -84,5 +82,5 @@ require (
golang.org/x/sys v0.34.0 // indirect
golang.org/x/text v0.27.0 // indirect
golang.org/x/time v0.12.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect
)
Loading