Skip to content

Commit 00e3d7b

Browse files
committed
feat(kiali): Consildate tools in ManageIstioConfig
Signed-off-by: Alberto Gutierrez <aljesusg@gmail.com>
1 parent 77a12b8 commit 00e3d7b

File tree

7 files changed

+195
-539
lines changed

7 files changed

+195
-539
lines changed

README.md

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -354,40 +354,14 @@ In case multi-cluster support is enabled (default) and you have access to multip
354354
- `namespaces` (`string`) - Optional comma-separated list of namespaces to include in the graph
355355
- `rateInterval` (`string`) - Rate interval for fetching (e.g., '10m', '5m', '1h'). Default: '60s'
356356

357-
- **kiali_istio_config** - Get all Istio configuration objects in the mesh including their full YAML resources and details
358-
359-
- **kiali_istio_object_details** - Get detailed information about a specific Istio object including validation and help information
360-
- `group` (`string`) **(required)** - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
361-
- `kind` (`string`) **(required)** - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
362-
- `name` (`string`) **(required)** - Name of the Istio object
363-
- `namespace` (`string`) **(required)** - Namespace containing the Istio object
364-
- `version` (`string`) **(required)** - API version of the Istio object (e.g., 'v1', 'v1beta1')
365-
366-
- **kiali_istio_object_patch** - Modify an existing Istio object using PATCH method. The JSON patch data will be applied to the existing object.
367-
- `group` (`string`) **(required)** - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
368-
- `json_patch` (`string`) **(required)** - JSON patch data to apply to the object
369-
- `kind` (`string`) **(required)** - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
370-
- `name` (`string`) **(required)** - Name of the Istio object
371-
- `namespace` (`string`) **(required)** - Namespace containing the Istio object
372-
- `version` (`string`) **(required)** - API version of the Istio object (e.g., 'v1', 'v1beta1')
373-
374-
- **kiali_istio_object_create** - Create a new Istio object using POST method. The JSON data will be used to create the new object.
375-
- `group` (`string`) **(required)** - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
376-
- `json_data` (`string`) **(required)** - JSON data for the new object
377-
- `kind` (`string`) **(required)** - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
378-
- `namespace` (`string`) **(required)** - Namespace where the Istio object will be created
379-
- `version` (`string`) **(required)** - API version of the Istio object (e.g., 'v1', 'v1beta1')
380-
381-
- **kiali_istio_object_delete** - Delete an existing Istio object using DELETE method.
382-
- `group` (`string`) **(required)** - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
383-
- `kind` (`string`) **(required)** - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
384-
- `name` (`string`) **(required)** - Name of the Istio object
385-
- `namespace` (`string`) **(required)** - Namespace containing the Istio object
386-
- `version` (`string`) **(required)** - API version of the Istio object (e.g., 'v1', 'v1beta1')
387-
388-
- **kiali_validations_list** - List all the validations in the current cluster from all namespaces
389-
- `namespace` (`string`) - Optional single namespace to retrieve validations from (alternative to namespaces)
390-
- `namespaces` (`string`) - Optional comma-separated list of namespaces to retrieve validations from
357+
- **kiali_manage_istio_config** - Manages Istio configuration objects (Gateways, VirtualServices, etc.). Can list (objects and validations), get, create, patch, or delete objects
358+
- `action` (`string`) **(required)** - Action to perform: list, get, create, patch, or delete
359+
- `group` (`string`) - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
360+
- `json_data` (`string`) - JSON data to apply or create the object
361+
- `kind` (`string`) - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
362+
- `name` (`string`) - Name of the Istio object
363+
- `namespace` (`string`) - Namespace containing the Istio object
364+
- `version` (`string`) - API version of the Istio object (e.g., 'v1', 'v1beta1')
391365

392366
- **kiali_services_list** - Get all services in the mesh across specified namespaces with health and Istio resource information
393367
- `namespaces` (`string`) - Comma-separated list of namespaces to get services from (e.g. 'bookinfo' or 'bookinfo,default'). If not provided, will list services from all accessible namespaces

pkg/kiali/endpoints.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,4 @@ const (
2323
WorkloadDetailsEndpoint = "/api/namespaces/%s/workloads/%s"
2424
WorkloadMetricsEndpoint = "/api/namespaces/%s/workloads/%s/metrics"
2525
ValidationsEndpoint = "/api/istio/validations"
26-
ValidationsListEndpoint = "/api/istio/validations"
2726
)

pkg/kiali/istio.go

Lines changed: 69 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -2,151 +2,96 @@ package kiali
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
67
"net/http"
78
"net/url"
89
"strings"
10+
"sync"
911
)
1012

