• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

goto / guardian / 17695496595

13 Sep 2025 10:46AM UTC coverage: 70.095%. First build
17695496595

push

github

rahmatrhd
feat: introduce create resource API

0 of 65 new or added lines in 5 files covered. (0.0%)

11319 of 16148 relevant lines covered (70.1%)

4.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.74
/api/handler/v1beta1/resource.go
1
package v1beta1
2

3
import (
4
        "context"
5
        "errors"
6
        "fmt"
7
        "strings"
8

9
        "golang.org/x/sync/errgroup"
10

11
        "github.com/google/uuid"
12
        guardianv1beta1 "github.com/goto/guardian/api/proto/gotocompany/guardian/v1beta1"
13
        "github.com/goto/guardian/core/provider"
14
        "github.com/goto/guardian/core/resource"
15
        "github.com/goto/guardian/domain"
16
        "google.golang.org/grpc/codes"
17
        "google.golang.org/grpc/status"
18
)
19

NEW
20
func (s *GRPCServer) CreateResource(ctx context.Context, req *guardianv1beta1.CreateResourceRequest) (*guardianv1beta1.CreateResourceResponse, error) {
×
NEW
21
        r := s.adapter.FromResourceProto(req.GetResource())
×
NEW
22

×
NEW
23
        if err := s.providerService.CreateResource(ctx, r); err != nil {
×
NEW
24
                switch {
×
NEW
25
                case errors.Is(err, provider.ErrRecordNotFound):
×
NEW
26
                        return nil, status.Error(codes.NotFound, fmt.Sprintf("provider with type %q and urn %q does not exist", r.ProviderType, r.ProviderURN))
×
27
                case errors.Is(err, provider.ErrInvalidResourceType),
28
                        errors.Is(err, provider.ErrInvalidResource),
NEW
29
                        errors.Is(err, resource.ErrInvalidResource):
×
NEW
30
                        return nil, status.Error(codes.InvalidArgument, err.Error())
×
NEW
31
                default:
×
NEW
32
                        return nil, s.internalError(ctx, err.Error())
×
33
                }
34
        }
35

NEW
36
        resourceProto, err := s.adapter.ToResourceProto(r)
×
NEW
37
        if err != nil {
×
NEW
38
                return nil, s.internalError(ctx, "failed to convert to resource proto: %v", err)
×
NEW
39
        }
×
40

NEW
41
        return &guardianv1beta1.CreateResourceResponse{
×
NEW
42
                Resource: resourceProto,
×
NEW
43
        }, nil
×
44
}
45

46
func (s *GRPCServer) ListResources(ctx context.Context, req *guardianv1beta1.ListResourcesRequest) (*guardianv1beta1.ListResourcesResponse, error) {
3✔
47
        var details map[string]string
3✔
48
        if req.GetDetails() != nil {
4✔
49
                details = map[string]string{}
1✔
50
                for _, d := range req.GetDetails() {
3✔
51
                        filter := strings.Split(d, ":")
2✔
52
                        if len(filter) == 2 {
4✔
53
                                path := filter[0]
2✔
54
                                value := filter[1]
2✔
55
                                details[path] = value
2✔
56
                        }
2✔
57
                }
58
        }
59
        filter := domain.ListResourcesFilter{
3✔
60
                IsDeleted:    req.GetIsDeleted(),
3✔
61
                ResourceType: req.GetType(),
3✔
62
                ResourceURN:  req.GetUrn(),
3✔
63
                ProviderType: req.GetProviderType(),
3✔
64
                ProviderURN:  req.GetProviderUrn(),
3✔
65
                Name:         req.GetName(),
3✔
66
                Details:      details,
3✔
67
                Size:         req.GetSize(),
3✔
68
                Offset:       req.GetOffset(),
3✔
69
                OrderBy:      req.GetOrderBy(),
3✔
70
                Q:            req.GetQ(),
3✔
71
        }
3✔
72

3✔
73
        resources, total, err := s.listResources(ctx, filter)
3✔
74
        if err != nil {
5✔
75
                return nil, err
2✔
76
        }
2✔
77

78
        return &guardianv1beta1.ListResourcesResponse{
1✔
79
                Resources: resources,
1✔
80
                Total:     uint32(total),
1✔
81
        }, nil
1✔
82
}
83

