Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/mark3labs/mcp-go v0.43.1
github.com/spf13/cobra v1.10.1
github.com/spf13/viper v1.21.0
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand All @@ -34,5 +35,4 @@ require (
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.28.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
141 changes: 141 additions & 0 deletions pkg/tools/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,3 +367,144 @@ func createRequest(ctx context.Context, reqUrl *url.URL, keys *ContextKeys, opts
applyAuthHeader(req, keys)
return req, nil
}

func ListConfs(ctx context.Context, client Client) ([]*ConfSummary, error) {
keys, err := FetchContextKeys(ctx)
if err != nil {
return nil, err
}

confsURL, err := url.Parse(fmt.Sprintf("%s/v1/orgs/%s/confs", client.APIURL(), keys.OrgID))
if err != nil {
return nil, err
}

req, err := createRequest(ctx, confsURL, keys, func(v url.Values) {
v.Set("empty_contents", "true")
})
if err != nil {
return nil, fmt.Errorf("failed to create confs request: %v", err)
}

resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
bodyBytes, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("failed to list confs, status code %d: %s", resp.StatusCode, string(bodyBytes))
}

var out []*ConfSummary
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
return nil, fmt.Errorf("failed to decode confs response: %v", err)
}
return out, nil
}

func GetIngestionEndpoints(ctx context.Context, client Client) (*IngestionEndpointsResponse, error) {
keys, err := FetchContextKeys(ctx)
if err != nil {
return nil, err
}

endpointsURL, err := url.Parse(fmt.Sprintf("%s/v1/orgs/%s/ingestion_endpoints", client.APIURL(), keys.OrgID))
if err != nil {
return nil, err
}

req, err := createRequest(ctx, endpointsURL, keys)
if err != nil {
return nil, fmt.Errorf("failed to create ingestion_endpoints request: %v", err)
}

resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
bodyBytes, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("failed to get ingestion endpoints, status code %d: %s", resp.StatusCode, string(bodyBytes))
}

var out IngestionEndpointsResponse
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
return nil, fmt.Errorf("failed to decode ingestion_endpoints response: %v", err)
}
return &out, nil
}

func GetIngestionToken(ctx context.Context, client Client, confID, nodeName string) (*IngestionTokenResponse, error) {
keys, err := FetchContextKeys(ctx)
if err != nil {
return nil, err
}

tokenURL, err := url.Parse(fmt.Sprintf("%s/v1/orgs/%s/ingestion_token", client.APIURL(), keys.OrgID))
if err != nil {
return nil, err
}

req, err := createRequest(ctx, tokenURL, keys, func(v url.Values) {
v.Set("conf_id", confID)
v.Set("node_name", nodeName)
})
if err != nil {
return nil, fmt.Errorf("failed to create ingestion_token request: %v", err)
}

resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
bodyBytes, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("failed to get ingestion token, status code %d: %s", resp.StatusCode, string(bodyBytes))
}

var out IngestionTokenResponse
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
return nil, fmt.Errorf("failed to decode ingestion_token response: %v", err)
}
return &out, nil
}

func GetConf(ctx context.Context, client Client, confID string) (*ConfSummary, error) {
keys, err := FetchContextKeys(ctx)
if err != nil {
return nil, err
}

confURL, err := url.Parse(fmt.Sprintf("%s/v1/orgs/%s/confs/%s", client.APIURL(), keys.OrgID, confID))
if err != nil {
return nil, err
}

req, err := createRequest(ctx, confURL, keys)
if err != nil {
return nil, fmt.Errorf("failed to create get-conf request: %v", err)
}

resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
bodyBytes, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("failed to get conf %s, status code %d: %s", confID, resp.StatusCode, string(bodyBytes))
}

var out ConfSummary
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
return nil, fmt.Errorf("failed to decode conf response: %v", err)
}
return &out, nil
}
39 changes: 36 additions & 3 deletions pkg/tools/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ const (
type FleetType string

const (
EdgeFleetType FleetType = "Edge"
CloudFleetType FleetType = "Cloud"
GatewayFleetType FleetType = "Gateway"
EdgeFleetType FleetType = "Edge"
CloudFleetType FleetType = "Cloud"
GatewayFleetType FleetType = "Gateway"
IngestionPipelineFleetType FleetType = "IngestionPipeline"
)

// FleetStatus represents the status of a fleet
Expand All @@ -69,3 +70,35 @@ type PipelineSummary struct {
FleetType FleetType `json:"fleet_type,omitempty"`
Status FleetStatus `json:"status,omitempty"`
}

// IngestionEndpointsResponse mirrors the backend response from
// GET /v1/orgs/{org_id}/ingestion_endpoints
type IngestionEndpointsResponse struct {
HTTPS *HTTPSIngestionEndpoints `json:"https,omitempty"`
}

type HTTPSIngestionEndpoints struct {
BaseURL string `json:"base_url"`
PathForDataType map[string]string `json:"path_for_data_type"`
SampleData map[string]string `json:"sample_data"`
TestCommands map[string]string `json:"test_commands"`
}

// IngestionTokenResponse mirrors the backend response from
// GET /v1/orgs/{org_id}/ingestion_token
type IngestionTokenResponse struct {
RawToken string `json:"raw_token"`
TokenID string `json:"token_id"`
OrgID string `json:"org_id"`
ConfID string `json:"conf_id"`
NodeName string `json:"node_name"`
}

// ConfSummary mirrors the fields of backend/core.Conf that this package uses.
// The backend endpoint returns more fields; we only decode what we need.
type ConfSummary struct {
ID string `json:"id"`
Tag string `json:"tag"`
FleetType FleetType `json:"fleet_type"`
Content string `json:"content,omitempty"`
}
Loading
Loading