Skip to content

Commit 488027e

Browse files
committed
refactor getCASBackend
Signed-off-by: Javier Rodriguez <javier@chainloop.dev>
1 parent af68f4c commit 488027e

3 files changed

Lines changed: 65 additions & 65 deletions

File tree

app/cli/pkg/action/action.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package action
1717

1818
import (
19+
"context"
1920
"fmt"
2021
"os"
2122
"path/filepath"
@@ -25,6 +26,9 @@ import (
2526
"github.com/chainloop-dev/chainloop/pkg/attestation/crafter"
2627
"github.com/chainloop-dev/chainloop/pkg/attestation/crafter/statemanager/filesystem"
2728
"github.com/chainloop-dev/chainloop/pkg/attestation/crafter/statemanager/remote"
29+
"github.com/chainloop-dev/chainloop/pkg/casclient"
30+
"github.com/chainloop-dev/chainloop/pkg/grpcconn"
31+
2832
"github.com/rs/zerolog"
2933
"google.golang.org/grpc"
3034
)
@@ -94,3 +98,52 @@ func newCrafter(stateOpts *newCrafterStateOpts, conn *grpc.ClientConn, opts ...c
9498

9599
return crafter.NewCrafter(stateManager, attClient, opts...)
96100
}
101+
102+
// getCASBackend tries to get CAS upload credentials and set up a CAS client
103+
// If strict is true, errors are returned; if false, warnings are logged and nil error is returned
104+
func getCASBackend(ctx context.Context, client pb.AttestationServiceClient, workflowRunID, casCAPath, casURI string, casConnectionInsecure bool, logger zerolog.Logger, casBackend *casclient.CASBackend) (func() error, error) {
105+
credsResp, err := client.GetUploadCreds(ctx, &pb.AttestationServiceGetUploadCredsRequest{
106+
WorkflowRunId: workflowRunID,
107+
})
108+
if err != nil {
109+
// Log warning but don't fail - will fall back to inline storage
110+
logger.Warn().Err(err).Msg("failed to get CAS credentials for PR metadata, will store inline")
111+
return nil, fmt.Errorf("getting upload creds: %w", err)
112+
}
113+
114+
if credsResp == nil || credsResp.GetResult() == nil {
115+
logger.Debug().Msg("no upload creds result, will store inline")
116+
return nil, fmt.Errorf("getting upload creds: %w", err)
117+
}
118+
119+
result := credsResp.GetResult()
120+
backend := result.GetBackend()
121+
if backend == nil {
122+
logger.Debug().Msg("no backend info in upload creds, will store inline")
123+
return nil, fmt.Errorf("no backend found in upload creds")
124+
}
125+
126+
casBackend.Name = backend.Provider
127+
if backend.GetLimits() != nil {
128+
casBackend.MaxSize = backend.GetLimits().MaxBytes
129+
}
130+
131+
// Only attempt to create a CAS connection when not inline and token is present
132+
if backend.IsInline || result.Token == "" {
133+
return nil, nil
134+
}
135+
136+
opts := []grpcconn.Option{grpcconn.WithInsecure(casConnectionInsecure)}
137+
if casCAPath != "" {
138+
opts = append(opts, grpcconn.WithCAFile(casCAPath))
139+
}
140+
141+
artifactCASConn, err := grpcconn.New(casURI, result.Token, opts...)
142+
if err != nil {
143+
logger.Warn().Err(err).Msg("failed to create CAS connection, will store inline")
144+
return nil, fmt.Errorf("creating CAS connection: %w", err)
145+
}
146+
147+
casBackend.Uploader = casclient.New(artifactCASConn, casclient.WithLogger(logger))
148+
return artifactCASConn.Close, nil
149+
}

app/cli/pkg/action/attestation_add.go

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"github.com/chainloop-dev/chainloop/pkg/attestation/crafter"
2525
api "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1"
2626
"github.com/chainloop-dev/chainloop/pkg/casclient"
27-
"github.com/chainloop-dev/chainloop/pkg/grpcconn"
2827
"google.golang.org/grpc"
2928
)
3029

