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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
with:
fetch-tags: true
- uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff
- uses: actions/setup-go@v6
with:
Expand Down
1 change: 1 addition & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ set shell := ["bash", "-u", "-c"]

export scripts := ".github/workflows/scripts"
export GOBIN := `echo $PWD/.bin`
export TAG := `git describe --tags $(git rev-list --tags --max-count=1)`

# print available commands
[private]
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ module github.com/shoenig/ssh-key-sync
go 1.26

require (
cattlecloud.net/go/babycli v0.2.0
github.com/hashicorp/go-set/v3 v3.0.1
github.com/shoenig/go-landlock v1.3.0
github.com/shoenig/test v1.12.2
oss.indeed.com/go/libtime v1.6.0
)

require (
cattlecloud.net/go/stacks v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gojuno/minimock/v3 v3.4.7 // indirect
github.com/google/go-cmp v0.6.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
cattlecloud.net/go/babycli v0.2.0 h1:niw4uPiFQT7bekq8OJ3LoiIsz2B7L6EZcO+esMx9AP0=
cattlecloud.net/go/babycli v0.2.0/go.mod h1:IhC9GNNMMlDr5sx/lMFBDa1d7jvkI1sluTPsKbpvoAU=
cattlecloud.net/go/stacks v1.1.0 h1:uXnOnluwPT+3IfRDzTmkEP8RCfToBeNremjahViWUhY=
cattlecloud.net/go/stacks v1.1.0/go.mod h1:BD7LcLq19hHEyA+oQOrInqmjjiCccCcVTIxt8eEmW4M=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
Expand Down
54 changes: 44 additions & 10 deletions internal/command/cmd.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,56 @@
package command

import (
"errors"
"fmt"
"os"

"cattlecloud.net/go/babycli"
"github.com/shoenig/ssh-key-sync/internal/config"
"github.com/shoenig/ssh-key-sync/internal/netapi"
"github.com/shoenig/ssh-key-sync/internal/ssh"
"github.com/shoenig/ssh-key-sync/version"
)

func Start(args []string) error {
arguments := config.ParseArguments(args[0], args[1:])
if arguments.GitHubUser == "" {
arguments.Usage()
return errors.New("missing required argument(s)")
}
func Invoke(args []string) babycli.Code {
return babycli.New(&babycli.Configuration{
Arguments: args,
Version: version.Version,
Top: &babycli.Component{
Name: "ssh-key-sync",
Description: "Sync SSH public keys from GitHub to authorized_keys",
Flags: babycli.Flags{
{Long: "verbose", Short: "v", Type: babycli.BooleanFlag, Help: "print verbose logging"},
{Long: "prune", Short: "p", Type: babycli.BooleanFlag, Help: "delete all keys not found in GitHub"},
{Long: "system-user", Short: "u", Type: babycli.StringFlag, Help: "specify the unix system user"},
{Long: "authorized-keys", Type: babycli.StringFlag, Help: "override the output authorized_keys file"},
{Long: "github-user", Short: "g", Type: babycli.StringFlag, Require: true, Help: "specify the GitHub user"},
{Long: "github-api", Type: babycli.StringFlag, Help: "specify the GitHub API endpoint"},
},
Function: run,
},
}).Run()
}

func run(c *babycli.Component) babycli.Code {
githubUser := c.GetString("github-user")

cfg := config.NewArguments(
c.GetBool("verbose"),
c.GetBool("prune"),
c.GetString("system-user"),
c.GetString("authorized-keys"),
githubUser,
c.GetString("github-api"),
)

reader := ssh.NewKeysReader()
githubClient := netapi.NewGithubClient(arguments)
exe := NewExec(arguments.Prune, arguments.Verbose, reader, githubClient)
return exe.Execute(arguments)
githubClient := netapi.NewGithubClient(cfg)
exe := NewExec(cfg.Prune, cfg.Verbose, reader, githubClient)

if err := exe.Execute(cfg); err != nil {
fmt.Fprintf(os.Stderr, "unable to execute: %v", err)
return babycli.Failure
}

return babycli.Success
}
17 changes: 17 additions & 0 deletions internal/config/arguments.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ func defaultUser() string {
return current
}

func NewArguments(verbose, prune bool, systemUser, authorizedKeys, githubUser, githubAPI string) Arguments {
if systemUser == "" {
systemUser = defaultUser()
}
if githubAPI == "" {
githubAPI = "https://api.github.com"
}
return Arguments{
Verbose: verbose,
Prune: prune,
SystemUser: systemUser,
AuthorizedKeys: authorizedKeys,
GitHubUser: githubUser,
GitHubAPI: githubAPI,
}
}

func ParseArguments(program string, args []string) Arguments {
flags := flag.NewFlagSet(program, flag.ContinueOnError)
var arguments Arguments
Expand Down
9 changes: 4 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package main

import (
"fmt"
"os"

"cattlecloud.net/go/babycli"
"github.com/shoenig/ssh-key-sync/internal/command"
)

func main() {
if err := command.Start(os.Args); err != nil {
fmt.Println("[fatal]", err)
os.Exit(1)
}
args := babycli.Arguments()
rc := command.Invoke(args)
os.Exit(rc)
}
3 changes: 3 additions & 0 deletions version/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package version

var Version = "deveopment"
Loading