Skip to content

Commit 72fa603

Browse files
authored
refactor(auth): use CLI-based authentication for GCE and Azure (#419)
- GCE: Replace JSON keyfile auth with Application Default Credentials (ADC) - Azure: Remove unused authFile parameter from NewAzure() - Update golangci-lint config to v2 format - Document breaking changes in README Signed-off-by: Engin Diri <engin.diri@ediri.de>
1 parent 1d78ee9 commit 72fa603

File tree

4 files changed

+78
-19
lines changed

4 files changed

+78
-19
lines changed

.golangci.yaml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
1+
version: "2"
2+
13
linters:
24
enable:
35
- thelper
4-
- gofumpt
56
- tparallel
67
- unconvert
78
- unparam
89
- wastedassign
910
- revive
1011
- forbidigo
1112
- tagliatelle
12-
- typecheck
1313
- goconst
1414
- gocritic
1515
- gocyclo
1616
- govet
1717
- errcheck
1818
- gosec
19-
- goimports
2019
- nolintlint
2120

21+
formatters:
22+
enable:
23+
- gofumpt
24+
- goimports
25+
2226
linters-settings:
2327
forbidigo:
2428
forbid:

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ SDK for every minectl product
99

1010
## Breaking changes
1111

12+
### v0.9.0
13+
14+
- **GCE**: Refactored authentication to use Application Default Credentials (ADC) instead of JSON keyfile.
15+
- `NewGCE(keyfile, zone string)` changed to `NewGCE(zone string)`
16+
- `GCE_KEY` environment variable is no longer used
17+
- New required environment variables: `GOOGLE_PROJECT` and `GOOGLE_SERVICE_ACCOUNT_EMAIL`
18+
- Optional: `GOOGLE_APPLICATION_CREDENTIALS` for service account JSON (if not using `gcloud auth application-default login`)
19+
20+
- **Azure**: Removed unused `authFile` parameter from `NewAzure()` function.
21+
- `NewAzure(authFile string)` changed to `NewAzure()`
22+
- `AZURE_AUTH_LOCATION` environment variable is no longer used
23+
- No changes needed if already using `AZURE_SUBSCRIPTION_ID` with `az login`
24+
1225
### v0.8.0
1326

1427
- Rename `Linode` to `Akamai Connected Cloud` and all related files. See this [blog post](https://www.linode.com/blog/linode/a-bold-new-approach-to-the-cloud/) for more information.

cloud/azure/azure.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,17 @@ type Azure struct {
2727
tmpl *minctlTemplate.Template
2828
}
2929

30-
func NewAzure(authFile string) (*Azure, error) {
30+
// NewAzure creates a new Azure instance using DefaultAzureCredential.
31+
// Authentication is handled automatically via the Azure credential chain:
32+
// 1. Environment variables (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET)
33+
// 2. Managed identity (when running on Azure)
34+
// 3. Azure CLI authentication (az login)
35+
// 4. Azure PowerShell authentication
36+
// 5. Azure Developer CLI authentication
37+
//
38+
// Required environment variables:
39+
// - AZURE_SUBSCRIPTION_ID: The Azure subscription ID
40+
func NewAzure() (*Azure, error) {
3141
cred, err := azidentity.NewDefaultAzureCredential(nil)
3242
if err != nil {
3343
return nil, err

cloud/gce/gce.go

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package gce
22

33
import (
44
"context"
5-
"encoding/json"
65
"fmt"
76
"os"
87
"path/filepath"
@@ -16,6 +15,7 @@ import (
1615
minctlTemplate "github.com/dirien/minectl-sdk/template"
1716
"github.com/dirien/minectl-sdk/update"
1817
"github.com/pkg/errors"
18+
"golang.org/x/oauth2/google"
1919
"google.golang.org/api/compute/v1"
2020
"google.golang.org/api/googleapi"
2121
"google.golang.org/api/option"
@@ -40,35 +40,67 @@ type GCE struct {
4040
tmpl *minctlTemplate.Template
4141
}
4242

43-
func NewGCE(keyfile, zone string) (*GCE, error) {
44-
file, err := os.ReadFile(keyfile)
45-
if err != nil {
46-
return nil, err
43+
// NewGCE creates a new GCE instance using Application Default Credentials (ADC).
44+
// Authentication is handled automatically via the standard Google credential chain:
45+
// 1. GOOGLE_APPLICATION_CREDENTIALS environment variable (path to service account JSON)
46+
// 2. gcloud CLI authentication (gcloud auth application-default login)
47+
// 3. GCE metadata service (when running on Google Cloud)
48+
//
49+
// Required environment variables:
50+
// - GOOGLE_PROJECT: The GCP project ID
51+
// - GOOGLE_SERVICE_ACCOUNT_EMAIL: The service account email (for OS Login SSH access)
52+
//
53+
// Optional:
54+
// - GOOGLE_APPLICATION_CREDENTIALS: Path to service account JSON (if not using gcloud CLI auth)
55+
func NewGCE(zone string) (*GCE, error) {
56+
ctx := context.Background()
57+
58+
// Get project ID from environment
59+
projectID := os.Getenv("GOOGLE_PROJECT")
60+
if projectID == "" {
61+
return nil, errors.New("GOOGLE_PROJECT environment variable is required")
4762
}
48-
var cred Credentials
49-
err = json.Unmarshal(file, &cred)
63+
64+
// Get service account email from environment (required for OS Login)
65+
serviceAccountEmail := os.Getenv("GOOGLE_SERVICE_ACCOUNT_EMAIL")
66+
if serviceAccountEmail == "" {
67+
return nil, errors.New("GOOGLE_SERVICE_ACCOUNT_EMAIL environment variable is required")
68+
}
69+
70+
// Use Application Default Credentials
71+
// This supports:
72+
// - GOOGLE_APPLICATION_CREDENTIALS env var pointing to service account JSON
73+
// - gcloud auth application-default login
74+
// - GCE metadata service
75+
creds, err := google.FindDefaultCredentials(ctx, compute.ComputeScope, oslogin.ComputeScope)
5076
if err != nil {
51-
return nil, err
77+
return nil, errors.Wrap(err, "failed to find default credentials. Run 'gcloud auth application-default login' or set GOOGLE_APPLICATION_CREDENTIALS")
5278
}
53-
computeService, err := compute.NewService(context.Background(), option.WithCredentialsJSON(file))
79+
80+
computeService, err := compute.NewService(ctx, option.WithCredentials(creds))
5481
if err != nil {
55-
return nil, err
82+
return nil, errors.Wrap(err, "failed to create compute service")
5683
}
5784

58-
userService, err := oslogin.NewService(context.Background(), option.WithCredentialsJSON(file))
85+
userService, err := oslogin.NewService(ctx, option.WithCredentials(creds))
5986
if err != nil {
60-
return nil, err
87+
return nil, errors.Wrap(err, "failed to create oslogin service")
6188
}
89+
6290
tmpl, err := minctlTemplate.NewTemplateBash()
6391
if err != nil {
6492
return nil, err
6593
}
94+
95+
// Extract service account ID from email (the part before @)
96+
serviceAccountID := strings.Split(serviceAccountEmail, "@")[0]
97+
6698
return &GCE{
6799
client: computeService,
68-
projectID: cred.ProjectID,
100+
projectID: projectID,
69101
user: userService,
70-
serviceAccountName: cred.ClientEmail,
71-
serviceAccountID: cred.ClientID,
102+
serviceAccountName: serviceAccountEmail,
103+
serviceAccountID: serviceAccountID,
72104
zone: zone,
73105
tmpl: tmpl,
74106
}, nil

0 commit comments

Comments
 (0)