@@ -98,40 +97,14 @@ func (action *AttestationAdd) Run(ctx context.Context, attestationID, materialNa
9897

9998
// Define CASbackend information based on the API response
10099
if !crafter.CraftingState.GetDryRun() {
101-
// Get upload creds and CASbackend for the current attestation and set up CAS client
102100
client := pb.NewAttestationServiceClient(action.CPConnection)
103-
creds, err := client.GetUploadCreds(ctx,
104-
&pb.AttestationServiceGetUploadCredsRequest{
105-
WorkflowRunId: crafter.CraftingState.GetAttestation().GetWorkflow().GetWorkflowRunId(),
106-
},
107-
)
108-
if err != nil {
109-
return nil, fmt.Errorf("getting upload creds: %w", err)
110-
}
111-
b := creds.GetResult().GetBackend()
112-
if b == nil {
113-
return nil, fmt.Errorf("no backend found in upload creds")
101+
workflowRunID := crafter.CraftingState.GetAttestation().GetWorkflow().GetWorkflowRunId()
102+
connectionCloserFn, getCASBackendErr := getCASBackend(ctx, client, workflowRunID, action.casCAPath, action.casURI, action.connectionInsecure, action.Logger, casBackend)
103+
if getCASBackendErr != nil {
104+
return nil, fmt.Errorf("failed to get CAS backend: %w", getCASBackendErr)
114105
}
115-
casBackend.Name = b.Provider
116-
casBackend.MaxSize = b.GetLimits().MaxBytes
117-
// Some CASBackends will actually upload information to the CAS server
118-
// in such case we need to set up a connection
119-
if !b.IsInline && creds.Result.Token != "" {
120-
var opts = []grpcconn.Option{
121-
grpcconn.WithInsecure(action.connectionInsecure),
122-
}
123-
124-
if action.casCAPath != "" {
125-
opts = append(opts, grpcconn.WithCAFile(action.casCAPath))
126-
}
127-
128-
artifactCASConn, err := grpcconn.New(action.casURI, creds.Result.Token, opts...)
129-
if err != nil {
130-
return nil, fmt.Errorf("creating CAS connection: %w", err)
131-
}
132-
defer artifactCASConn.Close()
133-
134-
casBackend.Uploader = casclient.New(artifactCASConn, casclient.WithLogger(action.Logger))
106+
if connectionCloserFn != nil {
107+
defer connectionCloserFn()
135108
}
136109
}
137110

app/cli/pkg/action/attestation_init.go

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
"github.com/chainloop-dev/chainloop/pkg/attestation/crafter"
2929
clientAPI "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1"
3030
"github.com/chainloop-dev/chainloop/pkg/casclient"
31-
"github.com/chainloop-dev/chainloop/pkg/grpcconn"
3231
"github.com/chainloop-dev/chainloop/pkg/policies"
3332
"github.com/rs/zerolog"
3433
)
@@ -233,38 +232,13 @@ func (action *AttestationInit) Run(ctx context.Context, opts *AttestationInitRun
233232
// Get CAS credentials for PR metadata upload
234233
var casBackend = &casclient.CASBackend{Name: "not-set"}
235234
if !action.dryRun && attestationID != "" {
236-
creds, err := client.GetUploadCreds(ctx,
237-
&pb.AttestationServiceGetUploadCredsRequest{
238-
WorkflowRunId: attestationID,
239-
},
240-
)
235+
connectionCloserFn, err := getCASBackend(ctx, client, attestationID, action.casCAPath, action.casURI, action.connectionInsecure, action.Logger, casBackend)
241236
if err != nil {
242-
// Log warning but don't fail - will fall back to inline storage
243-
action.Logger.Warn().Err(err).Msg("failed to get CAS credentials for PR metadata, will store inline")
244-
} else {
245-
b := creds.GetResult().GetBackend()
246-
if b != nil {
247-
casBackend.Name = b.Provider
248-
casBackend.MaxSize = b.GetLimits().MaxBytes
249-
250-
// Set up CAS connection if not inline
251-
if !b.IsInline && creds.Result.Token != "" {
252-
var opts = []grpcconn.Option{
253-
grpcconn.WithInsecure(action.connectionInsecure),
254-
}
255-
if action.casCAPath != "" {
256-
opts = append(opts, grpcconn.WithCAFile(action.casCAPath))
257-
}
258-
259-
artifactCASConn, err := grpcconn.New(action.casURI, creds.Result.Token, opts...)
260-
if err != nil {
261-
action.Logger.Warn().Err(err).Msg("failed to create CAS connection, will store inline")
262-
} else {
263-
defer artifactCASConn.Close()
264-
casBackend.Uploader = casclient.New(artifactCASConn, casclient.WithLogger(action.Logger))
265-
}
266-
}
267-
}
237+
// This should never happen in lenient mode, but handle it just in case
238+
action.Logger.Warn().Err(err).Msg("unexpected error getting CAS backend")
239+
}
240+
if connectionCloserFn != nil {
241+
defer connectionCloserFn()
268242
}
269243
}
270244

0 commit comments

Comments
 (0)