-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Implement dynamic registration for Cobra commands based on Equinix SDK types #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4d4cb80
370e781
81e3714
3f3ee7b
8d7ba43
f204629
aca4d49
6fbf310
ce7d57b
de2741a
1ba52af
e71f6f0
cdb3bea
95507a1
4067033
0f92bbd
1a5e23b
0d8af9b
8950f84
00657d1
30709d7
813507d
73bd372
2ceec37
737e15f
6f22f4d
9683b98
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| // Package main provides a CLI tool to extract SDK descriptions | ||
| package main | ||
|
|
||
| import ( | ||
| "flag" | ||
| "fmt" | ||
| "os" | ||
|
|
||
| "github.com/equinix/cli/internal/parser" | ||
| ) | ||
|
|
||
| func main() { | ||
| sdkPath := flag.String("sdk-path", "", "Path to the SDK source directory (required)") | ||
| outputFile := flag.String("output", "descriptions.json", "Output JSON file path") | ||
| flag.Parse() | ||
|
|
||
| if *sdkPath == "" { | ||
| fmt.Fprintln(os.Stderr, "Error: --sdk-path is required") | ||
| flag.Usage() | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| fmt.Printf("Extracting descriptions from SDK at: %s\n", *sdkPath) | ||
| descriptions, err := parser.ExtractDescriptions(*sdkPath) | ||
| if err != nil { | ||
| fmt.Fprintf(os.Stderr, "Error extracting descriptions: %v\n", err) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| fmt.Printf("Found %d services\n", len(descriptions.Services)) | ||
| for name, service := range descriptions.Services { | ||
| fmt.Printf(" - %s: %d methods, %d types\n", name, len(service.Methods), len(service.Types)) | ||
| } | ||
| fmt.Printf("Found %d global types\n", len(descriptions.Types)) | ||
|
|
||
| fmt.Printf("Saving descriptions to: %s\n", *outputFile) | ||
| if err := descriptions.SaveToFile(*outputFile); err != nil { | ||
| fmt.Fprintf(os.Stderr, "Error saving descriptions: %v\n", err) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| fmt.Println("Successfully extracted and saved SDK descriptions") | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,8 @@ import ( | |
| "io" | ||
| "log" | ||
| "net/http" | ||
| "net/http/httputil" | ||
| "os" | ||
|
|
||
| equinixoauth2 "github.com/equinix/equinix-sdk-go/extensions/equinixoauth2" | ||
| "github.com/spf13/viper" | ||
|
|
@@ -30,9 +32,43 @@ type Client struct { | |
| HTTPClient *http.Client | ||
| } | ||
|
|
||
| // debugTransport wraps an HTTP transport to log requests and responses when debug mode is enabled | ||
| type debugTransport struct { | ||
| transport http.RoundTripper | ||
| } | ||
|
|
||
| func (t *debugTransport) RoundTrip(req *http.Request) (*http.Response, error) { | ||
| // Log the request | ||
| fmt.Fprintf(os.Stderr, "\n==================== HTTP REQUEST ====================\n") | ||
| reqDump, err := httputil.DumpRequestOut(req, true) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you said that the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I added a |
||
| if err != nil { | ||
| fmt.Fprintf(os.Stderr, "Error dumping request: %v\n", err) | ||
| } else { | ||
| fmt.Fprintf(os.Stderr, "%s\n", string(reqDump)) | ||
| } | ||
| fmt.Fprintf(os.Stderr, "======================================================\n") | ||
|
|
||
| // Execute the request | ||
| resp, err := t.transport.RoundTrip(req) | ||
|
|
||
| if resp != nil { | ||
| // Log the response | ||
| fmt.Fprintf(os.Stderr, "\n==================== HTTP RESPONSE ====================\n") | ||
| respDump, dumpErr := httputil.DumpResponse(resp, true) | ||
| if dumpErr != nil { | ||
| fmt.Fprintf(os.Stderr, "Error dumping response: %v\n", dumpErr) | ||
| } else { | ||
| fmt.Fprintf(os.Stderr, "%s\n", string(respDump)) | ||
| } | ||
| fmt.Fprintf(os.Stderr, "=======================================================\n\n") | ||
| } | ||
|
|
||
| return resp, err | ||
| } | ||
|
|
||
| // NewStandardClient creates a new Client for Equinix APIs that exist under | ||
| // api.equinix.com and use OAuth2 client credentials for authentication | ||
| func NewStandardClient() (*Client, error) { | ||
| func NewStandardClient(options ...ClientOption) (*Client, error) { | ||
| client := &Client{ | ||
| BaseURL: "https://api.equinix.com", | ||
| DefaultHeaders: standardHeaders, | ||
|
|
@@ -51,11 +87,28 @@ func NewStandardClient() (*Client, error) { | |
| BaseURL: client.BaseURL, | ||
| } | ||
| authTransport := authConfig.New() | ||
| client.HTTPClient.Transport = authTransport | ||
|
|
||
| // Apply options to potentially wrap the transport | ||
| transport := http.RoundTripper(authTransport) | ||
| for _, opt := range options { | ||
| transport = opt(transport) | ||
| } | ||
|
|
||
| client.HTTPClient.Transport = transport | ||
|
|
||
| return client, nil | ||
| } | ||
|
|
||
| // ClientOption is a function that can modify the HTTP transport | ||
| type ClientOption func(http.RoundTripper) http.RoundTripper | ||
|
|
||
| // WithDebug returns a ClientOption that enables debug logging of HTTP requests and responses | ||
| func WithDebug() ClientOption { | ||
| return func(transport http.RoundTripper) http.RoundTripper { | ||
| return &debugTransport{transport: transport} | ||
| } | ||
| } | ||
|
|
||
| // NewPortalClient creates a new Client for Equinix APIs that exist under | ||
| // portal.equinix.com and rely on Cookies to transmit OAuth2 tokens | ||
| func NewPortalClient() (*Client, error) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug transport is something I would like to see built in to the SDK, as a follow-on to the introduction of shared templates for consistent code across services. Wouldn't be a super impactful change here, since we'd still need to explicitly wire up a client in the CLI for common use across SDK and non-SDK requests, but this implementation could be copied into the SDK later.