Skip to content

Commit 8caccf7

Browse files
AGENT-871: Authenticate wait-for commands
- Base64 encode ECDSA public, private keys - Set Authorization header param in the client
1 parent fcaa07d commit 8caccf7

File tree

8 files changed

+69
-12
lines changed

8 files changed

+69
-12
lines changed

cmd/openshift-install/agent/waitfor.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,13 @@ func newWaitForBootstrapCompleteCmd() *cobra.Command {
7171
logrus.Fatal(err)
7272
}
7373

74+
authToken, err := agentpkg.FindAuthTokenFromAssetStore(assetDir)
75+
if err != nil {
76+
logrus.Fatal(err)
77+
}
78+
7479
ctx := context.Background()
75-
cluster, err := agentpkg.NewCluster(ctx, assetDir, rendezvousIP, kubeconfigPath, sshKey, workflow.AgentWorkflowTypeInstall)
80+
cluster, err := agentpkg.NewCluster(ctx, assetDir, rendezvousIP, kubeconfigPath, sshKey, authToken, workflow.AgentWorkflowTypeInstall)
7681
if err != nil {
7782
logrus.Exit(exitCodeBootstrapFailed)
7883
}
@@ -106,8 +111,13 @@ func newWaitForInstallCompleteCmd() *cobra.Command {
106111
logrus.Fatal(err)
107112
}
108113