11-
// IstioConfig calls the Kiali Istio config API to get all Istio objects in the mesh.
12-
// Returns the full YAML resources and additional details about each object.
13-
func (k *Kiali) IstioConfig(ctx context.Context) (string, error) {
14-
endpoint := IstioConfigEndpoint + "?validate=true"
15-
16-
return k.executeRequest(ctx, http.MethodGet, endpoint, "", nil)
13+
type IstioConfigListResponse struct {
14+
Configs json.RawMessage `json:"configs"`
15+
Validations json.RawMessage `json:"validations"`
1716
}
1817

19-
// IstioObjectDetails returns detailed information about a specific Istio object.
20-
// Parameters:
21-
// - namespace: the namespace containing the Istio object
22-
// - group: the API group (e.g., "networking.istio.io", "gateway.networking.k8s.io")
23-
// - version: the API version (e.g., "v1", "v1beta1")
24-
// - kind: the resource kind (e.g., "DestinationRule", "VirtualService", "HTTPRoute")
25-
// - name: the name of the resource
26-
func (k *Kiali) IstioObjectDetails(ctx context.Context, namespace, group, version, kind, name string) (string, error) {
27-
if namespace == "" {
28-
return "", fmt.Errorf("namespace is required")
29-
}
30-
if group == "" {
31-
return "", fmt.Errorf("group is required")
32-
}
33-
if version == "" {
34-
return "", fmt.Errorf("version is required")
35-
}
36-
if kind == "" {
37-
return "", fmt.Errorf("kind is required")
38-
}
39-
if name == "" {
40-
return "", fmt.Errorf("name is required")
41-
}
42-
endpoint := fmt.Sprintf(IstioObjectEndpoint+"?validate=true&help=true",
18+
// Helper builders to avoid repeated url.PathEscape boilerplate
19+
func buildIstioObjectEndpoint(namespace, group, version, kind, name string) string {
20+
return fmt.Sprintf(IstioObjectEndpoint,
4321
url.PathEscape(namespace),
4422
url.PathEscape(group),
4523
url.PathEscape(version),
4624
url.PathEscape(kind),
47-
url.PathEscape(name))
48-
49-
return k.executeRequest(ctx, http.MethodGet, endpoint, "", nil)
25+
url.PathEscape(name),
26+
)
5027
}
5128

52-
// IstioObjectPatch patches an existing Istio object using PATCH method.
53-
// Parameters:
54-
// - namespace: the namespace containing the Istio object
55-
// - group: the API group (e.g., "networking.istio.io", "gateway.networking.k8s.io")
56-
// - version: the API version (e.g., "v1", "v1beta1")
57-
// - kind: the resource kind (e.g., "DestinationRule", "VirtualService", "HTTPRoute")
58-
// - name: the name of the resource
59-
// - jsonPatch: the JSON patch data to apply
60-
func (k *Kiali) IstioObjectPatch(ctx context.Context, namespace, group, version, kind, name, jsonPatch string) (string, error) {
61-
if namespace == "" {
62-
return "", fmt.Errorf("namespace is required")
63-
}
64-
if group == "" {
65-
return "", fmt.Errorf("group is required")
66-
}
67-
if version == "" {
68-
return "", fmt.Errorf("version is required")
69-
}
70-
if kind == "" {
71-
return "", fmt.Errorf("kind is required")
72-
}
73-
if name == "" {
74-
return "", fmt.Errorf("name is required")
75-
}
76-
if jsonPatch == "" {
77-
return "", fmt.Errorf("json patch data is required")
78-
}
79-
endpoint := fmt.Sprintf(IstioObjectEndpoint,
29+
func buildIstioObjectCreateEndpoint(namespace, group, version, kind string) string {
30+
return fmt.Sprintf(IstioObjectCreateEndpoint,
8031
url.PathEscape(namespace),
8132
url.PathEscape(group),
8233
url.PathEscape(version),
8334
url.PathEscape(kind),
84-
url.PathEscape(name))
85-
86-
return k.executeRequest(ctx, http.MethodPatch, endpoint, "application/json", strings.NewReader(jsonPatch))
35+
)
8736
}
8837

89-
// IstioObjectCreate creates a new Istio object using POST method.
90-
// Parameters:
91-
// - namespace: the namespace where the Istio object will be created
92-
// - group: the API group (e.g., "networking.istio.io", "gateway.networking.k8s.io")
93-
// - version: the API version (e.g., "v1", "v1beta1")
94-
// - kind: the resource kind (e.g., "DestinationRule", "VirtualService", "HTTPRoute")
95-
// - jsonData: the JSON data for the new object
96-
func (k *Kiali) IstioObjectCreate(ctx context.Context, namespace, group, version, kind, jsonData string) (string, error) {
97-
if namespace == "" {
98-
return "", fmt.Errorf("namespace is required")
99-
}
100-
if group == "" {
101-
return "", fmt.Errorf("group is required")
102-
}
103-
if version == "" {
104-
return "", fmt.Errorf("version is required")
105-
}
106-
if kind == "" {
107-
return "", fmt.Errorf("kind is required")
108-
}
109-
if jsonData == "" {
110-
return "", fmt.Errorf("json data is required")
111-
}
112-
endpoint := fmt.Sprintf(IstioObjectCreateEndpoint,
113-
url.PathEscape(namespace),
114-
url.PathEscape(group),
115-
url.PathEscape(version),
116-
url.PathEscape(kind))
38+
// IstioConfig calls the Kiali Istio config API to get all Istio objects in the mesh.
39+
// Returns the full YAML resources and additional details about each object.
40+
func (k *Kiali) IstioConfig(ctx context.Context, action string, namespace string, group string, version string, kind string, name string, jsonData string) (string, error) {
41+
switch action {
42+
case "get":
43+
endpoint := buildIstioObjectEndpoint(namespace, group, version, kind, name) + "?validate=true&help=true"
44+
return k.executeRequest(ctx, http.MethodGet, endpoint, "", nil)
45+
case "create":
46+
endpoint := buildIstioObjectCreateEndpoint(namespace, group, version, kind)
47+
return k.executeRequest(ctx, http.MethodPost, endpoint, "application/json", strings.NewReader(jsonData))
48+
case "patch":
49+
endpoint := buildIstioObjectEndpoint(namespace, group, version, kind, name)
50+
return k.executeRequest(ctx, http.MethodPatch, endpoint, "application/json", strings.NewReader(jsonData))
51+
case "delete":
52+
endpoint := buildIstioObjectEndpoint(namespace, group, version, kind, name)
53+
return k.executeRequest(ctx, http.MethodDelete, endpoint, "", nil)
54+
default:
55+
var wg sync.WaitGroup
56+
wg.Add(2)
57+
var configsContent string
58+
var configsErr error
59+
var validationsContent string
60+
var validationsErr error
11761

118-
return k.executeRequest(ctx, http.MethodPost, endpoint, "application/json", strings.NewReader(jsonData))
119-
}
62+
// List configs (existing list behavior)
63+
go func() {
64+
defer wg.Done()
65+
endpoint := IstioConfigEndpoint + "?validate=true"
66+
configsContent, configsErr = k.executeRequest(ctx, http.MethodGet, endpoint, "", nil)
67+
}()
12068

121-
// IstioObjectDelete deletes an existing Istio object using DELETE method.
122-
// Parameters:
123-
// - namespace: the namespace containing the Istio object
124-
// - group: the API group (e.g., "networking.istio.io", "gateway.networking.k8s.io")
125-
// - version: the API version (e.g., "v1", "v1beta1")
126-
// - kind: the resource kind (e.g., "DestinationRule", "VirtualService", "HTTPRoute", "Gateway")
127-
// - name: the name of the resource
128-
func (k *Kiali) IstioObjectDelete(ctx context.Context, namespace, group, version, kind, name string) (string, error) {
129-
if namespace == "" {
130-
return "", fmt.Errorf("namespace is required")
131-
}
132-
if group == "" {
133-
return "", fmt.Errorf("group is required")
134-
}
135-
if version == "" {
136-
return "", fmt.Errorf("version is required")
137-
}
138-
if kind == "" {
139-
return "", fmt.Errorf("kind is required")
140-
}
141-
if name == "" {
142-
return "", fmt.Errorf("name is required")
143-
}
144-
endpoint := fmt.Sprintf(IstioObjectEndpoint,
145-
url.PathEscape(namespace),
146-
url.PathEscape(group),
147-
url.PathEscape(version),
148-
url.PathEscape(kind),
149-
url.PathEscape(name))
69+
// List validations, optionally scoped to provided namespace
70+
go func() {
71+
defer wg.Done()
72+
var namespaces []string
73+
if ns := strings.TrimSpace(namespace); ns != "" {
74+
namespaces = []string{ns}
75+
}
76+
validationsContent, validationsErr = k.ValidationsList(ctx, namespaces)
77+
}()
15078

151-
return k.executeRequest(ctx, http.MethodDelete, endpoint, "", nil)
79+
wg.Wait()
80+
if configsErr != nil {
81+
return "", configsErr
82+
}
83+
if validationsErr != nil {
84+
return "", validationsErr
85+
}
86+
87+
resp := IstioConfigListResponse{
88+
Configs: json.RawMessage([]byte(configsContent)),
89+
Validations: json.RawMessage([]byte(validationsContent)),
90+
}
91+
out, err := json.Marshal(resp)
92+
if err != nil {
93+
return "", fmt.Errorf("failed to marshal istio list response: %v", err)
94+
}
95+
return string(out), nil
96+
}
15297
}

0 commit comments

Comments
 (0)