diff --git a/cmd/main.go b/cmd/main.go index 91f2e8b..ef3b0d3 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -17,12 +17,14 @@ limitations under the License. package main import ( + "context" "crypto/tls" "flag" "os" // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. + "google.golang.org/appengine/log" _ "k8s.io/client-go/plugin/pkg/client/auth" "k8s.io/apimachinery/pkg/runtime" @@ -39,6 +41,7 @@ import ( multitenancyv1 "github.com/edgenet-project/edgenet-software/api/multitenancy/v1" labellerscontroller "github.com/edgenet-project/edgenet-software/internal/controller/labellers" multitenancycontroller "github.com/edgenet-project/edgenet-software/internal/controller/multitenancy" + "github.com/edgenet-project/edgenet-software/internal/labeller" "github.com/edgenet-project/edgenet-software/internal/utils" //+kubebuilder:scaffold:imports ) @@ -64,9 +67,11 @@ func main() { var enableHTTP2 bool var disabledReconcilers utils.FlagList var debug bool + var maxmindUrl 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(&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, "Enable leader election for controller manager. "+ @@ -131,6 +136,15 @@ func main() { os.Exit(1) } + // Try to read the maxmind accountid, and token from the file. + maxmind, err := labeller.NewMaxMindFromSecret() + // If the error is not nil then we cannot get the maxmind config and we should not start node labeller reconcilier. + disableNodeLabeller := err != nil + + if err != nil { + log.Warningf(context.TODO(), "Cannot retrieve the MaxMind Account Token, running without the NodeLabeller") + } + // Setup reconcilers, we might want to add the list of reconcilers. This part is auto generated. // If you want to add the functionality to disable reconcilers, put it inside an if. // WARNING: This part is semi-auto-generated! By default you cannot disable reconcilers since they are @@ -153,10 +167,14 @@ func main() { os.Exit(1) } } - if !disabledReconcilers.Contains("NodeLabeller") { + // For NodeLabeller to be activated, it should not be in the disabled reconciler list and the maxmind from secret + // should not return an error + if !disabledReconcilers.Contains("NodeLabeller") && !disableNodeLabeller { if err = (&labellerscontroller.NodeLabellerReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), + // Add the maxming configuration to the reconcilier. + MaxMind: maxmind, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "NodeLabeller") os.Exit(1) diff --git a/go.mod b/go.mod index 9f08fb6..627eb74 100644 --- a/go.mod +++ b/go.mod @@ -47,14 +47,15 @@ require ( github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.46.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect + github.com/savaki/geoip2 v0.0.0-20150727150920-9968b08fbf39 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/net v0.22.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect diff --git a/go.sum b/go.sum index 857dfcc..6448ab9 100644 --- a/go.sum +++ b/go.sum @@ -96,6 +96,8 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/savaki/geoip2 v0.0.0-20150727150920-9968b08fbf39 h1:uiw3hmPAy2BLiEwsbU2zXJSf+FeGe8UXOM+GH2Qz1eo= +github.com/savaki/geoip2 v0.0.0-20150727150920-9968b08fbf39/go.mod h1:iMZP5PLivDai1MuEAzm+muyV6JfTn0ct+BzV+8ptbJg= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -134,6 +136,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -150,10 +154,14 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= diff --git a/internal/controller/labellers/nodelabeller_controller.go b/internal/controller/labellers/nodelabeller_controller.go index 46d1f32..366ad52 100644 --- a/internal/controller/labellers/nodelabeller_controller.go +++ b/internal/controller/labellers/nodelabeller_controller.go @@ -19,6 +19,7 @@ package labellers import ( "context" + "github.com/edgenet-project/edgenet-software/internal/labeller" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -30,7 +31,8 @@ import ( // NodeLabellerReconciler reconciles a NodeLabeller object type NodeLabellerReconciler struct { client.Client - Scheme *runtime.Scheme + Scheme *runtime.Scheme + MaxMind labeller.MaxMind } //+kubebuilder:rbac:groups=core,resources=node,verbs=get;list;watch;create;update;patch diff --git a/internal/labeller/maxmind.go b/internal/labeller/maxmind.go index cce77ef..a6b530a 100644 --- a/internal/labeller/maxmind.go +++ b/internal/labeller/maxmind.go @@ -1,5 +1,50 @@ package labeller -type LabelLookup interface { - Lookup() +import ( + "encoding/json" + "errors" + "net/http" + + "github.com/savaki/geoip2" +) + +type MaxMind interface { + MaxMindLookup(address string) (*geoip2.Response, error) +} + +type maxMind struct { + MaxMind + url string + accountId string + key string +} + +// Read the content from the secret directory +func NewMaxMindFromSecret() (MaxMind, error) { + return nil, errors.New("not yet implemented") +} + +// This is for +func (mm maxMind) MaxMindLookup(address string) (*geoip2.Response, error) { + req, err := http.NewRequest("GET", mm.url+address, nil) + if err != nil { + return nil, err + } + req.SetBasicAuth(mm.accountId, mm.key) + res, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer res.Body.Close() + if res.StatusCode >= 400 { + v := geoip2.Error{} + err := json.NewDecoder(res.Body).Decode(&v) + if err != nil { + return nil, err + } + return nil, v + } + response := &geoip2.Response{} + err = json.NewDecoder(res.Body).Decode(response) + return response, err }