Skip to content

Commit

Permalink
feat: If artifact has been deleted, show a message to that effect in …
Browse files Browse the repository at this point in the history
…the iFrame in the UI (#8966)

* feat: return 404 from the backend when artifact is 'Deleted'; starting to figure out how to use SuperAgent node modules on front end

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: don't show download link if artifact has been deleted

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: show message on UI if artifact has been deleted

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: revert accidental rename

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: for consistency add setHTTPStatus() in the json case too

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: Artifact Server to return http status code based on underlying storage provider response

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: Artifact Server to return http status code based on underlying storage provider response

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: just use the standard 404 response from the server

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: bring in latest argoproj/pkg which contains S3 code change

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: comment

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: update unit test to account for 404 errors

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: handle empty directory

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: make lint happy

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: bring in latest pkg so we can use s3 KeyExists() method

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: logic on the UI side to prevent showing the download button if artifact was deleted

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: don't show download button is artifact has been deleted

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: unit test

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: lint errors in ui

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: separate out the ListObjects() method of s3 ArtifactDriver so that it can be unit tested

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: remove unnecessary return

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: remove accidental duplication of code

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: reverting the UI changes to prevent downloading the same file twice - to be revisited later

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: testify gomodule reverted since it wasn't working

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: revert testify back to 1.7.2 since 1.7.3 and 1.7.4 are broken

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: lint error

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: empty commit

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* feat: create ArgoError.HTTPCode() so as to make code more centrally located

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>

* fix: go.sum

Signed-off-by: Julie Vogelman <julie_vogelman@intuit.com>
  • Loading branch information
juliev0 authored Jun 27, 2022
1 parent cb781cf commit 443155d
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 60 deletions.
21 changes: 21 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"net/http"
)

