Skip to content

Commit 0e140b7

Browse files
Allow Viewing of Disabled Params
Resolves #3583 Add a new subcommand "algorand-indexer api-config" to show current config
1 parent 8d85bf4 commit 0e140b7

File tree

7 files changed

+211
-6
lines changed

7 files changed

+211
-6
lines changed

README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,50 @@ When `--token your-token` is provided, an authentication header is required. For
112112
~$ curl localhost:8980/transactions -H "X-Indexer-API-Token: your-token"
113113
```
114114

115+
## Disabling Parameters
116+
117+
The Indexer has the ability to selectively enable or disable parameters for endpoints. Disabling a "required" parameter will result in the entire endpoint being disabled while disabling an "optional" parameter will cause an error to be returned only if the parameter is provided.
118+
119+
### Viewing the Current Configuration
120+
121+
The Indexer has a default set of disabled parameters. To view the disabled parameters issue:
122+
```
123+
~$ algorand-indexer api-config
124+
```
125+
126+
This will output ONLY the disabled parameters in a YAML configuration. To view all parameters (both enabled and disabled) issue:
127+
128+
```
129+
~$ algorand-indexer api-config all
130+
```
131+
132+
### Interpreting The Configuration
133+
134+
Below is a sample output of what the output of `algorand-indexer api-config` will look like:
135+
136+
```
137+
/v2/accounts:
138+
optional:
139+
- currency-greater-than: disabled
140+
- currency-less-than: disabled
141+
/v2/assets/{asset-id}/transactions:
142+
optional:
143+
- note-prefix: disabled
144+
- tx-type: disabled
145+
- sig-type: disabled
146+
- before-time: disabled
147+
- after-time: disabled
148+
- currency-greater-than: disabled
149+
- currency-less-than: disabled
150+
- address-role: disabled
151+
- exclude-close-to: disabled
152+
- rekey-to: disabled
153+
required:
154+
- asset-id: disabled
155+
```
156+
157+
Seeing this we know that the `/v2/accounts` endpoint will return an error if either `currency-greater-than` or `currency-less-than` is provided. Additionally, because a "required" parameter is provided for `/v2/assets/{asset-id}/transactions` then we know this entire endpoint is disabled. The optional parameters are provided so that you can understand what else is disabled if you enable all "required" parameters.
158+
115159
## Metrics
116160

117161
The `/metrics` endpoint is configured with the `--metrics-mode` option and configures if and how [Prometheus](https://prometheus.io/) formatted metrics are generated.

api/disabled_parameters.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,103 @@ import (
77

88
"github.com/getkin/kin-openapi/openapi3"
99
"github.com/labstack/echo/v4"
10+
"gopkg.in/yaml.v3"
1011
)
1112

13+
// DisplayDisabledMap is a struct that contains the necessary information
14+
// to output the current config to the screen
15+
type DisplayDisabledMap struct {
16+
// A complicated map but necessary to output the correct YAML.
17+
// This is supposed to represent a data structure with a similar YAML
18+
// representation:
19+
// /v2/accounts/{account-id}:
20+
// required:
21+
// - account-id : enabled
22+
// /v2/accounts:
23+
// optional:
24+
// - auth-addr : enabled
25+
// - next: disabled
26+
Data map[string]map[string][]map[string]string
27+
}
28+
29+
func (ddm *DisplayDisabledMap) String() (string, error) {
30+
31+
if len(ddm.Data) == 0 {
32+
return "", nil
33+
}
34+
35+
bytes, err := yaml.Marshal(ddm.Data)
36+
if err != nil {
37+
return "", err
38+
}
39+
40+
return string(bytes), nil
41+
}
42+
43+
func makeDisplayDisabledMap() *DisplayDisabledMap {
44+
return &DisplayDisabledMap{
45+
Data: make(map[string]map[string][]map[string]string),
46+
}
47+
}
48+
49+
func (ddm *DisplayDisabledMap) addEntry(restPath string, requiredOrOptional string, entryName string, status string) {
50+
if ddm.Data == nil {
51+
ddm.Data = make(map[string]map[string][]map[string]string)
52+
}
53+
54+
if ddm.Data[restPath] == nil {
55+
ddm.Data[restPath] = make(map[string][]map[string]string)
56+
}
57+
58+
mapEntry := map[string]string{entryName: status}
59+
60+
ddm.Data[restPath][requiredOrOptional] = append(ddm.Data[restPath][requiredOrOptional], mapEntry)
61+
}
62+
63+
// MakeDisplayDisabledMapFromConfig will make a DisplayDisabledMap that takes into account the DisabledMapConfig.
64+
// If limited is set to true, then only disabled parameters will be added to the DisplayDisabledMap
65+
func MakeDisplayDisabledMapFromConfig(swag *openapi3.Swagger, mapConfig *DisabledMapConfig, limited bool) *DisplayDisabledMap {
66+
67+
rval := makeDisplayDisabledMap()
68+
for restPath, item := range swag.Paths {
69+
70+
for opName, opItem := range item.Operations() {
71+
72+
for _, pref := range opItem.Parameters {
73+
74+
paramName := pref.Value.Name
75+
76+
parameterIsDisabled := mapConfig.isDisabled(restPath, opName, paramName)
77+
// If we are limited, then don't bother with enabled parameters
78+
if !parameterIsDisabled && limited {
79+
// If the parameter is not disabled, then we don't need
80+
// to do anything
81+
continue
82+
}
83+
84+
var statusStr string
85+
86+
if parameterIsDisabled {
87+
statusStr = "disabled"
88+
} else {
89+
statusStr = "enabled"
90+
}
91+
92+
if pref.Value.Required {
93+
rval.addEntry(restPath, "required", paramName, statusStr)
94+
} else {
95+
// If the optional parameter is disabled, add it to the map
96+
rval.addEntry(restPath, "optional", paramName, statusStr)
97+
}
98+
}
99+
100+
}
101+
102+
}
103+
104+
return rval
105+
}
106+
12107
// EndpointConfig is a data structure that contains whether the
13108
// endpoint is disabled (with a boolean) as well as a set that
14109
// contains disabled optional parameters. The disabled optional parameter

api/server.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func (e ExtraOptions) handlerTimeout() time.Duration {
5050
}
5151

5252
// Serve starts an http server for the indexer API. This call blocks.
53-
func Serve(ctx context.Context, serveAddr string, db idb.IndexerDb, fetcherError error, log *log.Logger, options ExtraOptions) {
53+
func Serve(ctx context.Context, disabledMapConfig *DisabledMapConfig, serveAddr string, db idb.IndexerDb, fetcherError error, log *log.Logger, options ExtraOptions) {
5454
e := echo.New()
5555
e.HideBanner = true
5656

@@ -83,10 +83,6 @@ func Serve(ctx context.Context, serveAddr string, db idb.IndexerDb, fetcherError
8383
log.Fatal(err)
8484
}
8585

86-
// TODO enable this when command line options allows for disabling/enabling overrides
87-
//disabledMapConfig := GetDefaultDisabledMapConfigForPostgres()
88-
disabledMapConfig := MakeDisabledMapConfig()
89-
9086
disabledMap, err := MakeDisabledMapFromOA3(swag, disabledMapConfig)
9187
if err != nil {
9288
log.Fatal(err)

cmd/algorand-indexer/api_config.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/spf13/cobra"
8+
9+
"github.com/algorand/indexer/api"
10+
"github.com/algorand/indexer/api/generated/v2"
11+
"github.com/algorand/indexer/config"
12+
)
13+
14+
var apiConfigCmd = &cobra.Command{
15+
Use: "api-config",
16+
Short: "dump api configuration",
17+
Long: "dump api configuration",
18+
//Args:
19+
Run: func(cmd *cobra.Command, args []string) {
20+
var err error
21+
config.BindFlags(cmd)
22+
err = configureLogger()
23+
if err != nil {
24+
fmt.Fprintf(os.Stderr, "failed to configure logger: %v", err)
25+
os.Exit(1)
26+
}
27+
swag, err := generated.GetSwagger()
28+
29+
if err != nil {
30+
fmt.Fprintf(os.Stderr, "failed to get swagger: %v", err)
31+
os.Exit(1)
32+
}
33+
34+
var displayDisabledMapConfig *api.DisplayDisabledMap
35+
// Show a limited subset
36+
if len(args) == 0 {
37+
displayDisabledMapConfig = api.MakeDisplayDisabledMapFromConfig(swag, disabledMapConfig, true)
38+
39+
} else {
40+
// This is the only acceptable option
41+
if args[0] != "all" {
42+
fmt.Fprintf(os.Stderr, "unrecognized option to api-config: %s", args[0])
43+
os.Exit(1)
44+
}
45+
46+
displayDisabledMapConfig = api.MakeDisplayDisabledMapFromConfig(swag, disabledMapConfig, false)
47+
}
48+
49+
output, err := displayDisabledMapConfig.String()
50+
51+
if err != nil {
52+
fmt.Fprintf(os.Stderr, "failed to output yaml: %v", err)
53+
os.Exit(1)
54+
}
55+
56+
fmt.Fprint(os.Stdout, output)
57+
os.Exit(0)
58+
59+
},
60+
}

cmd/algorand-indexer/daemon.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ var daemonCmd = &cobra.Command{
128128

129129
fmt.Printf("serving on %s\n", daemonServerAddr)
130130
logger.Infof("serving on %s", daemonServerAddr)
131-
api.Serve(ctx, daemonServerAddr, db, bot, logger, makeOptions())
131+
api.Serve(ctx, disabledMapConfig, daemonServerAddr, db, bot, logger, makeOptions())
132132
wg.Wait()
133133
},
134134
}

cmd/algorand-indexer/main.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
log "github.com/sirupsen/logrus"
1313
"github.com/spf13/viper"
1414

15+
"github.com/algorand/indexer/api"
1516
bg "github.com/algorand/indexer/cmd/block-generator/core"
1617
iv "github.com/algorand/indexer/cmd/import-validator/core"
1718
v "github.com/algorand/indexer/cmd/validator/core"
@@ -23,6 +24,8 @@ import (
2324
"github.com/algorand/indexer/version"
2425
)
2526

27+
var disabledMapConfig *api.DisabledMapConfig
28+
2629
func maybeFail(err error, errfmt string, params ...interface{}) {
2730
if err == nil {
2831
return
@@ -137,6 +140,7 @@ func init() {
137140
rootCmd.AddCommand(importCmd)
138141
importCmd.Hidden = true
139142
rootCmd.AddCommand(daemonCmd)
143+
rootCmd.AddCommand(apiConfigCmd)
140144

141145
// Not applied globally to avoid adding to utility commands.
142146
addFlags := func(cmd *cobra.Command) {
@@ -203,6 +207,11 @@ func configureLogger() error {
203207
}
204208

205209
func main() {
210+
211+
// TODO enable this when command line options allows for disabling/enabling overrides
212+
//disabledMapConfig = api.GetDefaultDisabledMapConfigForPostgres()
213+
disabledMapConfig = api.MakeDisabledMapConfig()
214+
206215
if err := rootCmd.Execute(); err != nil {
207216
logger.WithError(err).Error("an error occurred running indexer")
208217
os.Exit(1)

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ require (
2727
github.com/vektra/mockery v1.1.2 // indirect
2828
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
2929
golang.org/x/tools v0.1.9 // indirect
30+
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
3031
)

0 commit comments

Comments
 (0)