84
func (s *GRPCServer) listResources(ctx context.Context, filter domain.ListResourcesFilter) ([]*guardianv1beta1.Resource, int64, error) {
3✔
85
        eg, ctx := errgroup.WithContext(ctx)
3✔
86
        var resources []*domain.Resource
3✔
87
        var total int64
3✔
88

3✔
89
        eg.Go(func() error {
6✔
90
                resourceRecords, err := s.resourceService.Find(ctx, filter)
3✔
91
                if err != nil {
4✔
92
                        return s.internalError(ctx, "failed to get resource list: %s", err)
1✔
93
                }
1✔
94
                resources = resourceRecords
2✔
95
                return nil
2✔
96
        })
97
        eg.Go(func() error {
6✔
98
                totalRecord, err := s.resourceService.GetResourcesTotalCount(ctx, filter)
3✔
99
                if err != nil {
3✔
100
                        return s.internalError(ctx, "failed to get resource total count: %s", err)
×
101
                }
×
102
                total = totalRecord
3✔
103
                return nil
3✔
104
        })
105

106
        if err := eg.Wait(); err != nil {
4✔
107
                return nil, 0, err
1✔
108
        }
1✔
109
        var resourceProtos []*guardianv1beta1.Resource
2✔
110
        for i, r := range resources {
4✔
111
                resourceProto, err := s.adapter.ToResourceProto(resources[i])
2✔
112
                if err != nil {
3✔
113
                        return nil, 0, s.internalError(ctx, "failed to parse resource %v: %v", r.Name, err)
1✔
114
                }
1✔
115
                resourceProtos = append(resourceProtos, resourceProto)
1✔
116
        }
117

118
        return resourceProtos, total, nil
1✔
119
}
120

121
func (s *GRPCServer) GetResource(ctx context.Context, req *guardianv1beta1.GetResourceRequest) (*guardianv1beta1.GetResourceResponse, error) {
4✔
122
        r, err := s.resourceService.GetOne(ctx, req.GetId())
4✔
123
        if err != nil {
6✔
124
                switch err {
2✔
125
                case resource.ErrRecordNotFound:
1✔
126
                        return nil, status.Error(codes.NotFound, "resource not found")
1✔
127
                default:
1✔
128
                        return nil, s.internalError(ctx, "failed to retrieve resource: %v", err)
1✔
129
                }
130
        }
131

132
        resourceProto, err := s.adapter.ToResourceProto(r)
2✔
133
        if err != nil {
3✔
134
                return nil, s.internalError(ctx, "failed to parse resource: %v", err)
1✔
135
        }
1✔
136

137
        return &guardianv1beta1.GetResourceResponse{
1✔
138
                Resource: resourceProto,
1✔
139
        }, nil
1✔
140
}
141

142
func (s *GRPCServer) UpdateResource(ctx context.Context, req *guardianv1beta1.UpdateResourceRequest) (*guardianv1beta1.UpdateResourceResponse, error) {
4✔
143
        r := s.adapter.FromResourceProto(req.GetResource())
4✔
144

4✔
145
        if _, err := uuid.Parse(req.GetId()); err != nil {
7✔
146
                r.GlobalURN = req.GetId()
3✔
147
        } else {
4✔
148
                r.ID = req.GetId()
1✔
149
        }
1✔
150

151
        if err := s.resourceService.Update(ctx, r); err != nil {
6✔
152
                if errors.Is(err, resource.ErrRecordNotFound) {
3✔
153
                        return nil, status.Error(codes.NotFound, "resource not found")
1✔
154
                }
1✔
155
                return nil, s.internalError(ctx, "failed to update resource: %v", err)
1✔
156
        }
157

158
        resourceProto, err := s.adapter.ToResourceProto(r)
2✔
159
        if err != nil {
3✔
160
                return nil, s.internalError(ctx, "failed to parse resource: %v", err)
1✔
161
        }
1✔
162

163
        return &guardianv1beta1.UpdateResourceResponse{
1✔
164
                Resource: resourceProto,
1✔
165
        }, nil
1✔
166
}
167

168
func (s *GRPCServer) DeleteResource(ctx context.Context, req *guardianv1beta1.DeleteResourceRequest) (*guardianv1beta1.DeleteResourceResponse, error) {
3✔
169
        if err := s.resourceService.Delete(ctx, req.GetId()); err != nil {
5✔
170
                if errors.Is(err, resource.ErrRecordNotFound) {
3✔
171
                        return nil, status.Errorf(codes.NotFound, "resource not found")
1✔
172
                }
1✔
173
                return nil, s.internalError(ctx, "failed to update resource: %v", err)
1✔
174
        }
175

176
        return &guardianv1beta1.DeleteResourceResponse{}, nil
1✔
177
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc