diff --git a/cloud/aws/runtime/keyvalue/dynamodb.go b/cloud/aws/runtime/keyvalue/dynamodb.go index 14726af4b..7aa306e79 100644 --- a/cloud/aws/runtime/keyvalue/dynamodb.go +++ b/cloud/aws/runtime/keyvalue/dynamodb.go @@ -113,7 +113,7 @@ func (s *DynamoKeyValueService) Get(ctx context.Context, req *keyvaluepb.KeyValu if result.Item == nil { return nil, newErr( codes.NotFound, - fmt.Sprintf("%v not found", req.Ref), + fmt.Sprintf("key %s not found in store %s", req.Ref.Key, req.Ref.Store), err, ) } diff --git a/cloud/azure/deploy/api.go b/cloud/azure/deploy/api.go index 414e7d5b0..5ef10965d 100644 --- a/cloud/azure/deploy/api.go +++ b/cloud/azure/deploy/api.go @@ -19,6 +19,7 @@ import ( "strings" "github.com/nitrictech/nitric/cloud/common/deploy/resources" + "github.com/nitrictech/nitric/core/pkg/logger" deploymentspb "github.com/nitrictech/nitric/core/pkg/proto/deployments/v1" "github.com/getkin/kin-openapi/openapi3" @@ -81,6 +82,11 @@ func (p *NitricAzurePulumiProvider) Api(ctx *pulumi.Context, parent pulumi.Resou return fmt.Errorf("invalid document supplied for api: %s", name) } + if len(openapiDoc.Paths) < 1 { + logger.Warnf("skipping deployment of API %s, no routes defined", name) + return nil + } + managedIdentities := p.containerEnv.ManagedUser.ID().ToStringOutput().ApplyT(func(id string) apimanagement.UserIdentityPropertiesMapOutput { return apimanagement.UserIdentityPropertiesMap{ id: nil, diff --git a/cloud/azure/deploy/bucket.go b/cloud/azure/deploy/bucket.go index 0fa4b0316..d6a5acd1f 100644 --- a/cloud/azure/deploy/bucket.go +++ b/cloud/azure/deploy/bucket.go @@ -38,19 +38,19 @@ func eventTypeToStorageEventType(eventType *storagepb.BlobEventType) []string { func (p *NitricAzurePulumiProvider) newAzureBucketNotification(ctx *pulumi.Context, parent pulumi.Resource, bucketName string, config *deploymentspb.BucketListener) error { target, ok := p.containerApps[config.GetService()] if !ok { - return fmt.Errorf("") + return fmt.Errorf("target container app %s not found", config.GetService()) } bucket, ok := p.buckets[bucketName] if !ok { - return fmt.Errorf("") + return fmt.Errorf("target bucket %s not found", bucketName) } opts := []pulumi.ResourceOption{pulumi.Parent(parent), pulumi.DependsOn([]pulumi.Resource{target.App, bucket})} hostUrl, err := target.HostUrl() if err != nil { - return err + return fmt.Errorf("unable to determine container app host URL: %w", err) } _, err = pulumiEventgrid.NewEventSubscription(ctx, ResourceName(ctx, bucketName+target.Name, EventSubscriptionRT), &pulumiEventgrid.EventSubscriptionArgs{ @@ -91,7 +91,7 @@ func (p *NitricAzurePulumiProvider) Bucket(ctx *pulumi.Context, parent pulumi.Re } for _, sub := range config.Listeners { - err = p.newAzureBucketNotification(ctx, parent, name+sub.GetService(), sub) + err = p.newAzureBucketNotification(ctx, parent, name, sub) if err != nil { return err } diff --git a/cloud/azure/runtime/keyvalue/keyvalue.go b/cloud/azure/runtime/keyvalue/keyvalue.go index 5961ea78d..521a6b530 100644 --- a/cloud/azure/runtime/keyvalue/keyvalue.go +++ b/cloud/azure/runtime/keyvalue/keyvalue.go @@ -18,8 +18,10 @@ import ( "context" "encoding/json" "fmt" + "net/http" "time" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/data/aztables" "github.com/nitrictech/nitric/cloud/azure/runtime/env" @@ -68,8 +70,21 @@ func (s *AzureStorageTableKeyValueService) Get(ctx context.Context, req *keyvalu response, err := client.GetEntity(ctx, req.Ref.Store, req.Ref.Key, nil) if err != nil { + var respErr *azcore.ResponseError + if errors.As(err, &respErr) { + switch respErr.StatusCode { + case http.StatusNotFound: + // Handle not found error + return nil, newErr( + codes.NotFound, + fmt.Sprintf("key %s not found in store %s", req.Ref.Key, req.Ref.Store), + err, + ) + } + } + return nil, newErr( - codes.InvalidArgument, + codes.Unknown, "failed to call aztables:GetEntity", err, ) @@ -186,6 +201,15 @@ func (s *AzureStorageTableKeyValueService) Delete(ctx context.Context, req *keyv _, err = client.DeleteEntity(ctx, req.Ref.Store, req.Ref.Key, nil) if err != nil { + var respErr *azcore.ResponseError + if errors.As(err, &respErr) { + switch respErr.StatusCode { + case http.StatusNotFound: + // not found isn't an error for delete + return &keyvaluepb.KeyValueDeleteResponse{}, nil + } + } + return nil, newErr( codes.Internal, "failed to call aztables.DeleteEntity", diff --git a/cloud/gcp/runtime/keyvalue/firestore.go b/cloud/gcp/runtime/keyvalue/firestore.go index 553e622f1..cb360d142 100644 --- a/cloud/gcp/runtime/keyvalue/firestore.go +++ b/cloud/gcp/runtime/keyvalue/firestore.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package document +package keyvalue import ( "context" @@ -23,7 +23,6 @@ import ( v1 "github.com/nitrictech/nitric/core/pkg/proto/keyvalue/v1" "google.golang.org/grpc/codes" - grpcCodes "google.golang.org/grpc/codes" "google.golang.org/protobuf/types/known/structpb" "cloud.google.com/go/firestore" @@ -53,10 +52,17 @@ func (s *FirestoreDocService) Get(ctx context.Context, req *v1.KeyValueGetReques value, err := doc.Get(ctx) if err != nil { - if status.Code(err) == grpcCodes.PermissionDenied { + switch status.Code(err) { + case codes.NotFound: + return nil, newErr( + codes.NotFound, + fmt.Sprintf("key %s not found in store %s", req.Ref.Key, req.Ref.Store), + err, + ) + case codes.PermissionDenied: return nil, newErr( codes.PermissionDenied, - "permission denied, have you requested access to this collection?", + "permission denied, have you requested access to this key value store?", err, ) } @@ -107,10 +113,10 @@ func (s *FirestoreDocService) Set(ctx context.Context, req *v1.KeyValueSetReques doc := s.getDocRef(req.Ref) if _, err := doc.Set(ctx, req.Content.AsMap()); err != nil { - if status.Code(err) == grpcCodes.PermissionDenied { + if status.Code(err) == codes.PermissionDenied { return nil, newErr( codes.PermissionDenied, - "permission denied, have you requested access to this collection?", + "permission denied, have you requested access to this key value store?", err, ) } @@ -140,10 +146,10 @@ func (s *FirestoreDocService) Delete(ctx context.Context, req *v1.KeyValueDelete // Delete document if _, err := doc.Delete(ctx); err != nil { - if status.Code(err) == grpcCodes.PermissionDenied { + if status.Code(err) == codes.PermissionDenied { return nil, newErr( codes.PermissionDenied, - "permission denied, have you requested access to this collection?", + "permission denied, have you requested access to this key value store?", err, ) }