@opensoha/contracts 0.1.24 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPATIBILITY.md +24 -0
- package/README.md +1 -1
- package/agent/environment/export.go +1 -0
- package/agent/environment/protocol_test.go +1 -1
- package/agent/guest/protocol_test.go +2 -2
- package/auth/catalog_generated.go +2 -2
- package/auth/gateway_permissions_test.go +48 -0
- package/auth/permission-catalog.json +300 -1
- package/compat/consumer-revisions.json +1 -1
- package/compat/json-schema-ecosystem-0.1.0.json +1 -1
- package/compat/openapi-loose-boundaries-0.1.0.json +1 -1
- package/delivery/document.schema.json +127 -9
- package/examples/relations_compat_test.go +18 -0
- package/fixtures/openapi/DeliveryDocument/invalid/migration-missing-guide-build-template.json +30 -0
- package/fixtures/openapi/DeliveryDocument/invalid/migration-missing-guide-deployment-template.json +30 -0
- package/fixtures/openapi/DeliveryDocument/invalid/migration-missing-guide-workflow-template.json +27 -0
- package/fixtures/openapi/DeliveryDocument/valid/migration-build-template.json +31 -0
- package/fixtures/openapi/DeliveryDocument/valid/migration-deployment-template.json +31 -0
- package/fixtures/openapi/DeliveryDocument/valid/migration-workflow-template.json +28 -0
- package/fixtures/openapi/DeliveryPlanInput/invalid/manual-plan.json +7 -0
- package/fixtures/openapi/DeliveryPlanInput/valid/manual-plan.json +6 -0
- package/fixtures/openapi/DeliveryTargetInput/invalid/candidate-on-runtime-deploy.json +9 -0
- package/fixtures/openapi/DeliveryTargetInput/invalid/config-update-missing-service.json +7 -0
- package/fixtures/openapi/DeliveryTargetInput/valid/template-configuration-only.json +8 -0
- package/fixtures/openapi/DeliveryTargetInput/valid/template-configuration-without-runtime-environment.json +1 -0
- package/fixtures/openapi/KubernetesAgentActionCheck/invalid/unproven-state.json +6 -0
- package/fixtures/openapi/KubernetesAgentActionCheck/valid/configured-denied.json +9 -0
- package/fixtures/openapi/KubernetesAgentActionProfile/invalid/wildcard.json +1 -0
- package/fixtures/openapi/KubernetesAgentActionProfile/valid/workbench.json +1 -0
- package/fixtures/openapi/KubernetesClusterRegistrationRequest/invalid/action-profile.json +3 -0
- package/fixtures/openapi/KubernetesClusterRegistrationRequest/valid/action-profile.json +5 -0
- package/fixtures/openapi/KubernetesImportCandidateListEnvelope/invalid/source-with-spec.json +33 -0
- package/fixtures/openapi/KubernetesImportCandidateListEnvelope/invalid/source-without-uid.json +29 -0
- package/fixtures/openapi/KubernetesImportCandidateListEnvelope/valid/stable-source.json +30 -0
- package/fixtures/openapi/KubernetesNodeListEnvelope/invalid/condition-status-boolean.json +17 -0
- package/fixtures/openapi/KubernetesNodeListEnvelope/invalid/taint-effect-missing.json +16 -0
- package/fixtures/openapi/KubernetesNodeListEnvelope/valid/legacy-fields-absent.json +11 -0
- package/fixtures/openapi/KubernetesNodeListEnvelope/valid/no-taints.json +13 -0
- package/fixtures/openapi/KubernetesNodeListEnvelope/valid/ready-cordoned-tainted.json +28 -0
- package/fixtures/openapi/KubernetesNodeListEnvelope/valid/unknown-fields-null.json +13 -0
- package/fixtures/openapi/KubernetesPod/invalid/pod-uid.json +9 -0
- package/fixtures/openapi/KubernetesPod/valid/pod-uid.json +9 -0
- package/fixtures/openapi/KubernetesPodDetail/invalid/pod-uid.json +6 -0
- package/fixtures/openapi/KubernetesPodDetail/valid/pod-uid.json +6 -0
- package/fixtures/openapi/KubernetesServiceImportRequest/invalid/empty-source-uid.json +48 -0
- package/fixtures/openapi/KubernetesServiceImportRequest/valid/pinned-workloads-and-cr.json +48 -0
- package/fixtures/openapi/KubernetesTopologyCoverage/invalid/empty-as-success.json +5 -0
- package/fixtures/openapi/KubernetesTopologyCoverage/valid/not-installed.json +6 -0
- package/fixtures/openapi/KubernetesTopologyGraphEdge/invalid/negative-weight.json +8 -0
- package/fixtures/openapi/KubernetesTopologyGraphEdge/valid/zero-weight.json +20 -0
- package/fixtures/openapi/KubernetesTopologyGraphNode/invalid/fake-flow-kind.json +42 -0
- package/fixtures/openapi/KubernetesTopologyGraphNode/valid/rule.json +42 -0
- package/fixtures/openapi/KubernetesTopologySnapshot/invalid/raw-source-field.json +33 -0
- package/fixtures/openapi/KubernetesTopologySnapshot/valid/projected-source.json +32 -0
- package/fixtures/openapi/KubernetesTopologySnapshotRequest/invalid/arbitrary-gvr.json +8 -0
- package/fixtures/openapi/KubernetesTopologySnapshotRequest/valid/bounded-sources.json +11 -0
- package/fixtures/openapi/KubernetesTopologySourceQuery/invalid/cluster-namespace.json +4 -0
- package/fixtures/openapi/KubernetesTopologySourceQuery/valid/all-namespaces.json +4 -0
- package/fixtures/openapi/ManifestExecutionTaskPayload/invalid/initialization.json +7 -0
- package/fixtures/openapi/ManifestExecutionTaskPayload/valid/initialization.json +7 -0
- package/fixtures/openapi/ManifestRootResource/invalid/root.json +1 -0
- package/fixtures/openapi/ManifestRootResource/valid/root.json +1 -0
- package/fixtures/openapi/ResourceMonitoringPanel/invalid/unknown-quality.json +7 -0
- package/fixtures/openapi/ResourceMonitoringPanel/valid/not-collected.json +7 -0
- package/fixtures/openapi/ResourceMonitoringPoint/invalid/string-zero.json +4 -0
- package/fixtures/openapi/ResourceMonitoringPoint/valid/missing.json +4 -0
- package/fixtures/openapi/ResourceMonitoringPoint/valid/zero.json +4 -0
- package/fixtures/openapi/ResourceMonitoringView/invalid/raw-query.json +12 -0
- package/fixtures/openapi/ResourceMonitoringView/valid/unconfigured.json +12 -0
- package/fixtures/openapi/ResourceRelationConfig/invalid/executable-rule.json +17 -0
- package/fixtures/openapi/ResourceRelationConfig/valid/unknown-kind.json +13 -0
- package/fixtures/openapi/ServiceDeploymentTemplateInput/invalid/migration-missing-guide-valid-yaml.json +38 -0
- package/fixtures/openapi/ServiceDeploymentTemplateInput/valid/migration-valid-yaml.json +39 -0
- package/fixtures/openapi/TemplateMigrationAssessment/invalid/initialization.json +9 -0
- package/fixtures/openapi/TemplateMigrationAssessment/valid/initialization.json +9 -0
- package/fixtures/openapi/TemplateMigrationPolicy/invalid/blank-guide.json +5 -0
- package/fixtures/openapi/TemplateMigrationPolicy/invalid/missing-guide.json +4 -0
- package/fixtures/openapi/TemplateMigrationPolicy/invalid/unknown-escape-hatch.json +6 -0
- package/fixtures/openapi/TemplateMigrationPolicy/valid/legacy-safe.json +4 -0
- package/fixtures/openapi/TemplateMigrationPolicy/valid/ordered-data-change.json +5 -0
- package/fixtures/openapi/TemplateUpdateBatchInput/invalid/duplicate-candidates.json +11 -0
- package/fixtures/openapi/TemplateUpdateBatchInput/invalid/empty-identities.json +10 -0
- package/fixtures/openapi/TemplateUpdateBatchInput/valid/staged-adoption.json +10 -0
- package/fixtures/openapi/TemplateUpdatePolicyInput/invalid/unknown-mode.json +8 -0
- package/fixtures/openapi/TemplateUpdatePolicyInput/valid/explicit-automatic.json +8 -0
- package/fixtures/openapi/TemplateUpdatePreviewInput/invalid/empty-identities.json +10 -0
- package/fixtures/openapi/TemplateUpdatePreviewInput/invalid/empty-targets.json +6 -0
- package/fixtures/openapi/TemplateUpdatePreviewInput/valid/cross-version-manual.json +14 -0
- package/gen/go/sohaapi/client.go +1 -1
- package/gen/go/sohaapi/client_test.go +2 -2
- package/gen/go/sohaapi/import_source_compat_test.go +12 -0
- package/gen/go/sohaapi/kubernetes_monitoring_test.go +67 -0
- package/gen/go/sohaapi/types.go +2210 -387
- package/gen/ts/sohaapi/index.ts +1862 -5
- package/go.mod +2 -2
- package/helmrelease/delivery.go +4 -1
- package/helmrelease/initialization.go +10 -0
- package/helmrelease/runtime/delivery.go +40 -10
- package/helmrelease/runtime/delivery_test.go +4 -0
- package/helmrelease/runtime/initialization.go +186 -0
- package/helmrelease/runtime/initialization_test.go +203 -0
- package/openapi/soha-api.json +5514 -1179
- package/openapi/soha-api.yaml +1080 -11
- package/openapi/spec_generated.go +3 -3
- package/openapi/spec_test.go +76 -0
- package/package.json +1 -1
- package/resource/agent_access.go +12 -0
- package/resource/agent_profiles.go +62 -0
- package/resource/agent_profiles_test.go +36 -0
- package/resource/kubernetes_kinds.go +73 -0
- package/resource/kubernetes_kinds_test.go +38 -0
- package/resource/models.go +25 -14
- package/resource/network_topology.go +166 -0
- package/resource/network_topology_projection.go +208 -0
- package/resource/network_topology_projection_test.go +53 -0
- package/resource/network_topology_test.go +51 -0
- package/resource/network_topology_validation.go +29 -0
- package/resource/node_drain.go +34 -0
- package/resource/relations.go +225 -0
- package/resource/relations_test.go +47 -0
- package/resource/resource_monitoring.go +99 -0
- package/resource/root_cr.go +38 -0
- package/resource/runtime/argocd_integration_test.go +1 -1
- package/resource/runtime/initialization.go +66 -0
- package/resource/runtime/initialization_test.go +80 -0
- package/resource/runtime/network_topology.go +232 -0
- package/resource/runtime/network_topology_test.go +62 -0
- package/resource/runtime/node_drain.go +124 -0
- package/resource/runtime/node_drain_test.go +95 -0
- package/resource/runtime/relations.go +161 -0
- package/resource/runtime/relations_test.go +100 -0
- package/resource/runtime/resource_edit.go +128 -0
- package/resource/runtime/resource_edit_test.go +183 -0
- package/resource/runtime/resource_monitoring.go +243 -0
- package/resource/runtime/resource_monitoring_test.go +88 -0
- package/resource/runtime/root_cr.go +79 -0
- package/resource/runtime/root_cr_test.go +118 -0
|
@@ -5,9 +5,9 @@ package openapi
|
|
|
5
5
|
import _ "embed"
|
|
6
6
|
|
|
7
7
|
const (
|
|
8
|
-
Version = "0.1.
|
|
9
|
-
YAMLSHA256 = "
|
|
10
|
-
JSONSHA256 = "
|
|
8
|
+
Version = "0.1.26"
|
|
9
|
+
YAMLSHA256 = "6d18163614e65c1f0f0439d928b65bcdd5937781ee6ae912a53526a592cbc2db"
|
|
10
|
+
JSONSHA256 = "37b9e04ece8f49eabdfe41a695ad9b28ce21d434d6a2e2b97922a9f202230c41"
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
//go:embed soha-api.yaml
|
package/openapi/spec_test.go
CHANGED
|
@@ -4,6 +4,7 @@ import (
|
|
|
4
4
|
"crypto/sha256"
|
|
5
5
|
"encoding/json"
|
|
6
6
|
"fmt"
|
|
7
|
+
"strings"
|
|
7
8
|
"testing"
|
|
8
9
|
)
|
|
9
10
|
|
|
@@ -36,3 +37,78 @@ func TestEmbeddedSpecsMatchMetadata(t *testing.T) {
|
|
|
36
37
|
t.Fatalf("info.version = %q, want %q", document.Info.Version, Version)
|
|
37
38
|
}
|
|
38
39
|
}
|
|
40
|
+
|
|
41
|
+
func TestTopologySuccessResponsePreservesDescription(t *testing.T) {
|
|
42
|
+
var document struct {
|
|
43
|
+
Paths map[string]struct {
|
|
44
|
+
Get struct {
|
|
45
|
+
Responses map[string]map[string]json.RawMessage `json:"responses"`
|
|
46
|
+
} `json:"get"`
|
|
47
|
+
} `json:"paths"`
|
|
48
|
+
}
|
|
49
|
+
if err := json.Unmarshal(JSON(), &document); err != nil {
|
|
50
|
+
t.Fatal(err)
|
|
51
|
+
}
|
|
52
|
+
response := document.Paths["/clusters/{clusterID}/network/topology"].Get.Responses["200"]
|
|
53
|
+
if len(response) == 0 {
|
|
54
|
+
t.Fatal("missing topology success response")
|
|
55
|
+
}
|
|
56
|
+
for key := range response {
|
|
57
|
+
switch key {
|
|
58
|
+
case "description", "headers", "content", "links":
|
|
59
|
+
default:
|
|
60
|
+
if !strings.HasPrefix(key, "x-") {
|
|
61
|
+
t.Errorf("unexpected topology response field %q", key)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
var description string
|
|
66
|
+
if err := json.Unmarshal(response["description"], &description); err != nil {
|
|
67
|
+
t.Fatal(err)
|
|
68
|
+
}
|
|
69
|
+
if !strings.Contains(description, "Kubernetes, Gateway API, Traefik and APISIX topology,") {
|
|
70
|
+
t.Fatalf("topology response description was truncated: %q", description)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
func TestPodWebSocketMetadataPreservesHTTPRouteSurface(t *testing.T) {
|
|
75
|
+
var document struct {
|
|
76
|
+
Paths map[string]json.RawMessage `json:"paths"`
|
|
77
|
+
Streams map[string]struct {
|
|
78
|
+
Get struct {
|
|
79
|
+
Permissions struct {
|
|
80
|
+
Keys []string `json:"keys"`
|
|
81
|
+
} `json:"x-soha-permissions"`
|
|
82
|
+
Parameters []struct {
|
|
83
|
+
Name string `json:"name"`
|
|
84
|
+
Schema struct {
|
|
85
|
+
Type string `json:"type"`
|
|
86
|
+
MinLength int `json:"minLength"`
|
|
87
|
+
} `json:"schema"`
|
|
88
|
+
} `json:"parameters"`
|
|
89
|
+
} `json:"get"`
|
|
90
|
+
} `json:"x-soha-websocket-paths"`
|
|
91
|
+
}
|
|
92
|
+
if err := json.Unmarshal(JSON(), &document); err != nil {
|
|
93
|
+
t.Fatal(err)
|
|
94
|
+
}
|
|
95
|
+
for suffix, permission := range map[string]string{"logs/stream": "platform.pods.logs", "terminal": "platform.pods.exec"} {
|
|
96
|
+
path := "/clusters/{clusterID}/workloads/pods/{podName}/" + suffix
|
|
97
|
+
if _, exists := document.Paths[path]; exists {
|
|
98
|
+
t.Fatalf("WebSocket target entered the HTTP client route surface: %s", path)
|
|
99
|
+
}
|
|
100
|
+
stream, exists := document.Streams[path]
|
|
101
|
+
if !exists || len(stream.Get.Permissions.Keys) != 1 || stream.Get.Permissions.Keys[0] != permission {
|
|
102
|
+
t.Fatalf("missing WebSocket target permission: %s", path)
|
|
103
|
+
}
|
|
104
|
+
uidQuery := false
|
|
105
|
+
for _, parameter := range stream.Get.Parameters {
|
|
106
|
+
if parameter.Name == "expectedUid" && parameter.Schema.Type == "string" && parameter.Schema.MinLength == 1 {
|
|
107
|
+
uidQuery = true
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if !uidQuery {
|
|
111
|
+
t.Fatalf("missing non-empty expectedUid query metadata: %s", path)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
package/package.json
CHANGED
package/resource/agent_access.go
CHANGED
|
@@ -21,3 +21,15 @@ type PrometheusQuery struct {
|
|
|
21
21
|
End int64 `json:"end,omitempty"`
|
|
22
22
|
Step int64 `json:"step,omitempty"`
|
|
23
23
|
}
|
|
24
|
+
|
|
25
|
+
// AgentActionCheck separates binary support, authenticated action policy, and Kubernetes authorization.
|
|
26
|
+
// RBAC scope is cluster-wide; target-specific checks and mutations remain authoritative.
|
|
27
|
+
type AgentActionCheck struct {
|
|
28
|
+
Action string `json:"action"`
|
|
29
|
+
Implementation string `json:"implementation"`
|
|
30
|
+
Configured string `json:"configured"`
|
|
31
|
+
KubernetesRBAC string `json:"kubernetesRBAC"`
|
|
32
|
+
CheckedAt string `json:"checkedAt,omitempty"`
|
|
33
|
+
ReasonCode string `json:"reasonCode,omitempty"`
|
|
34
|
+
Scope string `json:"scope,omitempty"`
|
|
35
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
package resource
|
|
2
|
+
|
|
3
|
+
import "fmt"
|
|
4
|
+
|
|
5
|
+
// KubernetesAgentProfileActions is an installation preset, never a runtime permission bypass.
|
|
6
|
+
// Legacy preserves installations generated before the workbench profile was introduced.
|
|
7
|
+
func KubernetesAgentProfileActions(profile string) ([]string, error) {
|
|
8
|
+
switch profile {
|
|
9
|
+
case "read-only":
|
|
10
|
+
return []string{"platform.custom_resources.list"}, nil
|
|
11
|
+
case "workbench":
|
|
12
|
+
return append([]string(nil), kubernetesWorkbenchActions[:]...), nil
|
|
13
|
+
case "legacy":
|
|
14
|
+
actions := make([]string, 0, len(kubernetesWorkbenchActions))
|
|
15
|
+
for _, action := range kubernetesWorkbenchActions {
|
|
16
|
+
if action != "platform.helm_releases.install" && action != "platform.helm_releases.values_update" && action != "platform.helm_releases.delete" && action != "platform.helm_releases.rollback" {
|
|
17
|
+
actions = append(actions, action)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return actions, nil
|
|
21
|
+
default:
|
|
22
|
+
return nil, fmt.Errorf("unknown Kubernetes Agent action profile")
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// KubernetesAgentActions lists implemented platform actions, including separately opted-in CRD deletion.
|
|
27
|
+
func KubernetesAgentActions() []string {
|
|
28
|
+
actions := make([]string, 0, len(kubernetesWorkbenchActions))
|
|
29
|
+
for _, action := range kubernetesWorkbenchActions {
|
|
30
|
+
if action != "runtime.execution_tasks.cancel" {
|
|
31
|
+
actions = append(actions, action)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return append(actions, "platform.crds.delete")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var kubernetesWorkbenchActions = [...]string{
|
|
38
|
+
"platform.nodes.drain",
|
|
39
|
+
"platform.pods.exec",
|
|
40
|
+
"platform.deployments.restart",
|
|
41
|
+
"platform.deployments.scale",
|
|
42
|
+
"platform.deployments.image",
|
|
43
|
+
"platform.deployments.rollback",
|
|
44
|
+
"platform.statefulsets.restart",
|
|
45
|
+
"platform.statefulsets.scale",
|
|
46
|
+
"platform.daemonsets.restart",
|
|
47
|
+
"platform.resources.apply",
|
|
48
|
+
"platform.resources.create",
|
|
49
|
+
"platform.resources.delete",
|
|
50
|
+
"platform.custom_resources.list",
|
|
51
|
+
"platform.custom_resources.create",
|
|
52
|
+
"platform.custom_resources.apply",
|
|
53
|
+
"platform.custom_resources.delete",
|
|
54
|
+
"platform.port_forwards.create",
|
|
55
|
+
"platform.port_forwards.tunnel",
|
|
56
|
+
"platform.port_forwards.delete",
|
|
57
|
+
"platform.helm_releases.install",
|
|
58
|
+
"platform.helm_releases.values_update",
|
|
59
|
+
"platform.helm_releases.delete",
|
|
60
|
+
"platform.helm_releases.rollback",
|
|
61
|
+
"runtime.execution_tasks.cancel",
|
|
62
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
package resource
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"slices"
|
|
5
|
+
"testing"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
func TestKubernetesAgentProfilesKeepPermissionsExplicit(t *testing.T) {
|
|
9
|
+
workbench, err := KubernetesAgentProfileActions("workbench")
|
|
10
|
+
if err != nil {
|
|
11
|
+
t.Fatal(err)
|
|
12
|
+
}
|
|
13
|
+
for _, action := range []string{"platform.nodes.drain", "platform.resources.apply", "platform.resources.create", "platform.resources.delete", "platform.helm_releases.rollback", "platform.port_forwards.tunnel"} {
|
|
14
|
+
if !slices.Contains(workbench, action) {
|
|
15
|
+
t.Fatalf("missing workbench action %s", action)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if slices.Contains(workbench, "*") || slices.Contains(workbench, "platform.crds.delete") {
|
|
19
|
+
t.Fatal("workbench must not opt into unrestricted or CRD deletion actions")
|
|
20
|
+
}
|
|
21
|
+
legacy, _ := KubernetesAgentProfileActions("legacy")
|
|
22
|
+
if slices.Contains(legacy, "platform.helm_releases.install") {
|
|
23
|
+
t.Fatal("legacy installation permissions expanded")
|
|
24
|
+
}
|
|
25
|
+
readOnly, _ := KubernetesAgentProfileActions("read-only")
|
|
26
|
+
if !slices.Equal(readOnly, []string{"platform.custom_resources.list"}) {
|
|
27
|
+
t.Fatalf("read-only contains writes: %v", readOnly)
|
|
28
|
+
}
|
|
29
|
+
if _, err := KubernetesAgentProfileActions("unknown"); err == nil {
|
|
30
|
+
t.Fatal("unknown profile accepted")
|
|
31
|
+
}
|
|
32
|
+
workbench[0] = "changed"
|
|
33
|
+
if next, _ := KubernetesAgentProfileActions("workbench"); next[0] == "changed" {
|
|
34
|
+
t.Fatal("profile leaked mutable storage")
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
package resource
|
|
2
|
+
|
|
3
|
+
import "strings"
|
|
4
|
+
|
|
5
|
+
// KubernetesResourceKind describes the fixed resource surface shared by both transports.
|
|
6
|
+
// GenericYAML excludes resources whose dedicated lifecycle has stronger authorization.
|
|
7
|
+
type KubernetesResourceKind struct {
|
|
8
|
+
Kind string
|
|
9
|
+
Group string
|
|
10
|
+
Version string
|
|
11
|
+
Resource string
|
|
12
|
+
Namespaced bool
|
|
13
|
+
GenericYAML bool
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
var kubernetesResourceKinds = [...]KubernetesResourceKind{
|
|
17
|
+
{Kind: "Namespace", Group: "", Version: "v1", Resource: "namespaces", Namespaced: false, GenericYAML: false},
|
|
18
|
+
{Kind: "Pod", Group: "", Version: "v1", Resource: "pods", Namespaced: true, GenericYAML: true},
|
|
19
|
+
{Kind: "Node", Group: "", Version: "v1", Resource: "nodes", Namespaced: false, GenericYAML: true},
|
|
20
|
+
{Kind: "Deployment", Group: "apps", Version: "v1", Resource: "deployments", Namespaced: true, GenericYAML: true},
|
|
21
|
+
{Kind: "StatefulSet", Group: "apps", Version: "v1", Resource: "statefulsets", Namespaced: true, GenericYAML: true},
|
|
22
|
+
{Kind: "DaemonSet", Group: "apps", Version: "v1", Resource: "daemonsets", Namespaced: true, GenericYAML: true},
|
|
23
|
+
{Kind: "ReplicaSet", Group: "apps", Version: "v1", Resource: "replicasets", Namespaced: true, GenericYAML: true},
|
|
24
|
+
{Kind: "Job", Group: "batch", Version: "v1", Resource: "jobs", Namespaced: true, GenericYAML: true},
|
|
25
|
+
{Kind: "CronJob", Group: "batch", Version: "v1", Resource: "cronjobs", Namespaced: true, GenericYAML: true},
|
|
26
|
+
{Kind: "ConfigMap", Group: "", Version: "v1", Resource: "configmaps", Namespaced: true, GenericYAML: true},
|
|
27
|
+
{Kind: "Secret", Group: "", Version: "v1", Resource: "secrets", Namespaced: true, GenericYAML: true},
|
|
28
|
+
{Kind: "ServiceAccount", Group: "", Version: "v1", Resource: "serviceaccounts", Namespaced: true, GenericYAML: true},
|
|
29
|
+
{Kind: "ReplicationController", Group: "", Version: "v1", Resource: "replicationcontrollers", Namespaced: true, GenericYAML: true},
|
|
30
|
+
{Kind: "Service", Group: "", Version: "v1", Resource: "services", Namespaced: true, GenericYAML: true},
|
|
31
|
+
{Kind: "PersistentVolumeClaim", Group: "", Version: "v1", Resource: "persistentvolumeclaims", Namespaced: true, GenericYAML: true},
|
|
32
|
+
{Kind: "PersistentVolume", Group: "", Version: "v1", Resource: "persistentvolumes", Namespaced: false, GenericYAML: true},
|
|
33
|
+
{Kind: "StorageClass", Group: "storage.k8s.io", Version: "v1", Resource: "storageclasses", Namespaced: false, GenericYAML: true},
|
|
34
|
+
{Kind: "Role", Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "roles", Namespaced: true, GenericYAML: true},
|
|
35
|
+
{Kind: "RoleBinding", Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "rolebindings", Namespaced: true, GenericYAML: true},
|
|
36
|
+
{Kind: "ResourceQuota", Group: "", Version: "v1", Resource: "resourcequotas", Namespaced: true, GenericYAML: true},
|
|
37
|
+
{Kind: "LimitRange", Group: "", Version: "v1", Resource: "limitranges", Namespaced: true, GenericYAML: true},
|
|
38
|
+
{Kind: "Lease", Group: "coordination.k8s.io", Version: "v1", Resource: "leases", Namespaced: true, GenericYAML: true},
|
|
39
|
+
{Kind: "HorizontalPodAutoscaler", Group: "autoscaling", Version: "v2", Resource: "horizontalpodautoscalers", Namespaced: true, GenericYAML: true},
|
|
40
|
+
{Kind: "PodDisruptionBudget", Group: "policy", Version: "v1", Resource: "poddisruptionbudgets", Namespaced: true, GenericYAML: true},
|
|
41
|
+
{Kind: "Ingress", Group: "networking.k8s.io", Version: "v1", Resource: "ingresses", Namespaced: true, GenericYAML: true},
|
|
42
|
+
{Kind: "EndpointSlice", Group: "discovery.k8s.io", Version: "v1", Resource: "endpointslices", Namespaced: true, GenericYAML: true},
|
|
43
|
+
{Kind: "NetworkPolicy", Group: "networking.k8s.io", Version: "v1", Resource: "networkpolicies", Namespaced: true, GenericYAML: true},
|
|
44
|
+
{Kind: "IngressClass", Group: "networking.k8s.io", Version: "v1", Resource: "ingressclasses", Namespaced: false, GenericYAML: true},
|
|
45
|
+
{Kind: "GatewayClass", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "gatewayclasses", Namespaced: false, GenericYAML: true},
|
|
46
|
+
{Kind: "Gateway", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "gateways", Namespaced: true, GenericYAML: true},
|
|
47
|
+
{Kind: "HTTPRoute", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "httproutes", Namespaced: true, GenericYAML: true},
|
|
48
|
+
{Kind: "BackendTLSPolicy", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "backendtlspolicies", Namespaced: true, GenericYAML: true},
|
|
49
|
+
{Kind: "GRPCRoute", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "grpcroutes", Namespaced: true, GenericYAML: true},
|
|
50
|
+
{Kind: "ReferenceGrant", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "referencegrants", Namespaced: true, GenericYAML: true},
|
|
51
|
+
{Kind: "PriorityClass", Group: "scheduling.k8s.io", Version: "v1", Resource: "priorityclasses", Namespaced: false, GenericYAML: true},
|
|
52
|
+
{Kind: "RuntimeClass", Group: "node.k8s.io", Version: "v1", Resource: "runtimeclasses", Namespaced: false, GenericYAML: true},
|
|
53
|
+
{Kind: "ClusterRole", Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterroles", Namespaced: false, GenericYAML: true},
|
|
54
|
+
{Kind: "ClusterRoleBinding", Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterrolebindings", Namespaced: false, GenericYAML: true},
|
|
55
|
+
{Kind: "CustomResourceDefinition", Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions", Namespaced: false, GenericYAML: false},
|
|
56
|
+
{Kind: "WorkloadCronJob", Group: "workloads.soha.io", Version: "v1alpha1", Resource: "workloadcronjobs", Namespaced: true, GenericYAML: false},
|
|
57
|
+
{Kind: "MutatingWebhookConfiguration", Group: "admissionregistration.k8s.io", Version: "v1", Resource: "mutatingwebhookconfigurations", Namespaced: false, GenericYAML: true},
|
|
58
|
+
{Kind: "ValidatingWebhookConfiguration", Group: "admissionregistration.k8s.io", Version: "v1", Resource: "validatingwebhookconfigurations", Namespaced: false, GenericYAML: true},
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// KubernetesResourceKinds returns a copy so callers cannot alter the shared surface.
|
|
62
|
+
func KubernetesResourceKinds() []KubernetesResourceKind {
|
|
63
|
+
return append([]KubernetesResourceKind(nil), kubernetesResourceKinds[:]...)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
func LookupKubernetesResourceKind(kind string) (KubernetesResourceKind, bool) {
|
|
67
|
+
for _, definition := range kubernetesResourceKinds {
|
|
68
|
+
if strings.EqualFold(strings.TrimSpace(kind), definition.Kind) {
|
|
69
|
+
return definition, true
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return KubernetesResourceKind{}, false
|
|
73
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package resource
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"strings"
|
|
5
|
+
"testing"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
func TestKubernetesResourceKindsAreUniqueAndKeepDedicatedLifecycles(t *testing.T) {
|
|
9
|
+
seen := map[string]bool{}
|
|
10
|
+
for _, definition := range KubernetesResourceKinds() {
|
|
11
|
+
key := strings.ToLower(definition.Kind)
|
|
12
|
+
if seen[key] || definition.Version == "" || definition.Resource == "" {
|
|
13
|
+
t.Fatalf("invalid definition: %+v", definition)
|
|
14
|
+
}
|
|
15
|
+
seen[key] = true
|
|
16
|
+
if got, ok := LookupKubernetesResourceKind(" " + key + " "); !ok || got != definition {
|
|
17
|
+
t.Fatalf("lookup: %+v %v", got, ok)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
for _, kind := range []string{"Namespace", "CustomResourceDefinition", "WorkloadCronJob"} {
|
|
21
|
+
if definition, ok := LookupKubernetesResourceKind(kind); !ok || definition.GenericYAML {
|
|
22
|
+
t.Fatalf("%s must retain its dedicated lifecycle", kind)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
for _, kind := range []string{"HorizontalPodAutoscaler", "PodDisruptionBudget"} {
|
|
26
|
+
if definition, ok := LookupKubernetesResourceKind(kind); !ok || !definition.GenericYAML || !definition.Namespaced {
|
|
27
|
+
t.Fatalf("missing namespaced YAML surface: %s", kind)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if _, ok := LookupKubernetesResourceKind("Unknown"); ok {
|
|
31
|
+
t.Fatal("unknown kind accepted")
|
|
32
|
+
}
|
|
33
|
+
definitions := KubernetesResourceKinds()
|
|
34
|
+
definitions[0].Kind = "changed"
|
|
35
|
+
if KubernetesResourceKinds()[0].Kind == "changed" {
|
|
36
|
+
t.Fatal("caller changed the shared registry")
|
|
37
|
+
}
|
|
38
|
+
}
|
package/resource/models.go
CHANGED
|
@@ -14,13 +14,14 @@ const (
|
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
type ResourceRef struct {
|
|
17
|
-
ClusterID
|
|
18
|
-
APIVersion
|
|
19
|
-
Kind
|
|
20
|
-
Name
|
|
21
|
-
Namespace
|
|
22
|
-
ScopeMode
|
|
23
|
-
UID
|
|
17
|
+
ClusterID string `json:"clusterId"`
|
|
18
|
+
APIVersion string `json:"apiVersion"`
|
|
19
|
+
Kind string `json:"kind"`
|
|
20
|
+
Name string `json:"name"`
|
|
21
|
+
Namespace string `json:"namespace,omitempty"`
|
|
22
|
+
ScopeMode ResourceScopeMode `json:"scopeMode"`
|
|
23
|
+
UID string `json:"uid,omitempty"`
|
|
24
|
+
ResourceVersion string `json:"resourceVersion,omitempty"`
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
type ResourceSearchItem struct {
|
|
@@ -103,6 +104,7 @@ type NamespaceUpsertInput struct {
|
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
type PodView struct {
|
|
107
|
+
UID string `json:"uid,omitempty"`
|
|
106
108
|
Name string `json:"name"`
|
|
107
109
|
Namespace string `json:"namespace"`
|
|
108
110
|
Phase string `json:"phase"`
|
|
@@ -239,6 +241,7 @@ type NodeResourceSummaryView struct {
|
|
|
239
241
|
}
|
|
240
242
|
|
|
241
243
|
type PodDetailView struct {
|
|
244
|
+
UID string `json:"uid,omitempty"`
|
|
242
245
|
Name string `json:"name"`
|
|
243
246
|
Namespace string `json:"namespace"`
|
|
244
247
|
Phase string `json:"phase"`
|
|
@@ -897,19 +900,27 @@ type NetworkTopologyTraceView struct {
|
|
|
897
900
|
}
|
|
898
901
|
|
|
899
902
|
type NetworkTopologyView struct {
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
903
|
+
GraphVersion string `json:"graphVersion,omitempty"`
|
|
904
|
+
Nodes []NetworkTopologyGraphNode `json:"nodes,omitempty"`
|
|
905
|
+
Edges []NetworkTopologyGraphEdge `json:"edges,omitempty"`
|
|
906
|
+
Coverage []NetworkTopologyCoverage `json:"coverage,omitempty"`
|
|
907
|
+
ObservedAt string `json:"observedAt,omitempty"`
|
|
908
|
+
Truncated bool `json:"truncated,omitempty"`
|
|
909
|
+
ClusterID string `json:"clusterId"`
|
|
910
|
+
Namespace string `json:"namespace,omitempty"`
|
|
911
|
+
Source string `json:"source"`
|
|
912
|
+
GeneratedAt string `json:"generatedAt"`
|
|
913
|
+
Summary NetworkTopologySummaryView `json:"summary"`
|
|
914
|
+
Traces []NetworkTopologyTraceView `json:"traces,omitempty"`
|
|
915
|
+
Warnings []string `json:"warnings,omitempty"`
|
|
907
916
|
}
|
|
908
917
|
|
|
909
918
|
type NodeView struct {
|
|
910
919
|
Name string `json:"name"`
|
|
911
920
|
Status string `json:"status"`
|
|
912
921
|
Unschedulable bool `json:"unschedulable"`
|
|
922
|
+
Taints []NodeTaintView `json:"taints"`
|
|
923
|
+
Conditions []WorkloadConditionView `json:"conditions"`
|
|
913
924
|
Roles []string `json:"roles,omitempty"`
|
|
914
925
|
Version string `json:"version,omitempty"`
|
|
915
926
|
InternalIP string `json:"internalIp,omitempty"`
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
package resource
|
|
2
|
+
|
|
3
|
+
const (
|
|
4
|
+
NetworkTopologySnapshotFeature = "network.topology.snapshot.v1"
|
|
5
|
+
NetworkTopologyGatewayL4Feature = "network.topology.gateway-l4.v1"
|
|
6
|
+
NetworkTopologyMaxQueries = 64
|
|
7
|
+
NetworkTopologyMaxSourceItems = 200
|
|
8
|
+
NetworkTopologyMaxSourceBytes = 1 << 20
|
|
9
|
+
NetworkTopologyMaxTotalBytes = 4 << 20
|
|
10
|
+
NetworkTopologyMaxObjectBytes = 64 << 10
|
|
11
|
+
NetworkTopologyDefaultNodes = 200
|
|
12
|
+
NetworkTopologyDefaultEdges = 400
|
|
13
|
+
NetworkTopologyMaxNodes = 500
|
|
14
|
+
NetworkTopologyMaxEdges = 1000
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
type NetworkTopologyGraphNode struct {
|
|
18
|
+
ID string `json:"id"`
|
|
19
|
+
Type string `json:"type"`
|
|
20
|
+
Label string `json:"label"`
|
|
21
|
+
Provider string `json:"provider"`
|
|
22
|
+
Protocol string `json:"protocol,omitempty"`
|
|
23
|
+
ResolutionState string `json:"resolutionState"`
|
|
24
|
+
Resource *ResourceRef `json:"resource,omitempty"`
|
|
25
|
+
Rule *NetworkTopologyRule `json:"rule,omitempty"`
|
|
26
|
+
Properties []NetworkTopologyProperty `json:"properties,omitempty"`
|
|
27
|
+
Conditions []NetworkTopologyCondition `json:"conditions,omitempty"`
|
|
28
|
+
Generation int64 `json:"generation,omitempty"`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type NetworkTopologyGraphEdge struct {
|
|
32
|
+
ID string `json:"id"`
|
|
33
|
+
Source string `json:"source"`
|
|
34
|
+
Target string `json:"target"`
|
|
35
|
+
Relation string `json:"relation"`
|
|
36
|
+
ResolutionState string `json:"resolutionState"`
|
|
37
|
+
Protocol string `json:"protocol,omitempty"`
|
|
38
|
+
Port string `json:"port,omitempty"`
|
|
39
|
+
Weight *int64 `json:"weight,omitempty"`
|
|
40
|
+
TotalWeight *int64 `json:"totalWeight,omitempty"`
|
|
41
|
+
MirrorPercent *float64 `json:"mirrorPercent,omitempty"`
|
|
42
|
+
RuleRef string `json:"ruleRef,omitempty"`
|
|
43
|
+
SourceRef *ResourceRef `json:"sourceRef,omitempty"`
|
|
44
|
+
Note string `json:"note,omitempty"`
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type NetworkTopologyRule struct {
|
|
48
|
+
Name string `json:"name,omitempty"`
|
|
49
|
+
Index int `json:"index"`
|
|
50
|
+
MatchGroups [][]NetworkTopologyMatch `json:"matchGroups,omitempty"`
|
|
51
|
+
MatchSummary string `json:"matchSummary,omitempty"`
|
|
52
|
+
Priority *int64 `json:"priority,omitempty"`
|
|
53
|
+
TLSMode string `json:"tlsMode,omitempty"`
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
type NetworkTopologyMatch struct {
|
|
57
|
+
Type string `json:"type"`
|
|
58
|
+
Name string `json:"name,omitempty"`
|
|
59
|
+
Operator string `json:"operator,omitempty"`
|
|
60
|
+
Value string `json:"value,omitempty"`
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
type NetworkTopologyProperty struct {
|
|
64
|
+
Name string `json:"name"`
|
|
65
|
+
Value string `json:"value"`
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type NetworkTopologyCondition struct {
|
|
69
|
+
Type string `json:"type"`
|
|
70
|
+
Status string `json:"status"`
|
|
71
|
+
Reason string `json:"reason,omitempty"`
|
|
72
|
+
ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
|
|
73
|
+
LastTransitionTime string `json:"lastTransitionTime,omitempty"`
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
type NetworkTopologyCoverage struct {
|
|
77
|
+
Provider string `json:"provider"`
|
|
78
|
+
SourceID string `json:"sourceId"`
|
|
79
|
+
State string `json:"state"`
|
|
80
|
+
Namespace string `json:"namespace,omitempty"`
|
|
81
|
+
SupportedKinds []string `json:"supportedKinds,omitempty"`
|
|
82
|
+
ReasonCode string `json:"reasonCode,omitempty"`
|
|
83
|
+
CheckedAt string `json:"checkedAt,omitempty"`
|
|
84
|
+
ObservedAt string `json:"observedAt,omitempty"`
|
|
85
|
+
Truncated bool `json:"truncated,omitempty"`
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Snapshot queries name a fixed source, never a caller-supplied GVR or field path.
|
|
89
|
+
type NetworkTopologySourceQuery struct {
|
|
90
|
+
SourceID string `json:"sourceId"`
|
|
91
|
+
Namespace string `json:"namespace,omitempty"`
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
type NetworkTopologySnapshotRequest struct {
|
|
95
|
+
Queries []NetworkTopologySourceQuery `json:"queries"`
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
type NetworkTopologySourceObject struct {
|
|
99
|
+
Resource ResourceRef `json:"resource"`
|
|
100
|
+
Generation int64 `json:"generation,omitempty"`
|
|
101
|
+
// Content contains only the source's contract-allowlisted projection, not an original manifest.
|
|
102
|
+
Content string `json:"content"`
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
type NetworkTopologySourceResult struct {
|
|
106
|
+
Coverage NetworkTopologyCoverage `json:"coverage"`
|
|
107
|
+
Objects []NetworkTopologySourceObject `json:"objects"`
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
type NetworkTopologySnapshot struct {
|
|
111
|
+
Version string `json:"version"`
|
|
112
|
+
Sources []NetworkTopologySourceResult `json:"sources"`
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
type NetworkTopologySourceDefinition struct {
|
|
116
|
+
ID string
|
|
117
|
+
Provider string
|
|
118
|
+
FallbackVersion string
|
|
119
|
+
CRDResourceDefinition
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
var networkTopologySources = [...]NetworkTopologySourceDefinition{
|
|
123
|
+
{ID: "kubernetes.services", Provider: "kubernetes", CRDResourceDefinition: CRDResourceDefinition{Kind: "Service", Version: "v1", Resource: "services", Namespaced: true}},
|
|
124
|
+
{ID: "kubernetes.pods", Provider: "kubernetes", CRDResourceDefinition: CRDResourceDefinition{Kind: "Pod", Version: "v1", Resource: "pods", Namespaced: true}},
|
|
125
|
+
{ID: "kubernetes.endpointslices", Provider: "kubernetes", CRDResourceDefinition: CRDResourceDefinition{Kind: "EndpointSlice", Group: "discovery.k8s.io", Version: "v1", Resource: "endpointslices", Namespaced: true}},
|
|
126
|
+
{ID: "kubernetes.ingresses", Provider: "kubernetes", CRDResourceDefinition: CRDResourceDefinition{Kind: "Ingress", Group: "networking.k8s.io", Version: "v1", Resource: "ingresses", Namespaced: true}},
|
|
127
|
+
{ID: "kubernetes.ingressclasses", Provider: "kubernetes", CRDResourceDefinition: CRDResourceDefinition{Kind: "IngressClass", Group: "networking.k8s.io", Version: "v1", Resource: "ingressclasses"}},
|
|
128
|
+
{ID: "gateway.gateways", Provider: "gateway", CRDResourceDefinition: CRDResourceDefinition{Kind: "Gateway", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "gateways", Namespaced: true}},
|
|
129
|
+
{ID: "gateway.gatewayclasses", Provider: "gateway", CRDResourceDefinition: CRDResourceDefinition{Kind: "GatewayClass", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "gatewayclasses"}},
|
|
130
|
+
{ID: "gateway.httproutes", Provider: "gateway", CRDResourceDefinition: CRDResourceDefinition{Kind: "HTTPRoute", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "httproutes", Namespaced: true}},
|
|
131
|
+
{ID: "gateway.grpcroutes", Provider: "gateway", CRDResourceDefinition: CRDResourceDefinition{Kind: "GRPCRoute", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "grpcroutes", Namespaced: true}},
|
|
132
|
+
{ID: "gateway.tcproutes", Provider: "gateway", FallbackVersion: "v1alpha2", CRDResourceDefinition: CRDResourceDefinition{Kind: "TCPRoute", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "tcproutes", Namespaced: true}},
|
|
133
|
+
{ID: "gateway.tlsroutes", Provider: "gateway", FallbackVersion: "v1alpha2", CRDResourceDefinition: CRDResourceDefinition{Kind: "TLSRoute", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "tlsroutes", Namespaced: true}},
|
|
134
|
+
{ID: "gateway.udproutes", Provider: "gateway", FallbackVersion: "v1alpha2", CRDResourceDefinition: CRDResourceDefinition{Kind: "UDPRoute", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "udproutes", Namespaced: true}},
|
|
135
|
+
{ID: "gateway.referencegrants", Provider: "gateway", FallbackVersion: "v1beta1", CRDResourceDefinition: CRDResourceDefinition{Kind: "ReferenceGrant", Group: "gateway.networking.k8s.io", Version: "v1", Resource: "referencegrants", Namespaced: true}},
|
|
136
|
+
{ID: "traefik.ingressroutes", Provider: "traefik", CRDResourceDefinition: CRDResourceDefinition{Kind: "IngressRoute", Group: "traefik.io", Version: "v1alpha1", Resource: "ingressroutes", Namespaced: true}},
|
|
137
|
+
{ID: "traefik.ingressroutetcps", Provider: "traefik", CRDResourceDefinition: CRDResourceDefinition{Kind: "IngressRouteTCP", Group: "traefik.io", Version: "v1alpha1", Resource: "ingressroutetcps", Namespaced: true}},
|
|
138
|
+
{ID: "traefik.ingressrouteudps", Provider: "traefik", CRDResourceDefinition: CRDResourceDefinition{Kind: "IngressRouteUDP", Group: "traefik.io", Version: "v1alpha1", Resource: "ingressrouteudps", Namespaced: true}},
|
|
139
|
+
{ID: "traefik.traefikservices", Provider: "traefik", CRDResourceDefinition: CRDResourceDefinition{Kind: "TraefikService", Group: "traefik.io", Version: "v1alpha1", Resource: "traefikservices", Namespaced: true}},
|
|
140
|
+
{ID: "traefik.middlewares", Provider: "traefik", CRDResourceDefinition: CRDResourceDefinition{Kind: "Middleware", Group: "traefik.io", Version: "v1alpha1", Resource: "middlewares", Namespaced: true}},
|
|
141
|
+
{ID: "traefik.middlewaretcps", Provider: "traefik", CRDResourceDefinition: CRDResourceDefinition{Kind: "MiddlewareTCP", Group: "traefik.io", Version: "v1alpha1", Resource: "middlewaretcps", Namespaced: true}},
|
|
142
|
+
{ID: "apisix.apisixroutes", Provider: "apisix", CRDResourceDefinition: CRDResourceDefinition{Kind: "ApisixRoute", Group: "apisix.apache.org", Version: "v2", Resource: "apisixroutes", Namespaced: true}},
|
|
143
|
+
{ID: "apisix.apisixupstreams", Provider: "apisix", CRDResourceDefinition: CRDResourceDefinition{Kind: "ApisixUpstream", Group: "apisix.apache.org", Version: "v2", Resource: "apisixupstreams", Namespaced: true}},
|
|
144
|
+
{ID: "apisix.apisixtls", Provider: "apisix", CRDResourceDefinition: CRDResourceDefinition{Kind: "ApisixTls", Group: "apisix.apache.org", Version: "v2", Resource: "apisixtls", Namespaced: true}},
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
func NetworkTopologySources() []NetworkTopologySourceDefinition {
|
|
148
|
+
return append([]NetworkTopologySourceDefinition(nil), networkTopologySources[:]...)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
func IsGatewayL4TopologySource(id string) bool {
|
|
152
|
+
return id == "gateway.tcproutes" || id == "gateway.tlsroutes" || id == "gateway.udproutes"
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
func (d NetworkTopologySourceDefinition) RequiresCustomResourceAccess() bool {
|
|
156
|
+
return d.Provider == "traefik" || d.Provider == "apisix" || IsGatewayL4TopologySource(d.ID)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
func LookupNetworkTopologySource(id string) (NetworkTopologySourceDefinition, bool) {
|
|
160
|
+
for _, definition := range networkTopologySources {
|
|
161
|
+
if definition.ID == id {
|
|
162
|
+
return definition, true
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return NetworkTopologySourceDefinition{}, false
|
|
166
|
+
}
|