Skip to content
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

feat: hide resources #254

Merged
merged 4 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
.PHONY: vendor
.PHONY: build generate log test vendor

build:
go build -o ldcli

generate:
go generate ./...
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can run make generate if that's easier.


log:
tail -f *.log

Expand Down
145 changes: 0 additions & 145 deletions cmd/resources/resource_cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,22 +124,6 @@ func AddAllResourceCmds(rootCmd *cobra.Command, client resources.Client, analyti
"\u003e ### Available for Pro and Enterprise plans\n\u003e\n\u003e Metrics is available to customers on a Pro or Enterprise plan. To learn more, [read about our pricing](https://launchdarkly.com/pricing/). To add metrics to your plan, [contact Sales](https://launchdarkly.com/contact-sales/).\n\nMetrics track flag behavior over time when an experiment is running. The data generated from experiments gives you more insight into the impact of a particular flag. To learn more, read [Metrics](https://docs.launchdarkly.com/home/metrics).\n\nUsing the metrics API, you can create, delete, and manage metrics.\n\n\u003e ### Are you importing metric events?\n\u003e\n\u003e If you want to import metric events into LaunchDarkly from an existing data source, use the metric import API. To learn more, read [Importing metric events](/home/metrics/import-metric-events).\n\n\u003e ### Metric keys and event keys are different\n\u003e\n\u003e LaunchDarkly automatically generates a metric key when you create a metric. You can use the metric key to identify the metric in API calls.\n\u003e\n\u003e Custom conversion/binary and custom numeric metrics also require an event key. You can set the event key to anything you want. Adding this event key to your codebase lets your SDK track actions customers take in your app as events. To learn more, read [Sending custom events](https://docs.launchdarkly.com/sdk/features/events).\n",
)

gen_Oauth2ClientsResourceCmd := NewResourceCmd(
rootCmd,
analyticsTracker,
"oauth-2-clients",
"Make requests (list, create, etc.) on oauth2 clients",
"The OAuth2 client API allows you to register a LaunchDarkly OAuth client for use in your own custom integrations. Registering a LaunchDarkly OAuth client allows you to use LaunchDarkly as an identity provider so that account members can log into your application with their LaunchDarkly account.\n\nYou can create and manage LaunchDarkly OAuth clients using the LaunchDarkly OAuth client API. This API acknowledges creation of your client with a response containing a one-time, unique `_clientSecret`. If you lose your client secret, you will have to register a new client. LaunchDarkly does not store client secrets in plain text.\n\nSeveral of the endpoints in the OAuth2 client API require an OAuth client ID. The OAuth client ID is returned as part of the [Create a LaunchDarkly OAuth 2.0 client](/tag/OAuth2-Clients#operation/createOAuth2Client) and [Get clients](/tag/OAuth2-Clients#operation/getOAuthClients) responses. It is the `_clientId` field, or the `_clientId` field of each element in the `items` array.\n\nYou must have _Admin_ privileges or an access token created by a member with _Admin_ privileges in order to be able to use this feature.\n\nPlease note that `redirectUri`s must be absolute URIs that conform to the https URI scheme. If you wish to register a client with a different URI scheme, please contact LaunchDarkly Support.\n",
)

gen_OtherResourceCmd := NewResourceCmd(
rootCmd,
analyticsTracker,
"other",
"Make requests (list, create, etc.) on other",
"Other requests available in the LaunchDarkly API. \n",
)

gen_ProjectsResourceCmd := NewResourceCmd(
rootCmd,
analyticsTracker,
Expand Down Expand Up @@ -3009,135 +2993,6 @@ func AddAllResourceCmds(rootCmd *cobra.Command, client resources.Client, analyti
SupportsSemanticPatch: false,
})

NewOperationCmd(gen_Oauth2ClientsResourceCmd, client, OperationData{
Short: "Create a LaunchDarkly OAuth 2.0 client",
Long: "Create (register) a LaunchDarkly OAuth2 client. OAuth2 clients allow you to build custom integrations using LaunchDarkly as your identity provider.",
Use: "create-o-auth-2-client",
Params: []Param{},
HTTPMethod: "POST",
HasBody: true,
RequiresBody: true,
Path: "/api/v2/oauth/clients",
SupportsSemanticPatch: false,
})

