Skip to content

Commit 91764f9

Browse files
authored
Feat: update aws-cli-auth (cobra, browser, build tool) (#21)
* fix: upgrade to new cobra implementation * fix: add own test container context fix: update test eirctl tasks feat: add a fallback to the chromium browser but prefer own chrome fix: remove process killer func +semver: feature +semver: FEATURE * fix: address linters fix: add custom binary * fix: tasks * fix: update test report path * fix: permissions for CI * fix: run test pipeline * fix: vuln check * fix: update to amd64 compatibel image * fix: correct container * fix: publish ci container * fix: changeCI workflow name * fix: unit test in ci * fix: debug * fix: multi stage * fix: remove debug output from task * fix: update quality gates in sonar * fix: remove debug outputs fix: add custom executable to cli flags * fix: update readme
1 parent 164b307 commit 91764f9

26 files changed

+740
-523
lines changed

.github/pull_request_template.md

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,11 @@
11
---
2-
name: Bug report
3-
about: Create a report to help us improve
4-
title: ''
5-
labels: ''
6-
assignees: ''
7-
2+
name: PR
83
---
94

10-
**Describe the bug**
11-
A clear and concise description of what the bug is.
12-
13-
**To Reproduce**
14-
Steps to reproduce the behavior:
15-
1. Go to '...'
16-
2. Click on '....'
17-
3. Scroll down to '....'
18-
4. See error
19-
20-
**Expected behavior**
21-
A clear and concise description of what you expected to happen.
5+
**Describe the PR**
226

237
**Screenshots**
248
If applicable, add screenshots to help explain your problem.
259

26-
**Desktop (please complete the following information):**
27-
- OS: [e.g. iOS]
28-
- Browser [e.g. chrome, safari]
29-
- Version [e.g. 22]
30-
31-
**Smartphone (please complete the following information):**
32-
- Device: [e.g. iPhone6]
33-
- OS: [e.g. iOS8.1]
34-
- Browser [e.g. stock browser, safari]
35-
- Version [e.g. 22]
36-
3710
**Additional context**
3811
Add any other context about the problem here.

.github/workflows/ci.yml

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@ on:
66
push:
77
branches: [ master, main ]
88

9+
permissions:
10+
contents: write
11+
statuses: write
12+
checks: write
13+
pull-requests: write
14+
915
jobs:
1016
set-version:
11-
runs-on: ubuntu-latest
17+
runs-on: ubuntu-22.04
1218
container:
1319
image: mcr.microsoft.com/dotnet/sdk:6.0
1420
outputs:
@@ -27,47 +33,50 @@ jobs:
2733
- name: Set SemVer Version
2834
uses: gittools/actions/gitversion/execute@v1
2935
id: gitversion
36+
3037
pr:
31-
runs-on: ubuntu-latest
32-
container:
33-
image: golang:1.24-bookworm
38+
runs-on: ubuntu-22.04
3439
needs: set-version
3540
env:
3641
REVISION: $GITHUB_SHA
3742
SEMVER: ${{ needs.set-version.outputs.semVer }}
3843
steps:
3944
- uses: actions/checkout@v4
40-
- name: install deps
45+
46+
- uses: ensono/actions/[email protected]
47+
with:
48+
version: latest
49+
isPrerelease: false
50+
51+
- name: prep-git
4152
run: |
42-
# Chromium dependencies
43-
apt-get update && apt-get install -y jq git \
44-
zip unzip \
45-
libnss3 \
46-
libxss1 \
47-
libasound2 \
48-
libxtst6 \
49-
libgtk-3-0 \
50-
libgbm1 \
51-
ca-certificates
5253
git config --global --add safe.directory "$GITHUB_WORKSPACE"
5354
git config user.email ${{ github.actor }}[email protected]
5455
git config user.name ${{ github.actor }}
55-
- name: make test
56+
57+
- name: Run linters
58+
run: |
59+
echo 'eirctl run vuln:check'
60+
61+
- name: Unit Tests
5662
run: |
57-
make REVISION=$GITHUB_SHA test
58-
- name: Publish Junit style Test Report
59-
uses: mikepenz/action-junit-report@v3
60-
if: always() # always run even if the previous step fails
63+
eirctl run unit:test:run
64+
65+
- name: Publish Test Report
66+
uses: mikepenz/action-junit-report@v5
67+
if: success() || failure()
6168
with:
62-
report_paths: '**/report-junit.xml'
63-
- name: Analyze with SonarCloud
64-
# You can pin the exact commit or the version.
65-
uses: SonarSource/sonarcloud-github-action@master
69+
report_paths: '.coverage/report-junit.xml'
70+
commit: ${{ github.sha }}
71+
fail_on_failure: true
72+
check_name: aws-cli-auth Unit Tests
73+
74+
- name: Analyze with SonarCloud
75+
uses: SonarSource/sonarqube-scan-action@v5
6676
env:
67-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information
68-
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Generate a token on Sonarcloud.io, add it to the secrets of this repo with the name SONAR_TOKEN (Settings > Secrets > Actions > add new repository secret)
77+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
78+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
6979
with:
70-
args:
80+
projectBaseDir: .
81+
args: >
7182
-Dsonar.projectVersion=${{ needs.set-version.outputs.semVer }}
72-
-Dsonar.go.coverage.reportPaths=/github/workspace/.coverage/out
73-
-Dsonar.go.tests.reportPaths=/github/workspace/.coverage/report-junit.xml

.github/workflows/release.yml

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,31 +39,35 @@ jobs:
3939
run: |
4040
echo "REVISION -> $GITHUB_SHA"
4141
echo "VERSION -> $GITVERSION_SEMVER"
42+
4243
release:
4344
runs-on: ubuntu-latest
44-
container:
45-
image: golang:1.24-bookworm
46-
env:
47-
FOO: Bar
4845
needs: set-version
4946
env:
5047
SEMVER: ${{ needs.set-version.outputs.semVer }}
5148
steps:
5249
- uses: actions/checkout@v4
5350
with:
5451
fetch-depth: 1
55-
- name: install deps
52+
53+
- uses: ensono/actions/[email protected]
54+
with:
55+
version: latest
56+
isPrerelease: false
57+
58+
- name: git-deps
5659
run: |
57-
apt-get update && apt-get install jq git -y
5860
git config --global --add safe.directory "$GITHUB_WORKSPACE"
5961
git config user.email ${{ github.actor }}[email protected]
6062
git config user.name ${{ github.actor }}
6163
- name: release library
6264
run: |
63-
make GIT_TAG=${SEMVER} REVISION=$GITHUB_SHA tag
64-
- name: release binary
65+
VERSION=${SEMVER} REVISION=$GITHUB_SHA eirctl run tag
66+
67+
- name: Build binary
6568
run: |
66-
make REVISION=$GITHUB_SHA GIT_TAG=${SEMVER} PAT=${{ secrets.GITHUB_TOKEN }} cross-build
69+
eirctl run pipeline bin:release --set Version=${SEMVER} --set Revision=$GITHUB_SHA
70+
6771
- name: Release
6872
uses: softprops/[email protected]
6973
with:
@@ -72,4 +76,4 @@ jobs:
7276
generate_release_notes: true
7377
token: ${{ secrets.GITHUB_TOKEN }}
7478
files: ./dist/*
75-
prerelease: false
79+
prerelease: true

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ vendor/
2727

2828
.ignore*
2929
local/
30+
.deps/
31+
.cache/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ This tool deals with IdP logins via SAML, both into an AWS account directly or v
2727
2828
If, however, you need to support a non standard user journeys enforced by your IdP i.e. a sub company selection within your organization login portal, or a selection screen for different MFA providers - PingID or RSA HardToken etc.... you cannot reliably automate the flow or it would have to be too specific.
2929

30-
As such this approach uses [go-rod](https://github.com/go-rod/rod) library to uniformly allow the user to complete any and all auth steps and selections in a managed browser session up to the point of where the SAMLResponse is to be sent to AWS ACS service `https://signin.aws.amazon.com/saml`.
30+
As such this approach uses [go-rod](https://github.com/go-rod/rod) library to uniformly allow the user to complete any and all auth steps and selections in a managed browser session up to the point of where the SAMLResponse is to be sent to AWS ACS service `https://signin.aws.amazon.com/saml`.
3131

3232
Capturing this via hijack request and posting to AWS STS service to exchange this for the temporary credentials.
3333

aws-cli-auth.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,29 @@ package main
22

33
import (
44
"context"
5+
"log"
6+
"os"
7+
"os/signal"
8+
"syscall"
59

610
"github.com/DevLabFoundry/aws-cli-auth/cmd"
711
)
812

913
func main() {
10-
cmd.Execute(context.Background())
14+
ctx, stop := signal.NotifyContext(context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM, os.Kill}...)
15+
defer stop()
16+
17+
go func() {
18+
<-ctx.Done()
19+
stop()
20+
// log.Printf("\x1b[31minterrupted: %s\x1b[0m", ctx.Err())
21+
os.Exit(0)
22+
}()
23+
24+
c := cmd.New()
25+
c.WithSubCommands(cmd.SubCommands()...)
26+
27+
if err := c.Execute(ctx); err != nil {
28+
log.Fatalf("\x1b[31m%s\x1b[0m", err)
29+
}
1130
}

cmd/awscliauth.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package cmd
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"path"
8+
9+
"github.com/DevLabFoundry/aws-cli-auth/internal/credentialexchange"
10+
"github.com/spf13/cobra"
11+
)
12+
13+
var (
14+
Version string = "0.0.1"
15+
Revision string = "1111aaaa"
16+
)
17+
18+
type Root struct {
19+
Cmd *cobra.Command
20+
// ChannelOut io.Writer
21+
// ChannelErr io.Writer
22+
// viperConf *viper.Viper
23+
rootFlags *rootCmdFlags
24+
Datadir string
25+
}
26+
27+
type rootCmdFlags struct {
28+
cfgSectionName string
29+
storeInProfile bool
30+
killHangingProcess bool
31+
roleChain []string
32+
verbose bool
33+
duration int
34+
}
35+
36+
func New() *Root {
37+
rf := &rootCmdFlags{}
38+
r := &Root{
39+
rootFlags: rf,
40+
Cmd: &cobra.Command{
41+
Use: "aws-cli-auth",
42+
Short: "CLI tool for retrieving AWS temporary credentials",
43+
Long: `CLI tool for retrieving AWS temporary credentials using SAML providers, or specified method of retrieval - i.e. force AWS_WEB_IDENTITY.
44+
Useful in situations like CI jobs or containers where multiple env vars might be present.
45+
Stores them under the $HOME/.aws/credentials file under a specified path or returns the crednetial_process payload for use in config`,
46+
Version: fmt.Sprintf("%s-%s", Version, Revision),
47+
SilenceUsage: true,
48+
SilenceErrors: true,
49+
},
50+
}
51+
52+
r.Cmd.PersistentFlags().StringSliceVarP(&rf.roleChain, "role-chain", "", []string{}, "If specified it will assume the roles from the base credentials, in order they are specified in")
53+
r.Cmd.PersistentFlags().BoolVarP(&rf.storeInProfile, "store-profile", "s", false, `By default the credentials are returned to stdout to be used by the credential_process.
54+
Set this flag to instead store the credentials under a named profile section. You can then reference that profile name via the CLI or for use in an SDK`)
55+
r.Cmd.PersistentFlags().StringVarP(&rf.cfgSectionName, "cfg-section", "", "", "Config section name in the default AWS credentials file. To enable priofi")
56+
// When specifying store in profile the config section name must be provided
57+
r.Cmd.MarkFlagsRequiredTogether("store-profile", "cfg-section")
58+
r.Cmd.PersistentFlags().IntVarP(&rf.duration, "max-duration", "d", 900, `Override default max session duration, in seconds, of the role session [900-43200].
59+
NB: This cannot be higher than the 3600 as the API does not allow for AssumeRole for sessions longer than an hour`)
60+
r.Cmd.PersistentFlags().BoolVarP(&rf.verbose, "verbose", "v", false, "Verbose output")
61+
_ = r.dataDirInit()
62+
return r
63+
}
64+
65+
// SubCommands is a standalone Builder helper
66+
//
67+
// IF you are making your sub commands public, you can just pass them directly `WithSubCommands`
68+
func SubCommands() []func(*Root) {
69+
return []func(*Root){
70+
newSamlCmd,
71+
newClearCmd,
72+
newSpecificIdentityCmd,
73+
}
74+
}
75+
76+
func (r *Root) WithSubCommands(iocFuncs ...func(rootCmd *Root)) {
77+
for _, fn := range iocFuncs {
78+
fn(r)
79+
}
80+
}
81+
82+
func (r *Root) Execute(ctx context.Context) error {
83+
return r.Cmd.ExecuteContext(ctx)
84+
}
85+
86+
func (r *Root) dataDirInit() error {
87+
datadir := path.Join(credentialexchange.HomeDir(), fmt.Sprintf(".%s-data", credentialexchange.SELF_NAME))
88+
if _, err := os.Stat(datadir); err != nil {
89+
return os.MkdirAll(datadir, 0755)
90+
}
91+
r.Datadir = datadir
92+
return nil
93+
}

0 commit comments

Comments
 (0)