114+
authToken, err := agentpkg.FindAuthTokenFromAssetStore(assetDir)
115+
if err != nil {
116+
logrus.Fatal(err)
117+
}
118+
109119
ctx := context.Background()
110-
cluster, err := agentpkg.NewCluster(ctx, assetDir, rendezvousIP, kubeconfigPath, sshKey, workflow.AgentWorkflowTypeInstall)
120+
cluster, err := agentpkg.NewCluster(ctx, assetDir, rendezvousIP, kubeconfigPath, sshKey, authToken, workflow.AgentWorkflowTypeInstall)
111121
if err != nil {
112122
logrus.Exit(exitCodeBootstrapFailed)
113123
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ require (
4242
github.com/diskfs/go-diskfs v1.4.0
4343
github.com/form3tech-oss/jwt-go v3.2.3+incompatible
4444
github.com/go-openapi/errors v0.22.0
45+
github.com/go-openapi/runtime v0.26.2
4546
github.com/go-openapi/strfmt v0.23.0
4647
github.com/go-openapi/swag v0.23.0
4748
github.com/go-playground/validator/v10 v10.19.0

pkg/agent/cluster.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ type clusterInstallStatusHistory struct {
6666
}
6767

6868
// NewCluster initializes a Cluster object
69-
func NewCluster(ctx context.Context, assetDir, rendezvousIP, kubeconfigPath, sshKey string, workflowType workflow.AgentWorkflowType) (*Cluster, error) {
69+
func NewCluster(ctx context.Context, assetDir, rendezvousIP, kubeconfigPath, sshKey, authToken string, workflowType workflow.AgentWorkflowType) (*Cluster, error) {
7070
czero := &Cluster{}
7171
capi := &clientSet{}
7272

73-
restclient, err := NewNodeZeroRestClient(ctx, rendezvousIP, sshKey)
73+
restclient, err := NewNodeZeroRestClient(ctx, rendezvousIP, sshKey, authToken)
7474
if err != nil {
7575
logrus.Fatal(err)
7676
}

pkg/agent/rest.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/openshift/assisted-service/client/installer"
1616
"github.com/openshift/assisted-service/models"
1717
"github.com/openshift/installer/pkg/asset/agent/agentconfig"
18+
"github.com/openshift/installer/pkg/asset/agent/gencrypto"
1819
"github.com/openshift/installer/pkg/asset/agent/image"
1920
"github.com/openshift/installer/pkg/asset/agent/manifests"
2021
"github.com/openshift/installer/pkg/asset/installconfig"
@@ -32,7 +33,7 @@ type NodeZeroRestClient struct {
3233
}
3334

3435
// NewNodeZeroRestClient Initialize a new rest client to interact with the Agent Rest API on node zero.
35-
func NewNodeZeroRestClient(ctx context.Context, rendezvousIP string, sshKey string) (*NodeZeroRestClient, error) {
36+
func NewNodeZeroRestClient(ctx context.Context, rendezvousIP, sshKey, token string) (*NodeZeroRestClient, error) {
3637
restClient := &NodeZeroRestClient{}
3738

3839
// Get SSH Keys which can be used to determine if Rest API failures are due to network connectivity issues
@@ -46,6 +47,9 @@ func NewNodeZeroRestClient(ctx context.Context, rendezvousIP string, sshKey stri
4647
Host: net.JoinHostPort(rendezvousIP, "8090"),
4748
Path: client.DefaultBasePath,
4849
}
50+
51+
config.AuthInfo = gencrypto.UserAuthHeaderWriter(token)
52+
4953
client := client.New(config)
5054

5155
restClient.Client = client
@@ -115,6 +119,26 @@ func FindRendezvouIPAndSSHKeyFromAssetStore(assetDir string) (string, string, er
115119
return rendezvousIP, sshKey, nil
116120
}
117121

122+
// FindAuthTokenFromAssetStore returns the auth token.
123+
func FindAuthTokenFromAssetStore(assetDir string) (string, error) {
124+
authConfigAsset := &gencrypto.AuthConfig{}
125+
126+
assetStore, err := assetstore.NewStore(assetDir)
127+
if err != nil {
128+
return "", errors.Wrap(err, "failed to create asset store")
129+
}
130+
131+
authConfig, authConfigError := assetStore.Load(authConfigAsset)
132+
133+
if authConfigError != nil {
134+
logrus.Debug(errors.Wrapf(authConfigError, "failed to load %s", authConfigAsset.Name()))
135+
}
136+
137+
token := authConfig.(*gencrypto.AuthConfig).Token
138+
139+
return token, nil
140+
}
141+
118142
// IsRestAPILive Determine if the Agent Rest API on node zero has initialized
119143
func (rest *NodeZeroRestClient) IsRestAPILive() bool {
120144
// GET /v2/infraenvs
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package gencrypto
2+
3+
import (
4+
"github.com/go-openapi/runtime"
5+
"github.com/go-openapi/strfmt"
6+
)
7+
8+
// UserAuthHeaderWriter sets the JWT authorization token.
9+
func UserAuthHeaderWriter(token string) runtime.ClientAuthInfoWriter {
10+
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
11+
return r.SetHeaderParam("Authorization", token)
12+
})
13+
}

pkg/asset/agent/gencrypto/authconfig.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"crypto/elliptic"
77
"crypto/rand"
88
"crypto/x509"
9+
"encoding/base64"
910
"encoding/pem"
1011

1112
"github.com/golang-jwt/jwt/v4"
@@ -19,6 +20,8 @@ type AuthConfig struct {
1920
PublicKey, PrivateKey, Token string
2021
}
2122

23+
var _ asset.Asset = (*AuthConfig)(nil)
24+
2225
// LocalJWTKeyType suggests the key type to be used for the token.
2326
type LocalJWTKeyType string
2427

@@ -40,14 +43,19 @@ func (a *AuthConfig) Dependencies() []asset.Asset {
4043
func (a *AuthConfig) Generate(dependencies asset.Parents) error {
4144
infraEnvID := &common.InfraEnvID{}
4245
dependencies.Get(infraEnvID)
46+
4347
PublicKey, PrivateKey, err := keyPairPEM()
4448
if err != nil {
4549
return err
4650
}
47-
a.PublicKey = PublicKey
48-
a.PrivateKey = PrivateKey
51+
// Encode to Base64 (Standard encoding)
52+
encodedPrivateKeyPEM := base64.StdEncoding.EncodeToString([]byte(PrivateKey))
53+
encodedPubKeyPEM := base64.StdEncoding.EncodeToString([]byte(PublicKey))
54+
55+
a.PrivateKey = encodedPrivateKeyPEM
56+
a.PublicKey = encodedPubKeyPEM
4957

50-
token, err := localJWTForKey(infraEnvID.ID, a.PrivateKey)
58+
token, err := localJWTForKey(infraEnvID.ID, PrivateKey)
5159
if err != nil {
5260
return err
5361
}
@@ -57,7 +65,7 @@ func (a *AuthConfig) Generate(dependencies asset.Parents) error {
5765
}
5866

5967
// Name returns the human-friendly name of the asset.
60-
func (a *AuthConfig) Name() string {
68+
func (*AuthConfig) Name() string {
6169
return "Agent Installer API Auth Config"
6270
}
6371

pkg/asset/agent/gencrypto/authconfig_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ func TestAuthConfig_Generate(t *testing.T) {
2727

2828
assert.NoError(t, err)
2929

30-
assert.Contains(t, authConfigAsset.PrivateKey, "BEGIN EC PRIVATE KEY")
31-
assert.Contains(t, authConfigAsset.PublicKey, "BEGIN EC PUBLIC KEY")
30+
assert.NotEmpty(t, authConfigAsset.PrivateKey)
31+
assert.NotEmpty(t, authConfigAsset.PublicKey)
3232
assert.NotEmpty(t, authConfigAsset.Token)
3333
})
3434
}

pkg/nodejoiner/monitoraddnodes.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ func NewMonitorAddNodesCommand(directory, kubeconfigPath string, ips []string) e
1616
return err
1717
}
1818

19-
cluster, err := agentpkg.NewCluster(context.Background(), "", ips[0], kubeconfigPath, "", workflow.AgentWorkflowTypeAddNodes)
19+
var token string
20+
cluster, err := agentpkg.NewCluster(context.Background(), "", ips[0], kubeconfigPath, "", token, workflow.AgentWorkflowTypeAddNodes)
2021
if err != nil {
2122
// TODO exit code enumerate
2223
logrus.Exit(1)

0 commit comments

Comments
 (0)