1+ package cmd
2+
3+ import (
4+ "encoding/json"
5+ "fmt"
6+ "io"
7+ "net/http"
8+ "net/url"
9+ "time"
10+ )
11+
12+ // API client for Access Analyzer
13+ type APIClient struct {
14+ BaseURL string
15+ Client * http.Client
16+ }
17+
18+ // SourceType represents a scanner/source type from the API
19+ type SourceType struct {
20+ SourceTypeID string `json:"sourceTypeId"`
21+ TypeName string `json:"typeName"`
22+ DisplayName string `json:"displayName"`
23+ Description string `json:"description"`
24+ Version string `json:"version"`
25+ ScannerImage string `json:"scannerImage"`
26+ IsActive bool `json:"isActive"`
27+ IsBuiltIn bool `json:"isBuiltIn"`
28+ CreatedAt string `json:"createdAt"`
29+ UpdatedAt string `json:"updatedAt"`
30+ SupportedScans []string `json:"supportedScanTypes,omitempty"`
31+ Icon string `json:"icon,omitempty"`
32+ }
33+
34+ // SourceTypeListResponse represents the API response for listing source types
35+ type SourceTypeListResponse struct {
36+ Data []SourceType `json:"data"`
37+ Pagination PaginationMetadata `json:"pagination"`
38+ }
39+
40+ // PaginationMetadata represents pagination information
41+ type PaginationMetadata struct {
42+ Page int `json:"page"`
43+ PageSize int `json:"pageSize"`
44+ TotalItems int `json:"totalItems"`
45+ TotalPages int `json:"totalPages"`
46+ }
47+
48+ // NewAPIClient creates a new API client
49+ func NewAPIClient (baseURL string ) * APIClient {
50+ return & APIClient {
51+ BaseURL : baseURL ,
52+ Client : & http.Client {
53+ Timeout : 30 * time .Second ,
54+ },
55+ }
56+ }
57+
58+ // GetSourceTypes fetches all source types from the API
59+ func (c * APIClient ) GetSourceTypes () (* SourceTypeListResponse , error ) {
60+ // Build URL with pagination
61+ u , err := url .Parse (c .BaseURL + "/source-types" )
62+ if err != nil {
63+ return nil , fmt .Errorf ("invalid base URL: %w" , err )
64+ }
65+
66+ params := url.Values {}
67+ params .Set ("page" , "1" )
68+ params .Set ("pageSize" , "100" ) // Get all scanners in one request
69+ u .RawQuery = params .Encode ()
70+
71+ // Make HTTP request
72+ resp , err := c .Client .Get (u .String ())
73+ if err != nil {
74+ return nil , fmt .Errorf ("failed to make API request: %w" , err )
75+ }
76+ defer resp .Body .Close ()
77+
78+ // Check status code
79+ if resp .StatusCode != http .StatusOK {
80+ body , _ := io .ReadAll (resp .Body )
81+ return nil , fmt .Errorf ("API request failed with status %d: %s" , resp .StatusCode , string (body ))
82+ }
83+
84+ // Parse response
85+ var result SourceTypeListResponse
86+ if err := json .NewDecoder (resp .Body ).Decode (& result ); err != nil {
87+ return nil , fmt .Errorf ("failed to parse API response: %w" , err )
88+ }
89+
90+ return & result , nil
91+ }
92+
93+ // TestConnection tests the connection to the API
94+ func (c * APIClient ) TestConnection () error {
95+ // Try to get source types as a health check
96+ resp , err := c .Client .Get (c .BaseURL + "/source-types?page=1&pageSize=1" )
97+ if err != nil {
98+ return fmt .Errorf ("connection failed: %w" , err )
99+ }
100+ defer resp .Body .Close ()
101+
102+ if resp .StatusCode != http .StatusOK {
103+ body , _ := io .ReadAll (resp .Body )
104+ return fmt .Errorf ("API returned status %d: %s" , resp .StatusCode , string (body ))
105+ }
106+
107+ return nil
108+ }
109+
110+ // Helper function to get API client with configured endpoint
111+ func getAPIClient () (* APIClient , error ) {
112+ endpoint , err := getAAEndpoint ()
113+ if err != nil {
114+ return nil , err
115+ }
116+
117+ if endpoint == "" {
118+ return nil , fmt .Errorf ("no endpoint configured - use 'nwx aa config --endpoint=\" <url>\" '" )
119+ }
120+
121+ return NewAPIClient (endpoint ), nil
122+ }
0 commit comments