Skip to content

Commit

Permalink
feat: add beta endpoints tor resource commands (#307)
Browse files Browse the repository at this point in the history
* remove beta filter

* add beta header when beta endpoint is called

* fix beta commands

* rename feature flags beta

* remove backquotes from param descriptions

* rename fn

* pr feedback
  • Loading branch information
k3llymariee authored May 29, 2024
1 parent 29cf3b3 commit 03d71e3
Show file tree
Hide file tree
Showing 10 changed files with 3,272 additions and 962 deletions.
1 change: 1 addition & 0 deletions cmd/flags/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func makeArchiveRequest(client resources.Client) func(*cobra.Command, []string)
"application/json",
nil,
[]byte(`[{"op": "replace", "path": "/archived", "value": true}]`),
false,
)
if err != nil {
return errors.NewError(output.CmdOutputError(viper.GetString(cliflags.OutputFlag), err))
Expand Down
1 change: 1 addition & 0 deletions cmd/flags/toggle.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func runE(client resources.Client) func(*cobra.Command, []string) error {
"application/json",
nil,
[]byte(buildPatch(viper.GetString("environment"), toggleOn)),
false,
)
if err != nil {
return errors.NewError(output.CmdOutputError(viper.GetString(cliflags.OutputFlag), err))
Expand Down
1 change: 1 addition & 0 deletions cmd/members/invite.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func runE(client resources.Client) func(*cobra.Command, []string) error {
"application/json",
nil,
membersJson,
false,
)
if err != nil {
return errors.NewError(output.CmdOutputError(viper.GetString(cliflags.OutputFlag), err))
Expand Down
4,164 changes: 3,219 additions & 945 deletions cmd/resources/resource_cmds.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cmd/resources/resource_cmds.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func AddAllResourceCmds(
},
HTTPMethod: "{{ $opData.HTTPMethod }}",
HasBody: {{ $opData.HasBody }},
IsBeta: {{ $opData.IsBeta }},
RequiresBody: {{ $opData.RequiresBody }},
Path: "{{ $opData.Path }}",
SupportsSemanticPatch: {{ $opData.SupportsSemanticPatch }},
Expand Down
32 changes: 25 additions & 7 deletions cmd/resources/resource_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,25 @@ import (
// we have certain tags that aren't a 1:1 match to their operation id names
var mapTagToSchemaName = map[string]string{
"Account members": "Members",
"Account members (beta)": "Members beta",
"Approvals": "Approval requests",
"Code references": "Code refs",
"User settings": "User flag settings",
"Relay Proxy configurations": "Relay Proxy configs",
"Feature flags (beta)": "Flags beta",
"Integration audit log subscriptions": "Integration subscriptions",
"Metrics (beta)": "Metric groups beta",
"Relay Proxy configurations": "Relay Proxy configs",
"User settings": "User flag settings",
}

func getResourceNames(name string) (string, string) {
if mappedName, ok := mapTagToSchemaName[name]; ok {
name = mappedName
}

// remove parenthesis for (beta) endpoints
re := regexp.MustCompile(`\(([^)]+)\)`)
name = re.ReplaceAllString(name, "$1")

resourceKey := strcase.ToKebab(name)
// the operationIds use "FeatureFlag" so we want to keep that whole, but the command should just be `flags`
if name == "Feature flags" {
Expand All @@ -49,6 +56,7 @@ var mapOperationIdToCmdUse = map[string]string{
"getCustomWorkflow": "get",
"getDestination": "get",
"getDestinations": "list",
"getExperimentationSettings": "get-settings",
"getExpiringFlagsForUser": "list-expiring",
"getFeatureFlagScheduledChange": "get",
"getFlagConfigScheduledChanges": "list",
Expand All @@ -66,14 +74,17 @@ var mapOperationIdToCmdUse = map[string]string{
"patchDestination": "update",
"patchExpiringFlagsForUser": "update-expiring",
"patchFlagConfigScheduledChange": "update",
"patchMembers": "update-multiple",
"patchRelayAutoConfig": "update",
"patchTeams": "update-multiple",
"patchToken": "update",
"patchTriggerWorkflow": "update",
"postDestination": "create",
"postFlagConfigScheduledChanges": "create",
"postRelayAutoConfig": "create",
"postToken": "create",
"putContextFlagSetting": "replace",
"putExperimentationSettings": "replace-settings",
"putFlagFollowers": "replace",
"putFlagSetting": "replace",
"resetRelayAutoConfig": "reset",
Expand All @@ -83,6 +94,7 @@ var mapOperationIdToCmdUse = map[string]string{

func replaceMethodWithCmdUse(operationId string) string {
r := strings.NewReplacer(
"get-all", "list",
"post", "create",
"patch", "update",
"put", "replace",
Expand All @@ -92,16 +104,19 @@ func replaceMethodWithCmdUse(operationId string) string {
}

func removeResourceFromOperationId(resourceName, operationId string) string {
// strip the Beta tag from the resource name to properly remove it from the operation ID
resourceName = strings.TrimRight(resourceName, "Beta")

// operations use both singular (Team) and plural (Teams) resource names, whereas resource names are (usually) plural
var singularResourceName string
if strings.HasSuffix("teams", "s") {
singularResourceName = strings.TrimRight(resourceName, "s")
}
singularResourceName := strings.TrimRight(resourceName, "s")

r := strings.NewReplacer(
// a lot of "list" operations say "GetFor{ResourceName}"
fmt.Sprintf("For%s", singularResourceName), "",
fmt.Sprintf("For%s", resourceName), "",
"ByFlagKey", "",
"ById", "",
"ByKey", "",
"ByProject", "",
resourceName, "",
singularResourceName, "",
Expand Down Expand Up @@ -161,7 +176,6 @@ var mapParamToFlagName = map[string]string{
func stripFlagName(flagName string) string {
r := strings.NewReplacer(
"-key", "",
"-id", "",
)

return r.Replace(flagName)
Expand All @@ -175,3 +189,7 @@ func getFlagName(paramName string) string {
}
return flagName
}

func replaceBackticks(s string) string {
return strings.Replace(s, "`", "'", -1)
}
17 changes: 13 additions & 4 deletions cmd/resources/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type OperationData struct {
Params []Param
HTTPMethod string
HasBody bool
IsBeta bool
RequiresBody bool
Path string
SupportsSemanticPatch bool
Expand Down Expand Up @@ -119,32 +120,40 @@ func GetTemplateData(fileName string) (TemplateData, error) {
requiresBody = op.RequestBody.Value.Required
}

isBeta := strings.Contains(tag, "(beta)")

operation := OperationData{
Short: jsonString(op.Summary),
Long: jsonString(op.Description),
Use: use,
Params: make([]Param, 0),
HTTPMethod: method,
HasBody: hasBody,
IsBeta: isBeta,
RequiresBody: requiresBody,
Path: path,
SupportsSemanticPatch: supportsSemanticPatch,
}

for _, p := range op.Parameters {
if p.Value != nil {
// TODO: confirm if we only have one type per param b/c somehow this is a slice
if strings.Contains(p.Value.Description, "Deprecated") {
continue
}
// TODO: confirm if we only have one type per param b/c somehow this is a slice
types := *p.Value.Schema.Value.Type

// cobra will try to take backquoted values as the type, so we remove them
description := replaceBackticks(p.Value.Description)

param := Param{
Name: strcase.ToKebab(p.Value.Name),
In: p.Value.In,
Description: jsonString(p.Value.Description),
Description: jsonString(description),
Type: types[0],
Required: p.Value.Required,
}

operation.Params = append(operation.Params, param)
}
}
Expand Down Expand Up @@ -187,8 +196,7 @@ func NewResources(tags openapi3.Tags) map[string]ResourceData {
}

func shouldFilter(name string) bool {
return strings.Contains(name, "(beta)") ||
strings.Contains(name, "User") ||
return strings.Contains(name, "User") ||
strings.ToLower(name) == "other" ||
strings.ToLower(name) == "oauth2 clients"
}
Expand Down Expand Up @@ -326,6 +334,7 @@ func (op *OperationCmd) makeRequest(cmd *cobra.Command, args []string) error {
contentType,
query,
jsonData,
op.IsBeta,
)
if err != nil {
return errors.NewError(output.CmdOutputError(viper.GetString(cliflags.OutputFlag), err))
Expand Down
9 changes: 5 additions & 4 deletions cmd/resources/resources_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,23 @@ func TestNewResources(t *testing.T) {
{
Name: "My resources2",
},
{
Name: "My resources (beta)",
},
}

rs := resources.NewResources(tags)

require.Len(t, rs, 2)
require.Len(t, rs, 3)
assert.Equal(t, "MyResources", rs["my-resources"].GoName)
assert.Equal(t, "MyResources2", rs["my-resources-2"].GoName)
assert.Equal(t, "MyResourcesBeta", rs["my-resources-beta"].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",
},
Expand Down
7 changes: 5 additions & 2 deletions internal/resources/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

type Client interface {
MakeRequest(accessToken, method, path, contentType string, query url.Values, data []byte) ([]byte, error)
MakeRequest(accessToken, method, path, contentType string, query url.Values, data []byte, isBeta bool) ([]byte, error)
}

type ResourcesClient struct {
Expand All @@ -24,13 +24,16 @@ func NewClient(cliVersion string) ResourcesClient {
return ResourcesClient{cliVersion: cliVersion}
}

func (c ResourcesClient) MakeRequest(accessToken, method, path, contentType string, query url.Values, data []byte) ([]byte, error) {
func (c ResourcesClient) MakeRequest(accessToken, method, path, contentType string, query url.Values, data []byte, isBeta bool) ([]byte, error) {
client := http.Client{}

req, _ := http.NewRequest(method, path, bytes.NewReader(data))
req.Header.Add("Authorization", accessToken)
req.Header.Add("Content-type", contentType)
req.Header.Set("User-Agent", fmt.Sprintf("launchdarkly-cli/v%s", c.cliVersion))
if isBeta {
req.Header.Set("LD-API-Version", "beta")
}
req.URL.RawQuery = query.Encode()

res, err := client.Do(req)
Expand Down
1 change: 1 addition & 0 deletions internal/resources/mock_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func (c *MockClient) MakeRequest(
accessToken, method, path, contentType string,
query url.Values,
data []byte,
isBeta bool,
) ([]byte, error) {
c.Input = data

Expand Down

0 comments on commit 03d71e3

Please sign in to comment.