| 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 |
| } |