// Externally visible error codes
Expand All @@ -22,6 +23,7 @@ const (
type ArgoError interface {
Error() string
Code() string
HTTPCode() int
JSON() []byte
}

Expand Down Expand Up @@ -138,6 +140,25 @@ func (e argoerr) JSON() []byte {
return j
}

func (e argoerr) HTTPCode() int {
switch e.Code() {
case CodeUnauthorized:
return http.StatusUnauthorized
case CodeForbidden:
return http.StatusForbidden
case CodeNotFound:
return http.StatusNotFound
case CodeBadRequest:
return http.StatusBadRequest
case CodeNotImplemented:
return http.StatusNotImplemented
case CodeTimeout, CodeInternal:
return http.StatusInternalServerError
default:
return http.StatusInternalServerError
}
}

// IsCode is a helper to determine if the error is of a specific code
func IsCode(code string, err error) bool {
if argoErr, ok := err.(argoerr); ok {
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/antonmedv/expr v1.9.0
github.com/argoproj-labs/argo-dataflow v0.10.2
github.com/argoproj/argo-events v0.17.1-0.20220223155401-ddda8800f9f8
github.com/argoproj/pkg v0.13.3
github.com/argoproj/pkg v0.13.6
github.com/blushft/go-diagrams v0.0.0-20201006005127-c78c821223d9
github.com/colinmarc/hdfs v1.1.4-0.20180805212432-9746310a4d31
github.com/coreos/go-oidc/v3 v3.2.0
Expand Down Expand Up @@ -89,7 +89,7 @@ require (
github.com/ajg/form v1.5.1 // indirect
github.com/andybalholm/brotli v1.0.3 // indirect
github.com/awalterschulze/gographviz v0.0.0-20200901124122-0eecad45bd71 // indirect
github.com/aws/aws-sdk-go v1.44.35 // indirect
github.com/aws/aws-sdk-go v1.44.39 // indirect
github.com/aws/aws-sdk-go-v2 v1.16.2 // indirect
github.com/aws/aws-sdk-go-v2/config v1.15.3 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.11.2 // indirect
Expand Down
10 changes: 4 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ github.com/argoproj-labs/go-git/v5 v5.4.4 h1:xXa015ZCEElgNMxaevPsK68oAsbjpmNGo9W
github.com/argoproj-labs/go-git/v5 v5.4.4/go.mod h1:Lv1K45bcCda9jDMEZCGCVuXSGdBaSGAXUvptnVtaEsA=
github.com/argoproj/argo-events v0.17.1-0.20220223155401-ddda8800f9f8 h1:LqF/eUExbdTg7MEHUJt4DfZIg5hJN5lneybM7u7MbWI=
github.com/argoproj/argo-events v0.17.1-0.20220223155401-ddda8800f9f8/go.mod h1:AhwDnZwUrrwPgN0CYFMfZQ7liL+G+iL4ujNiLMv2l58=
github.com/argoproj/pkg v0.13.3 h1:wqVtXRHsKeO30c/CzcA1CtlH9Xp7DmdQrI9Z+7St4Xw=
github.com/argoproj/pkg v0.13.3/go.mod h1:KAthBovziz1F4Eks58kQDRRyzMpVfMPHi8gAHPQj3U4=
github.com/argoproj/pkg v0.13.6 h1:36WPD9MNYECHcO1/R1pj6teYspiK7uMQLCgLGft2abM=
github.com/argoproj/pkg v0.13.6/go.mod h1:I698DoJBKuvNFaixh4vFl2C88cNIT1WS7KCbz5ewyF8=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
Expand All @@ -219,8 +219,8 @@ github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZo
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.44.35 h1:2h93BS8/j1WUrr8CmALGwHYHTR+WYMZyDcINstX1+YM=
github.com/aws/aws-sdk-go v1.44.35/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.39 h1:pMxYLqnuDidT0ZTDAhYC66fb3W3Yc+oShmfzEL4fTDI=
github.com/aws/aws-sdk-go v1.44.39/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go-v2 v1.7.1/go.mod h1:L5LuPC1ZgDr2xQS7AmIec/Jlc7O/Y1u2KxJyNVab250=
github.com/aws/aws-sdk-go-v2 v1.14.0/go.mod h1:ZA3Y8V0LrlWj63MQAnRHgKf/5QB//LSZCPNWlWrNGLU=
github.com/aws/aws-sdk-go-v2 v1.16.2 h1:fqlCk6Iy3bnCumtrLz9r3mJ/2gUT0pJ0wLFVIdWh+JA=
Expand Down Expand Up @@ -1038,7 +1038,6 @@ github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WT
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
github.com/minio/minio-go/v7 v7.0.28/go.mod h1:x81+AX5gHSfCSqw7jxRKHvxUXMlE5uKX0Vb75Xk5yYg=
github.com/minio/minio-go/v7 v7.0.29 h1:7md6lIq1s6zPzUiDRX1BVLHolA4pDM8RMQqIszaJbY0=
github.com/minio/minio-go/v7 v7.0.29/go.mod h1:x81+AX5gHSfCSqw7jxRKHvxUXMlE5uKX0Vb75Xk5yYg=
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
Expand Down Expand Up @@ -1329,7 +1328,6 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
Expand Down
35 changes: 25 additions & 10 deletions server/artifacts/artifact_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/env"

argoerrors "github.com/argoproj/argo-workflows/v3/errors"
"github.com/argoproj/argo-workflows/v3/persist/sqldb"
wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
"github.com/argoproj/argo-workflows/v3/server/auth"
Expand Down Expand Up @@ -168,15 +169,15 @@ func (a *ArtifactServer) GetArtifactFile(w http.ResponseWriter, r *http.Request)

objects, err := driver.ListObjects(artifact)
if err != nil {
a.serverInternalError(err, w)
a.httpFromError(err, w)
return
}
log.Debugf("this is a directory, artifact: %+v; files: %v", artifact, objects)

key, _ := artifact.GetKey()
for _, object := range objects {

// object is prefixed the key, we must trim it
// object is prefixed by the key, we must trim it
dir, file := path.Split(strings.TrimPrefix(object, key+"/"))

// if dir is empty string, we are in the root dir
Expand Down Expand Up @@ -214,11 +215,11 @@ func (a *ArtifactServer) GetArtifactFile(w http.ResponseWriter, r *http.Request)

} else { // stream the file itself
log.Debugf("not a directory, artifact: %+v", artifact)

err = a.returnArtifact(w, artifact, driver)

if err != nil {
a.serverInternalError(err, w)
return
a.httpFromError(err, w)
}
}

Expand Down Expand Up @@ -306,6 +307,7 @@ func (a *ArtifactServer) getArtifactByUID(w http.ResponseWriter, r *http.Request
}

log.WithFields(log.Fields{"uid": uid, "nodeId": nodeId, "artifactName": artifactName, "isInput": isInput}).Info("Download artifact")

err = a.returnArtifact(w, art, driver)

if err != nil {
Expand Down Expand Up @@ -344,14 +346,25 @@ func (a *ArtifactServer) httpBadRequestError(w http.ResponseWriter) {
}

func (a *ArtifactServer) httpFromError(err error, w http.ResponseWriter) {
if err == nil {
return
}
statusCode := http.StatusInternalServerError
e := &apierr.StatusError{}
if errors.As(err, &e) {
if errors.As(err, &e) { // check if it's a Kubernetes API error
// There is a http error code somewhere in the error stack
statusCode := int(e.Status().Code)
http.Error(w, http.StatusText(statusCode), statusCode)
statusCode = int(e.Status().Code)
} else {
// Unknown error - return internal error
a.serverInternalError(err, w)
// check if it's an internal ArgoError
argoerr, typeOkay := err.(argoerrors.ArgoError)
if typeOkay {
statusCode = argoerr.HTTPCode()
}
}

http.Error(w, http.StatusText(statusCode), statusCode)
if statusCode == http.StatusInternalServerError {
log.WithError(err).Error("Artifact Server returned internal error")
}
}

Expand Down Expand Up @@ -415,7 +428,9 @@ func (a *ArtifactServer) returnArtifact(w http.ResponseWriter, art *wfv1.Artifac

_, err = io.Copy(w, stream)
if err != nil {
http.Error(w, fmt.Sprintf("failed to stream artifact: %v", err), http.StatusInternalServerError)
errStr := fmt.Sprintf("failed to stream artifact: %v", err)
http.Error(w, errStr, http.StatusInternalServerError)
return errors.New(errStr)
} else {
w.WriteHeader(http.StatusOK)
}
Expand Down
83 changes: 48 additions & 35 deletions server/artifacts/artifact_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (

apierr "k8s.io/apimachinery/pkg/api/errors"

argoerrors "github.com/argoproj/argo-workflows/v3/errors"

"github.com/stretchr/testify/assert"
testhttp "github.com/stretchr/testify/http"
"github.com/stretchr/testify/mock"
Expand Down Expand Up @@ -56,8 +58,10 @@ func (a *fakeArtifactDriver) OpenStream(artifact *wfv1.Artifact) (io.ReadCloser,
if err != nil {
return nil, err
}
if strings.HasSuffix(key, "notafile.txt") {
return nil, errors.New("not a valid file")
if strings.HasSuffix(key, "deletedFile.txt") {
return nil, argoerrors.New(argoerrors.CodeNotFound, "file deleted")
} else if strings.HasSuffix(key, "somethingElseWentWrong.txt") {
return nil, errors.New("whatever")
}
return io.NopCloser(bytes.NewReader(a.data)), nil
}
Expand Down Expand Up @@ -203,25 +207,26 @@ func TestArtifactServer_GetArtifactFile(t *testing.T) {
tests := []struct {
path string
// expected results:
redirect bool
location string
success bool
statusCode int
//redirect bool
location string
//success bool
isDirectory bool
directoryFiles []string // verify these files are in there, if this is a directory
}{
{
path: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory",
redirect: true,
location: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/",
path: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory",
statusCode: 307, // redirect
location: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/",
},
{
path: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/",
redirect: true,
location: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/index.html",
path: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/",
statusCode: 307, // redirect
location: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/index.html",
},
{
path: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/subdirectory/",
success: true,
statusCode: 200,
isDirectory: true,
directoryFiles: []string{
"..",
Expand All @@ -231,17 +236,22 @@ func TestArtifactServer_GetArtifactFile(t *testing.T) {
},
{
path: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/a.txt",
success: true,
statusCode: 200,
isDirectory: false,
},
{
path: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/subdirectory/b.txt",
success: true,
statusCode: 200,
isDirectory: false,
},
{
path: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/deletedFile.txt",
statusCode: 404,
isDirectory: false,
},
{
path: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/notafile.txt",
success: false,
path: "/artifact-files/my-ns/workflows/my-wf/my-node/outputs/my-s3-artifact-directory/somethingElseWentWrong.txt",
statusCode: 500,
isDirectory: false,
},
}
Expand All @@ -253,28 +263,25 @@ func TestArtifactServer_GetArtifactFile(t *testing.T) {
recorder := httptest.NewRecorder()

s.GetArtifactFile(recorder, r)
if tt.redirect {
assert.Equal(t, 307, recorder.Result().StatusCode)
assert.Equal(t, tt.statusCode, recorder.Result().StatusCode)
if tt.statusCode >= 300 && tt.statusCode <= 399 { // redirect
assert.Equal(t, tt.location, recorder.Header().Get("Location"))
} else if tt.success {
if assert.Equal(t, 200, recorder.Result().StatusCode) {
all, err := io.ReadAll(recorder.Result().Body)
if err != nil {
panic(fmt.Sprintf("failed to read http body: %v", err))
}
if tt.isDirectory {
fmt.Printf("got directory listing:\n%s\n", all)
// verify that the files are contained in the listing we got back
assert.Equal(t, len(tt.directoryFiles), strings.Count(string(all), "<li>"))
for _, file := range tt.directoryFiles {
assert.True(t, strings.Contains(string(all), file))
}
} else {
assert.Equal(t, "my-data", string(all))
} else if tt.statusCode >= 200 && tt.statusCode <= 299 { // success
all, err := io.ReadAll(recorder.Result().Body)
if err != nil {
panic(fmt.Sprintf("failed to read http body: %v", err))
}
if tt.isDirectory {
fmt.Printf("got directory listing:\n%s\n", all)
// verify that the files are contained in the listing we got back
assert.Equal(t, len(tt.directoryFiles), strings.Count(string(all), "<li>"))
for _, file := range tt.directoryFiles {
assert.True(t, strings.Contains(string(all), file))
}
} else {
assert.Equal(t, "my-data", string(all))
}
} else {
assert.NotEqual(t, 200, recorder.Result().StatusCode)

}
})
}
Expand Down Expand Up @@ -426,4 +433,10 @@ func TestArtifactServer_httpFromError(t *testing.T) {

assert.Equal(t, http.StatusUnauthorized, w.StatusCode)
assert.Contains(t, w.Output, "Unauthorized")

w = &testhttp.TestResponseWriter{}
err = argoerrors.New(argoerrors.CodeNotFound, "not found")

s.httpFromError(err, w)
assert.Equal(t, http.StatusNotFound, w.StatusCode)
}
33 changes: 27 additions & 6 deletions workflow/artifacts/s3/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,28 +206,49 @@ func saveS3Artifact(s3cli argos3.S3Client, path string, outputArtifact *wfv1.Art
return true, nil
}

// ListObjects returns the files inside the directory represented by the Artifact
func (s3Driver *ArtifactDriver) ListObjects(artifact *wfv1.Artifact) ([]string, error) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

var files []string
var done bool
err := waitutil.Backoff(executorretry.ExecutorRetry,
func() (bool, error) {
s3cli, err := s3Driver.newS3Client(ctx)
if err != nil {
return !isTransientS3Err(err), fmt.Errorf("failed to create new S3 client: %v", err)
}
files, err = s3cli.ListDirectory(artifact.S3.Bucket, artifact.S3.Key)
if err != nil {
return !isTransientS3Err(err), fmt.Errorf("failed to list directory: %v", err)
}
log.Debugf("successfully listing S3 directory associated with bucket: %s and key %s: %v", artifact.S3.Bucket, artifact.S3.Key, files)
return true, nil
done, files, err = listObjects(s3cli, artifact)
return done, err
})

return files, err
}

// listObjects returns the files inside the directory represented by the Artifact
// returns true if success or can't be retried (non-transient error)
// returns false if it can be retried (transient error)
func listObjects(s3cli argos3.S3Client, artifact *wfv1.Artifact) (bool, []string, error) {
var files []string
files, err := s3cli.ListDirectory(artifact.S3.Bucket, artifact.S3.Key)
if err != nil {
return !isTransientS3Err(err), files, fmt.Errorf("failed to list directory: %v", err)
}
log.Debugf("successfully listing S3 directory associated with bucket: %s and key %s: %v", artifact.S3.Bucket, artifact.S3.Key, files)

if len(files) == 0 {
directoryExists, err := s3cli.KeyExists(artifact.S3.Bucket, artifact.S3.Key)
if err != nil {
return !isTransientS3Err(err), files, fmt.Errorf("failed to check if key %s exists from bucket %s: %v", artifact.S3.Key, artifact.S3.Bucket, err)
}
if !directoryExists {
return true, files, errors.New(errors.CodeNotFound, fmt.Sprintf("no key found of name %s", artifact.S3.Key))
}
}
return true, files, nil
}

func (s3Driver *ArtifactDriver) IsDirectory(artifact *wfv1.Artifact) (bool, error) {
s3cli, err := s3Driver.newS3Client(context.TODO())
if err != nil {
Expand Down
Loading

0 comments on commit 443155d

Please sign in to comment.