NewOperationCmd(gen_Oauth2ClientsResourceCmd, client, OperationData{
Short: "Delete OAuth 2.0 client",
Long: "Delete an existing OAuth 2.0 client by unique client ID.",
Use: "delete-o-auth-client",
Params: []Param{
{
Name: "client-id",
In: "path",
Description: "The client ID",
Type: "string",
},
},
HTTPMethod: "DELETE",
HasBody: false,
RequiresBody: false,
Path: "/api/v2/oauth/clients/{clientId}",
SupportsSemanticPatch: false,
})

NewOperationCmd(gen_Oauth2ClientsResourceCmd, client, OperationData{
Short: "Get client by ID",
Long: "Get a registered OAuth 2.0 client by unique client ID.",
Use: "get-o-auth-client-by-id",
Params: []Param{
{
Name: "client-id",
In: "path",
Description: "The client ID",
Type: "string",
},
},
HTTPMethod: "GET",
HasBody: false,
RequiresBody: false,
Path: "/api/v2/oauth/clients/{clientId}",
SupportsSemanticPatch: false,
})

NewOperationCmd(gen_Oauth2ClientsResourceCmd, client, OperationData{
Short: "Get clients",
Long: "Get all OAuth 2.0 clients registered by your account.",
Use: "list-o-auth-clients",
Params: []Param{},
HTTPMethod: "GET",
HasBody: false,
RequiresBody: false,
Path: "/api/v2/oauth/clients",
SupportsSemanticPatch: false,
})

NewOperationCmd(gen_Oauth2ClientsResourceCmd, client, OperationData{
Short: "Patch client by ID",
Long: "Patch an existing OAuth 2.0 client by client ID. Updating an OAuth2 client uses a [JSON patch](https://datatracker.ietf.org/doc/html/rfc6902) representation of the desired changes. To learn more, read [Updates](/#section/Overview/Updates). Only `name`, `description`, and `redirectUri` may be patched.",
Use: "update-o-auth-client",
Params: []Param{
{
Name: "client-id",
In: "path",
Description: "The client ID",
Type: "string",
},
},
HTTPMethod: "PATCH",
HasBody: true,
RequiresBody: true,
Path: "/api/v2/oauth/clients/{clientId}",
SupportsSemanticPatch: false,
})

NewOperationCmd(gen_OtherResourceCmd, client, OperationData{
Short: "Gets the public IP list",
Long: "Get a list of IP ranges the LaunchDarkly service uses. You can use this list to allow LaunchDarkly through your firewall. We post upcoming changes to this list in advance on our [status page](https://status.launchdarkly.com/). \u003cbr /\u003e\u003cbr /\u003eIn the sandbox, click 'Try it' and enter any string in the 'Authorization' field to test this endpoint.",
Use: "get-ips",
Params: []Param{},
HTTPMethod: "GET",
HasBody: false,
RequiresBody: false,
Path: "/api/v2/public-ip-list",
SupportsSemanticPatch: false,
})

NewOperationCmd(gen_OtherResourceCmd, client, OperationData{
Short: "Gets the OpenAPI spec in json",
Long: "Get the latest version of the OpenAPI specification for LaunchDarkly's API in JSON format. In the sandbox, click 'Try it' and enter any string in the 'Authorization' field to test this endpoint.",
Use: "get-openapi-spec",
Params: []Param{},
HTTPMethod: "GET",
HasBody: false,
RequiresBody: false,
Path: "/api/v2/openapi.json",
SupportsSemanticPatch: false,
})

NewOperationCmd(gen_OtherResourceCmd, client, OperationData{
Short: "Root resource",
Long: "Get all of the resource categories the API supports. In the sandbox, click 'Try it' and enter any string in the 'Authorization' field to test this endpoint.",
Use: "get-root",
Params: []Param{},
HTTPMethod: "GET",
HasBody: false,
RequiresBody: false,
Path: "/api/v2",
SupportsSemanticPatch: false,
})

NewOperationCmd(gen_OtherResourceCmd, client, OperationData{
Short: "Get version information",
Long: "Get the latest API version, the list of valid API versions in ascending order, and the version being used for this request. These are all in the external, date-based format.",
Use: "get-versions",
Params: []Param{},
HTTPMethod: "GET",
HasBody: false,
RequiresBody: false,
Path: "/api/v2/versions",
SupportsSemanticPatch: false,
})

