diff --git a/cmd/main.go b/cmd/main.go index 0a295f8..6115e88 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -68,9 +68,13 @@ func main() { var disabledReconcilers utils.FlagList var debug bool var maxmindUrl string + var maxmindAccountId string + var maxmindToken string flag.BoolVar(&debug, "debug", false, "Debug mode for the logger") flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + flag.StringVar(&maxmindAccountId, "maxmind-accountid", "", "The account id of the maxmind geodatabase.") + flag.StringVar(&maxmindToken, "maxmind-token", "", "The access token of the maxmind geodatabase.") flag.StringVar(&maxmindUrl, "maxmind-url", "https://geoip.maxmind.com/geoip/v2.1/city/", "The endpoint of the maxmind for the ip lookup to work.") flag.Var(&disabledReconcilers, "disabled-reconcilers", "Comma seperated values of the reconciliers, Tenant,TenantResourceQuota,SubNamespace...") flag.BoolVar(&enableLeaderElection, "leader-elect", false, @@ -137,7 +141,7 @@ func main() { } // Try to read the maxmind accountid, and token from the file. - maxmind, err := labeller.NewMaxMindFromSecret() + maxmind, err := labeller.NewMaxMindFromSecret(maxmindUrl, maxmindAccountId, maxmindToken) // If the error is not nil then we cannot get the maxmind config and we should not start node labeller reconcilier. disableNodeLabeller := err != nil diff --git a/internal/labeller/maxmind.go b/internal/labeller/maxmind.go index b006748..1fc91d3 100644 --- a/internal/labeller/maxmind.go +++ b/internal/labeller/maxmind.go @@ -1,9 +1,11 @@ package labeller import ( + "encoding/base64" "encoding/json" "errors" "net/http" + "os" "github.com/savaki/geoip2" ) @@ -19,9 +21,71 @@ type maxMind struct { key string } -// Read the content from the secret directory -func NewMaxMindFromSecret() (MaxMind, error) { - return nil, errors.New("not yet implemented") +// Read the content from the secret directory. URL is given as a non empty string. Others can be. +// 1. First try to create the maxmind struct from command line arguments. +// 2. If they are not specified, look for the environment variables. +// 3. If they are also not specified, check the secrets mounted. +func NewMaxMindFromSecret(url, accountId, key string) (MaxMind, error) { + // Try to build from command line arguments + if url != "" && accountId != "" && key != "" { + return maxMind{ + url: url, + accountId: accountId, + key: key, + }, nil + } + + // Get them from environment variables. + accountId, key = os.Getenv("MAXMIND_ACCOUNTID"), os.Getenv("MAXMIND_KEY") + if url != "" && accountId != "" && key != "" { + return maxMind{ + url: url, + accountId: accountId, + key: key, + }, nil + } + + // Get them from secrets mounted by kubernetes. + accountIdPath := "/var/run/secrets/edge-net.io/maxmind-secret/maxmind_accountid" + keyPath := "/var/run/secrets/edge-net.io/maxmind-secret/maxmind_token" + + // Last resort, return error if there is one. + accountIdBytes, err := os.ReadFile(accountId) + if err != nil { + return nil, err + } + + // Last resort, return error if there is one. + keyBytes, err := os.ReadFile(keyPath) + if err != nil { + return nil, err + } + + accountIdBytes, err = base64.StdEncoding.DecodeString(string(accountIdBytes)) + + if err != nil { + return nil, err + } + + keyBytes, err = base64.StdEncoding.DecodeString(string(keyBytes)) + + if err != nil { + return nil, err + } + + accountId = string(accountIdBytes) + key = string(keyBytes) + + // Try to build from command line arguments + if url != "" && accountId != "" && key != "" { + return maxMind{ + url: url, + accountId: accountId, + key: key, + }, nil + } + + return nil, errors.New("cannot read the maxmind secrets") } // This is for performing a lookup on the IP Address