/
resource_with_id.go
149 lines (125 loc) · 4.05 KB
/
resource_with_id.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package resources
import (
"fmt"
"github.com/multycloud/multy/api/proto/commonpb"
pberr "github.com/multycloud/multy/api/proto/errorspb"
"github.com/multycloud/multy/resources/common"
"github.com/multycloud/multy/validate"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
type WithCommonParams interface {
GetCommonParameters() *commonpb.ResourceCommonArgs
proto.Message
}
type WithChildCommonParams interface {
GetCommonParameters() *commonpb.ChildResourceCommonArgs
proto.Message
}
type ResourceWithId[T WithCommonParams] struct {
ResourceId string
Args T
}
func (r *ResourceWithId[T]) GetCloudSpecificLocation() string {
if result, err := common.GetCloudLocation(r.GetLocation(), r.GetCloud()); err != nil {
validate.LogInternalError(err.Error())
return ""
} else {
return result
}
}
func (r *ResourceWithId[T]) GetLocation() commonpb.Location {
return r.Args.GetCommonParameters().GetLocation()
}
func (r *ResourceWithId[T]) GetResourceId() string {
return r.ResourceId
}
func (r *ResourceWithId[T]) GetResourceGroupId() string {
return r.Args.GetCommonParameters().GetResourceGroupId()
}
func (r *ResourceWithId[T]) GetCloud() commonpb.CloudProvider {
return r.Args.GetCommonParameters().CloudProvider
}
func (r *ResourceWithId[T]) ParseCloud(args T) commonpb.CloudProvider {
return args.GetCommonParameters().CloudProvider
}
func (r *ResourceWithId[T]) GetMetadata(m ResourceMetadatas) (ResourceMetadataInterface, error) {
converter, err := m.GetConverter(proto.MessageName(r.Args))
if err != nil {
return nil, err
}
return converter, nil
}
func (r *ResourceWithId[T]) Validate() (errs []validate.ValidationError) {
location := r.GetLocation()
if _, ok := common.LOCATION[location]; !ok {
errs = append(errs, validate.ValidationError{
ErrorMessage: fmt.Sprintf("location %s is not defined", location),
ResourceId: r.ResourceId,
FieldName: "location",
})
}
if r.Args.GetCommonParameters().ResourceGroupId == "" {
errs = append(errs, validate.ValidationError{
ErrorMessage: "resource group id cannot be empty",
ResourceId: r.ResourceId,
FieldName: "resource_group_id",
})
}
return errs
}
type ChildResourceWithId[ParentT Resource, ChildT WithChildCommonParams] struct {
ResourceId string
Args ChildT
Parent ParentT
Metadata ResourceMetadataInterface
}
func NewResource[T WithCommonParams](resourceId string, args T) ResourceWithId[T] {
return ResourceWithId[T]{
ResourceId: resourceId,
Args: args,
}
}
func NewChildResource[ParentT Resource, ChildT WithChildCommonParams](resourceId string, parent ParentT, args ChildT) ChildResourceWithId[ParentT, ChildT] {
return ChildResourceWithId[ParentT, ChildT]{
ResourceId: resourceId,
Args: args,
Parent: parent,
}
}
func (r *ResourceWithId[T]) NewValidationError(err error, field string) validate.ValidationError {
return NewError(err, r.ResourceId, field)
}
func NewError(err error, resourceId string, fieldName string) validate.ValidationError {
result := validate.ValidationError{
ErrorMessage: err.Error(),
ResourceId: resourceId,
FieldName: fieldName,
}
if s, ok := status.FromError(err); ok && s.Code() == codes.NotFound {
details := s.Details()[0].(*pberr.ResourceNotFoundDetails)
result.ResourceNotFound = true
result.ResourceNotFoundId = details.ResourceId
}
return result
}
func (r *ChildResourceWithId[A, B]) NewValidationError(err error, field string) validate.ValidationError {
return NewError(err, r.ResourceId, field)
}
func (r *ChildResourceWithId[A, B]) GetResourceId() string {
return r.ResourceId
}
func (r *ChildResourceWithId[A, B]) GetCloud() commonpb.CloudProvider {
return r.Parent.GetCloud()
}
func (r *ChildResourceWithId[A, B]) GetCloudSpecificLocation() string {
return r.Parent.GetCloudSpecificLocation()
}
func (r *ChildResourceWithId[A, B]) GetMetadata(m ResourceMetadatas) (ResourceMetadataInterface, error) {
converter, err := m.GetConverter(proto.MessageName(r.Args))
if err != nil {
return nil, err
}
return converter, nil
}