NewOperationCmd(gen_ProjectsResourceCmd, client, OperationData{
Short: "Delete project",
Long: "Delete a project by key. Use this endpoint with caution. Deleting a project will delete all associated environments and feature flags. You cannot delete the last project in an account.",
Expand Down
56 changes: 38 additions & 18 deletions cmd/resources/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,27 +71,11 @@ func GetTemplateData(fileName string) (TemplateData, error) {
return TemplateData{}, err
}

resources := make(map[string]ResourceData)
for _, r := range spec.Tags {
if strings.Contains(r.Name, "(beta)") {
// skip beta resources for now
continue
}

resourceName, resourceKey := getResourceNames(r.Name)
resources[resourceKey] = ResourceData{
GoName: strcase.ToCamel(resourceName),
DisplayName: strings.ToLower(resourceName),
Description: jsonString(r.Description),
Operations: make(map[string]OperationData, 0),
}
}

resources := NewResources(spec.Tags)
for path, pathItem := range spec.Paths.Map() {
for method, op := range pathItem.Operations() {
tag := op.Tags[0] // each op only has one tag
if strings.Contains(tag, "(beta)") {
// skip beta resources for now
if shouldFilter(tag) {
continue
}
_, resourceKey := getResourceNames(tag)
Expand Down Expand Up @@ -149,6 +133,42 @@ func GetTemplateData(fileName string) (TemplateData, error) {
return TemplateData{Resources: resources}, nil
}

func NewResourceData(tag openapi3.Tag) ResourceData {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made some constructor functions to encapsulate the rules for creating a resource data struct type. This is simpler to test than setting up JSON and calling GetTemplateData.

resourceName, _ := getResourceNames(tag.Name)

return ResourceData{
GoName: strcase.ToCamel(resourceName),
DisplayName: strings.ToLower(resourceName),
Description: jsonString(tag.Description),
Operations: make(map[string]OperationData, 0),
}
}

func NewResources(tags openapi3.Tags) map[string]ResourceData {
resources := make(map[string]ResourceData)
for _, t := range tags {
if shouldFilter(t.Name) {
continue
}

resourceName, resourceKey := getResourceNames(t.Name)
resources[resourceKey] = ResourceData{
GoName: strcase.ToCamel(resourceName),
DisplayName: strings.ToLower(resourceName),
Description: jsonString(t.Description),
Operations: make(map[string]OperationData, 0),
}
}

return resources
}

func shouldFilter(name string) bool {
return strings.Contains(name, "(beta)") ||
strings.ToLower(name) == "other" ||
strings.ToLower(name) == "oauth2 clients"
}

func NewResourceCmd(parentCmd *cobra.Command, analyticsTracker analytics.Tracker, resourceName, shortDescription, longDescription string) *cobra.Command {
cmd := &cobra.Command{
Use: resourceName,
Expand Down
75 changes: 75 additions & 0 deletions cmd/resources/resources_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package resources_test

import (
"testing"

"github.com/getkin/kin-openapi/openapi3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"ldcli/cmd/resources"
)

func TestNewResourceData(t *testing.T) {
t.Run("converts OpenAPI spec to a resource", func(t *testing.T) {
tag := openapi3.Tag{
Name: "My resources",
Description: "description",
}

resource := resources.NewResourceData(tag)

assert.Equal(t, "MyResources", resource.GoName)
assert.Equal(t, "my resources", resource.DisplayName)
assert.Equal(t, `"description"`, resource.Description)
})
}

func TestNewResources(t *testing.T) {
t.Run("builds a map of resources", func(t *testing.T) {
tags := openapi3.Tags{
{
Name: "My resources",
},
{
Name: "My resources2",
},
}

rs := resources.NewResources(tags)

require.Len(t, rs, 2)
assert.Equal(t, "MyResources", rs["my-resources"].GoName)
assert.Equal(t, "MyResources2", rs["my-resources-2"].GoName)
})

t.Run("skips certain endpoints", func(t *testing.T) {
tests := map[string]struct {
name string
}{
"skips beta endpoints": {
name: "My resources (beta)",
},
"skips oauth2- endpoints": {
name: "OAuth2 clients",
},
"skips other endpoints": {
name: "Other",
},
}
for name, tt := range tests {
tt := tt
t.Run(name, func(t *testing.T) {
tags := openapi3.Tags{
{
Name: tt.name,
},
}

rs := resources.NewResources(tags)

assert.Len(t, rs, 0)
})
}
})
}
Loading