-
Notifications
You must be signed in to change notification settings - Fork 76
/
util.go
141 lines (126 loc) · 4.48 KB
/
util.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
package genutils
import (
"fmt"
)
import (
"golang.org/x/text/cases"
"golang.org/x/text/language"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
)
import (
"github.com/apache/dubbo-kubernetes/api/mesh"
core_model "github.com/apache/dubbo-kubernetes/pkg/core/resources/model"
)
// DubboResourceForMessage fetches the Dubbo resource option out of a message.
func DubboResourceForMessage(desc protoreflect.MessageDescriptor) *mesh.DubboResourceOptions {
ext := proto.GetExtension(desc.Options(), mesh.E_Resource)
var resOption *mesh.DubboResourceOptions
if r, ok := ext.(*mesh.DubboResourceOptions); ok {
resOption = r
}
return resOption
}
// SelectorsForMessage finds all the top-level fields in the message are
// repeated selectors. We want to generate convenience accessors for these.
func SelectorsForMessage(m protoreflect.MessageDescriptor) []string {
var selectors []string
fields := m.Fields()
for i := 0; i < fields.Len(); i++ {
field := fields.Get(i)
m := field.Message()
if m != nil && m.FullName() == "dubbo.mesh.v1alpha1.Selector" {
fieldName := string(field.Name())
caser := cases.Title(language.English)
selectors = append(selectors, caser.String(fieldName))
}
}
return selectors
}
type ResourceInfo struct {
ResourceName string
ResourceType string
ProtoType string
Selectors []string
SkipRegistration bool
SkipKubernetesWrappers bool
ScopeNamespace bool
Global bool
DubboctlSingular string
DubboctlPlural string
WsReadOnly bool
WsAdminOnly bool
WsPath string
DdsDirection string
AllowToInspect bool
StorageVersion bool
IsPolicy bool
SingularDisplayName string
PluralDisplayName string
IsExperimental bool
AdditionalPrinterColumns []string
HasInsights bool
}
func ToResourceInfo(desc protoreflect.MessageDescriptor) ResourceInfo {
r := DubboResourceForMessage(desc)
out := ResourceInfo{
ResourceType: r.Type,
ResourceName: r.Name,
ProtoType: string(desc.Name()),
Selectors: SelectorsForMessage(desc),
SkipRegistration: r.SkipRegistration,
SkipKubernetesWrappers: r.SkipKubernetesWrappers,
Global: r.Global,
ScopeNamespace: r.ScopeNamespace,
AllowToInspect: r.AllowToInspect,
StorageVersion: r.StorageVersion,
SingularDisplayName: core_model.DisplayName(r.Type),
PluralDisplayName: r.PluralDisplayName,
IsExperimental: r.IsExperimental,
AdditionalPrinterColumns: r.AdditionalPrinterColumns,
HasInsights: r.HasInsights,
}
if r.Ws != nil {
pluralResourceName := r.Ws.Plural
if pluralResourceName == "" {
pluralResourceName = r.Ws.Name + "s"
}
out.WsReadOnly = r.Ws.ReadOnly
out.WsAdminOnly = r.Ws.AdminOnly
out.WsPath = pluralResourceName
if !r.Ws.ReadOnly {
out.DubboctlSingular = r.Ws.Name
out.DubboctlPlural = pluralResourceName
// Keep the typo to preserve backward compatibility
if out.DubboctlSingular == "health-check" {
out.DubboctlSingular = "healthcheck"
out.DubboctlPlural = "healthchecks"
}
}
}
if out.PluralDisplayName == "" {
out.PluralDisplayName = core_model.PluralType(core_model.DisplayName(r.Type))
}
// Working around the fact we don't really differentiate policies from the rest of resources:
// Anything global can't be a policy as it need to be on a mesh. Anything with locked Ws config is something internal and therefore not a policy
out.IsPolicy = !out.SkipRegistration && !out.Global && !out.WsAdminOnly && !out.WsReadOnly && out.ResourceType != "Dataplane" && out.ResourceType != "ExternalService"
switch {
case r.Dds == nil || (!r.Dds.SendToZone && !r.Dds.SendToGlobal):
out.DdsDirection = ""
case r.Dds.SendToGlobal && r.Dds.SendToZone:
out.DdsDirection = "model.ZoneToGlobalFlag | model.GlobalToAllButOriginalZoneFlag"
case r.Dds.SendToGlobal:
out.DdsDirection = "model.ZoneToGlobalFlag"
case r.Dds.SendToZone:
out.DdsDirection = "model.GlobalToAllZonesFlag"
}
if out.ResourceType == "MeshGateway" {
out.DdsDirection = "model.ZoneToGlobalFlag | model.GlobalToAllZonesFlag"
}
if p := desc.Parent(); p != nil {
if _, ok := p.(protoreflect.MessageDescriptor); ok {
out.ProtoType = fmt.Sprintf("%s_%s", p.Name(), desc.Name())
}
}
return out
}