diff --git a/.gitignore b/.gitignore index 888ebbc..d2530a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ -deployments/test +deployments/cluster.yaml +deployments/secret.yaml build/ diff --git a/Tiltfile b/Tiltfile index 720c391..a144ec9 100644 --- a/Tiltfile +++ b/Tiltfile @@ -20,15 +20,28 @@ def deploy_bmo_crd(): cmd = "curl -sSL {} | kubectl apply -f -".format(m3_uri) local(cmd, quiet=False) +def deploy_metal_crd(): + version = "9a29dae0cfa4575cc94b3c9d9643e441cea7ef9b" + bmcSecret_uri = "https://raw.githubusercontent.com/ironcore-dev/metal-operator/{}/config/crd/bases/metal.ironcore.dev_bmcsecrets.yaml".format(version) + cmd_bmcSecret = "curl -sSL {} | kubectl apply -f -".format(bmcSecret_uri) + bmc_uri = "https://raw.githubusercontent.com/ironcore-dev/metal-operator/{}/config/crd/bases/metal.ironcore.dev_bmcs.yaml".format(version) + cmd_bmc = "curl -sSL {} | kubectl apply -f -".format(bmc_uri) + server_uri = "https://raw.githubusercontent.com/ironcore-dev/metal-operator/{}/config/crd/bases/metal.ironcore.dev_servers.yaml".format(version) + cmd = "curl -sSL {} | kubectl apply -f -".format(server_uri) + local(cmd_bmcSecret, quiet=False) + local(cmd_bmc, quiet=False) + local(cmd, quiet=False) + docker_build('argora-dev', '.', build_args={"BININFO_BUILD_DATE": config.parse()['BININFO_BUILD_DATE'], "BININFO_VERSION": config.parse()['BININFO_VERSION'], "BININFO_COMMIT_HASH": config.parse()['BININFO_COMMIT_HASH']}) deploy_cert_manager() #deploy_capi_crd() deploy_bmo_crd() +deploy_metal_crd() k8s_yaml('deployments/cluster-api-components.yaml') k8s_yaml('config/rbac/role.yaml') k8s_yaml('deployments/argora.yaml') -k8s_yaml('deployments/test/cluster.yaml') +k8s_yaml('deployments/cluster.yaml') k8s_yaml('deployments/secret.yaml') diff --git a/cmd/main.go b/cmd/main.go index cb64a22..b933625 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,10 +1,5 @@ -/* - * Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit. - * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. - * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. - * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. - * Vestibulum commodo. Ut rhoncus gravida arcu. - */ +// Copyright 2024 SAP SE +// SPDX-License-Identifier: Apache-2.0 package main diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 1691b2c..b7dea06 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -28,6 +28,20 @@ rules: - patch - update - watch +- apiGroups: + - metal.ironcore.dev + resources: + - bmcs + - bmcsecrets + - servers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - metal3.io resources: diff --git a/deployments/argora.yaml b/deployments/argora.yaml index bf3bdd1..ecb11fe 100644 --- a/deployments/argora.yaml +++ b/deployments/argora.yaml @@ -39,6 +39,9 @@ spec: containers: - name: argora image: argora-dev:latest + args: + - --controllers="metal3Controller" + # - --controllers="ironCoreServerController" envFrom: - secretRef: - name: argora \ No newline at end of file + name: argora diff --git a/go.mod b/go.mod index bc3f964..a35176b 100644 --- a/go.mod +++ b/go.mod @@ -1,38 +1,41 @@ module github.com/sapcc/argora -go 1.23 +go 1.23.0 require ( github.com/dspinhirne/netaddr-go/v2 v2.0.0 github.com/metal3-io/baremetal-operator/apis v0.6.1 github.com/sapcc/go-api-declarations v1.13.2 github.com/sapcc/go-netbox-go v0.0.0-20241106125215-07e3722fbd4d - github.com/spf13/cobra v1.8.0 - k8s.io/api v0.30.1 + github.com/spf13/cobra v1.8.1 + k8s.io/api v0.31.4 sigs.k8s.io/cluster-api v1.7.2 - sigs.k8s.io/controller-runtime v0.18.4 + sigs.k8s.io/controller-runtime v0.19.4 ) require ( + github.com/ironcore-dev/controller-utils v0.9.7 + github.com/ironcore-dev/metal-operator v0.0.0-20250110122403-9a29dae0cfa4 gopkg.in/yaml.v3 v3.0.1 - k8s.io/apimachinery v0.30.1 + k8s.io/apimachinery v0.31.4 ) require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/errors v0.20.3 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/strfmt v0.21.7 // indirect - github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/swag v0.22.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -45,7 +48,6 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/metal3-io/baremetal-operator/pkg/hardwareutils v0.5.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -53,31 +55,31 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/x448/float16 v0.8.4 // indirect go.mongodb.org/mongo-driver v1.11.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/net v0.33.0 // indirect - golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/term v0.27.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/term v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.36.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/apiextensions-apiserver v0.30.1 // indirect - k8s.io/client-go v0.30.1 // indirect - k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/apiextensions-apiserver v0.31.4 // indirect + k8s.io/client-go v0.31.4 // indirect + k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 61234bf..cde0392 100644 --- a/go.sum +++ b/go.sum @@ -2,9 +2,9 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -20,8 +20,10 @@ github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0 github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= @@ -32,15 +34,16 @@ github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2Kv github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k= github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -53,14 +56,18 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/ironcore-dev/controller-utils v0.9.7 h1:ywNcB6lDeOe6UWxJaptbdgb9qb6cDx4+jxBcIGkMQD8= +github.com/ironcore-dev/controller-utils v0.9.7/go.mod h1:7X6JUmq75o4KFe05zUa9rEXnS39dSrlXqUnt9Wuiug0= +github.com/ironcore-dev/metal-operator v0.0.0-20250110122403-9a29dae0cfa4 h1:h6OMgXUwEiwHKKNn/pwauyjWamB1s+GFPxsgDksTgIE= +github.com/ironcore-dev/metal-operator v0.0.0-20250110122403-9a29dae0cfa4/go.mod h1:bYsdh4COQ5K0K1Z6Ssejm9t5cGbIIpMcu3d7bKTa+X4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -78,8 +85,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/metal3-io/baremetal-operator/apis v0.6.1 h1:CL5paLPWn0VEAcdtGaKKNMCR9AVYXjSuiO83vwlOHRI= github.com/metal3-io/baremetal-operator/apis v0.6.1/go.mod h1:dogSrgg9iPAznQonugPKRI41zOlQAaPb80U5WJ06E38= github.com/metal3-io/baremetal-operator/pkg/hardwareutils v0.5.1 h1:X0+MWsJ+Gj/TAkmhGybvesvxk6zQKu3NQXzvC6l0iJs= @@ -97,24 +102,25 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= -github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= -github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= -github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= +github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= +github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sapcc/go-api-declarations v1.13.2 h1:dPYYsjwKGObSAm6+K+dYCiLQWunYuWkywlZnuXfjsmk= github.com/sapcc/go-api-declarations v1.13.2/go.mod h1:83R3hTANhuRXt/pXDby37IJetw8l7DG41s33Tp9NXxI= @@ -122,8 +128,8 @@ github.com/sapcc/go-netbox-go v0.0.0-20241106125215-07e3722fbd4d h1:XE4jf3qitQ8b github.com/sapcc/go-netbox-go v0.0.0-20241106125215-07e3722fbd4d/go.mod h1:svNHmBLJaYKDerDkp+YC4gtRln93xELpwAnsDfNokUY= github.com/seborama/govcr v4.5.0+incompatible h1:XvdHtXi0d4cUAn+0aWolvwfS3nmhNC8Z+yMQwn/M64I= github.com/seborama/govcr v4.5.0+incompatible/go.mod h1:EgcISudCCYDLzbiAImJ8i7kk4+wTA44Kp+j4S0LhASI= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= 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,10 +140,12 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= @@ -156,20 +164,19 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -180,13 +187,12 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.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.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -198,23 +204,23 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= +google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -224,24 +230,24 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY= -k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM= -k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= -k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= -k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= -k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= -k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q= -k8s.io/client-go v0.30.1/go.mod h1:wrAqLNs2trwiCH/wxxmT/x3hKVH9PuV0GGW0oDoHVqc= -k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= -k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/api v0.31.4 h1:I2QNzitPVsPeLQvexMEsj945QumYraqv9m74isPDKhM= +k8s.io/api v0.31.4/go.mod h1:d+7vgXLvmcdT1BCo79VEgJxHHryww3V5np2OYTr6jdw= +k8s.io/apiextensions-apiserver v0.31.4 h1:FxbqzSvy92Ca9DIs5jqot883G0Ln/PGXfm/07t39LS0= +k8s.io/apiextensions-apiserver v0.31.4/go.mod h1:hIW9YU8UsqZqIWGG99/gsdIU0Ar45Qd3A12QOe/rvpg= +k8s.io/apimachinery v0.31.4 h1:8xjE2C4CzhYVm9DGf60yohpNUh5AEBnPxCryPBECmlM= +k8s.io/apimachinery v0.31.4/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/client-go v0.31.4 h1:t4QEXt4jgHIkKKlx06+W3+1JOwAFU/2OPiOo7H92eRQ= +k8s.io/client-go v0.31.4/go.mod h1:kvuMro4sFYIa8sulL5Gi5GFqUPvfH2O/dXuKstbaaeg= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= -k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/cluster-api v1.7.2 h1:bRE8zoao7ajuLC0HijqfZVcubKQCPlZ04HMgcA53FGE= sigs.k8s.io/cluster-api v1.7.2/go.mod h1:V9ZhKLvQtsDODwjXOKgbitjyCmC71yMBwDcMyNNIov0= -sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw= -sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= +sigs.k8s.io/controller-runtime v0.19.4 h1:SUmheabttt0nx8uJtoII4oIP27BVVvAKFvdvGFwV/Qo= +sigs.k8s.io/controller-runtime v0.19.4/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 0db3ba9..9170c91 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -1,16 +1,14 @@ -/* - * Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit. - * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. - * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. - * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. - * Vestibulum commodo. Ut rhoncus gravida arcu. - */ +// Copyright 2024 SAP SE +// SPDX-License-Identifier: Apache-2.0 package cmd import ( + "fmt" + metalv1alpha1 "github.com/ironcore-dev/metal-operator/api/v1alpha1" "os" + "github.com/ironcore-dev/controller-utils/cmdutils/switches" bmov1alpha1 "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1" "github.com/sapcc/go-api-declarations/bininfo" "github.com/spf13/cobra" @@ -31,11 +29,20 @@ var RootCmd = &cobra.Command{ } var ( - setupLog = ctrl.Log.WithName("setup") - netboxURL string - netboxToken string - bmcUser string - bmcPassword string + setupLog = ctrl.Log.WithName("setup") + netboxURL string + netboxToken string + bmcUser string + bmcPassword string + controllers switches.Switches + ironCoreRoles string + ironCoreRegion string +) + +const ( + // controllers + metal3ClusterController = "metal3Controller" + ironCoreServerController = "ironCoreServerController" ) func init() { @@ -43,10 +50,25 @@ func init() { RootCmd.PersistentFlags().StringVar(&netboxToken, "netbox-token", os.Getenv("NETBOX_TOKEN"), "API token for netbox") RootCmd.PersistentFlags().StringVar(&bmcUser, "bmc-user", os.Getenv("BMC_USER"), "BMC user") RootCmd.PersistentFlags().StringVar(&bmcPassword, "bmc-password", os.Getenv("BMC_PASS"), "BMC password") + RootCmd.PersistentFlags().StringVar(&ironCoreRoles, "ironcore-types", os.Getenv("IRONCORE_TYPES"), "Ironcore Cluster types") + RootCmd.PersistentFlags().StringVar(&ironCoreRegion, "ironcore-region", os.Getenv("IRONCORE_REGION"), "Ironcore Regions") + + controllers = *switches.New( + metal3ClusterController, + ironCoreServerController, + ) + + RootCmd.PersistentFlags().Var(&controllers, "controllers", + fmt.Sprintf("Controllers to enable. All controllers: %v. Disabled-by-default controllers: %v", + controllers.All(), + controllers.DisabledByDefault(), + ), + ) } func RunRootCmd(cmd *cobra.Command, args []string) error { ctrl.SetLogger(zap.New()) + mgr, err := ctrl.NewManager(config.GetConfigOrDie(), ctrl.Options{}) if err != nil { setupLog.Error(err, "unable to create manager") @@ -62,22 +84,43 @@ func RunRootCmd(cmd *cobra.Command, args []string) error { setupLog.Error(err, "unable to register baremetal operator scheme") return err } + err = metalv1alpha1.AddToScheme(mgr.GetScheme()) + if err != nil { + setupLog.Error(err, "unable to register metal operator scheme") + return err + } nbc, err := netbox.NewNetboxClient(netboxURL, netboxToken) if err != nil { setupLog.Error(err, "unable to create netbox client") return err } - clusterController := &controller.ClusterController{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Nb: nbc, - BMCUser: bmcUser, - BMCPassword: bmcPassword, + + if controllers.Enabled(metal3ClusterController) { + if err = (&controller.Metal3ClusterController{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Nb: nbc, + BMCUser: bmcUser, + BMCPassword: bmcPassword, + }).AddToManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Metal3Cluster") + os.Exit(1) + } } - err = clusterController.AddToManager(mgr) - if err != nil { - setupLog.Error(err, "unable to add cluster controller to manager") - return err + + if controllers.Enabled(ironCoreServerController) { + if err = (&controller.IronCoreServerController{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Nb: nbc, + BMCUser: bmcUser, + BMCPassword: bmcPassword, + IronCoreRoles: ironCoreRoles, + IronCoreRegion: ironCoreRegion, + }).AddToManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "IroncoreServer") + os.Exit(1) + } } setupLog.Info("starting manager") diff --git a/internal/controller/ironcore.go b/internal/controller/ironcore.go new file mode 100644 index 0000000..2b1fb81 --- /dev/null +++ b/internal/controller/ironcore.go @@ -0,0 +1,281 @@ +// Copyright 2024 SAP SE +// SPDX-License-Identifier: Apache-2.0 + +package controller + +import ( + "context" + "fmt" + metalv1alpha1 "github.com/ironcore-dev/metal-operator/api/v1alpha1" + "github.com/sapcc/argora/internal/netbox" + "github.com/sapcc/go-netbox-go/models" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "net" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/manager" + "strings" + "time" +) + +const ( + bmcProtocolRedfish = "Redfish" + bmcPort = 443 + defaultNamespace = "default" +) + +type IronCoreServerController struct { + client.Client + Nb *netbox.Client + Scheme *runtime.Scheme + BMCUser string + BMCPassword string + IronCoreRegion string + IronCoreRoles string +} + +// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=servers,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcs,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcsecrets,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete + +// Reconcile looks up IronCore clusters in Netbox and creates Servers for it +func (c *IronCoreServerController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + logger := log.FromContext(ctx) + logger.Info("reconciling IronCore cluster") + + var clusterRoles []string + if c.IronCoreRoles != "" { + clusterRoles = strings.Split(c.IronCoreRoles, ",") + } + + for _, clusterRole := range clusterRoles { + devices, cluster, err := c.Nb.LookupCluster(clusterRole, c.IronCoreRegion, "") + if err != nil { + logger.Error(err, "unable to lookup cluster in netbox") + return ctrl.Result{}, err + } + for _, device := range devices { + err = c.ReconcileDevice(ctx, cluster, &device) + if err != nil { + logger.Error(err, "unable to reconcile device") + return ctrl.Result{}, err + } + } + } + + return ctrl.Result{}, nil +} + +type PeriodicReconciler struct { + controller *IronCoreServerController +} + +func (r *PeriodicReconciler) Start(ctx context.Context) error { + // Trigger the Reconcile method immediately + _, err := r.controller.Reconcile(ctx, ctrl.Request{}) + if err != nil { + return err + } + + ticker := time.NewTicker(60 * time.Second) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + _, err := r.controller.Reconcile(ctx, ctrl.Request{}) + if err != nil { + return err + } + case <-ctx.Done(): + return nil + } + } +} + +func (c *IronCoreServerController) AddToManager(mgr manager.Manager) error { + // Add the custom Runnable to the manager + return mgr.Add(&PeriodicReconciler{controller: c}) +} + +func (c *IronCoreServerController) ReconcileDevice(ctx context.Context, cluster string, device *models.Device) error { + logger := log.FromContext(ctx) + logger.Info("reconciling device", "node", device.Name) + // check if device is active + if device.Status.Value != "active" { + logger.Info("device is not active") + return nil + } + // check if the host already exists + server := &metalv1alpha1.Server{} + err := c.Client.Get(ctx, client.ObjectKey{Name: device.Name, Namespace: defaultNamespace}, server) + if err == nil { + logger.Info("host already exists", "host", server.Name) + return nil + } + // ugly hack to get the role this is not easy to get to in netbox + nameParts := strings.Split(device.Name, "-") + if len(nameParts) != 2 { + err = fmt.Errorf("invalid device name: %s", device.Name) + logger.Error(err, "error splitting name") + return err + } + // get the region + region, err := c.Nb.GetRegionForDevice(device) + if err != nil { + logger.Error(err, "unable to lookup region for device") + return err + } + + oobIP, err := c.getOobIP(device) + if err != nil { + logger.Error(err, "unable to get OOB IP") + return err + } + + commonLabels := map[string]string{ + "topology.kubernetes.io/region": region, + "topology.kubernetes.io/zone": device.Site.Slug, + "kubernetes.metal.cloud.sap/cluster": cluster, + "kubernetes.metal.cloud.sap/name": device.Name, + "kubernetes.metal.cloud.sap/bb": nameParts[1], + } + + bmcSecret, err := c.createBmcSecret(ctx, device, commonLabels) + if err != nil { + logger.Error(err, "unable to create bmc secret") + return err + } + + bmc, err := c.createBmc(ctx, device, oobIP, bmcSecret, commonLabels) + if err != nil { + logger.Error(err, "unable to create BMC") + return err + } + + metalServerName := fmt.Sprintf("%s-system-0", device.Name) + metalServer := &metalv1alpha1.Server{ + ObjectMeta: ctrl.ObjectMeta{ + Name: metalServerName, + Labels: commonLabels, + }, + Spec: metalv1alpha1.ServerSpec{ + BMCRef: &corev1.LocalObjectReference{ + Name: bmc.Name, + }, + }, + } + err = c.Client.Create(ctx, metalServer) + if errors.IsAlreadyExists(err) { + logger.Info("server already exists", "Server", bmcSecret.Name) + return nil + } + if err != nil { + logger.Error(err, "unable to create Server") + return err + } + + if err := controllerutil.SetControllerReference(server, bmcSecret, c.Scheme); err != nil { + logger.Error(err, "unable to set owner reference for bmc secret") + return err + } + err = c.Client.Patch(ctx, bmcSecret, client.MergeFrom(bmcSecret)) + if err != nil { + logger.Error(err, "unable to patch bmcSecret") + return err + } + + if err := controllerutil.SetControllerReference(server, bmc, c.Scheme); err != nil { + logger.Error(err, "unable to set owner reference for bmc") + return err + } + err = c.Client.Patch(ctx, bmc, client.MergeFrom(bmc)) + if err != nil { + logger.Error(err, "unable to patch BMC") + return err + } + + return nil +} + +func (c *IronCoreServerController) createBmcSecret( + ctx context.Context, + device *models.Device, + labels map[string]string, +) (*metalv1alpha1.BMCSecret, error) { + user := c.BMCUser + password := c.BMCPassword + if user == "" || password == "" { + return nil, fmt.Errorf("bmc user or password not set") + } + bmcSecret := &metalv1alpha1.BMCSecret{ + ObjectMeta: ctrl.ObjectMeta{ + Name: device.Name, + Labels: labels, + }, + StringData: map[string]string{ + "username": user, + "password": password, + }, + } + err := c.Client.Create(ctx, bmcSecret) + if errors.IsAlreadyExists(err) { + log.FromContext(ctx).Info("bmc secret already exists", "bmcSecret", bmcSecret.Name) + return bmcSecret, nil + } + if err != nil { + return nil, fmt.Errorf("unable to create bmc secret: %w", err) + } + return bmcSecret, nil +} + +func (c *IronCoreServerController) createBmc( + ctx context.Context, + device *models.Device, + oobIP string, + bmcSecret *metalv1alpha1.BMCSecret, + labels map[string]string, +) (*metalv1alpha1.BMC, error) { + bmc := &metalv1alpha1.BMC{ + ObjectMeta: ctrl.ObjectMeta{ + Name: device.Name, + Labels: labels, + }, + Spec: metalv1alpha1.BMCSpec{ + Endpoint: &metalv1alpha1.InlineEndpoint{ + IP: metalv1alpha1.MustParseIP(oobIP), + }, + Protocol: metalv1alpha1.Protocol{ + Name: bmcProtocolRedfish, + Port: bmcPort, + }, + BMCSecretRef: corev1.LocalObjectReference{ + Name: bmcSecret.Name, + }, + }, + } + if err := c.Client.Create(ctx, bmc); err != nil { + if errors.IsAlreadyExists(err) { + log.FromContext(ctx).Info("BMC already exists", "BMC", bmc.Name) + return bmc, nil + } + return nil, fmt.Errorf("unable to create BMC: %w", err) + } + return bmc, nil +} + +func (c *IronCoreServerController) getOobIP( + device *models.Device, +) (string, error) { + oobIP := device.OOBIp.Address + ip, _, err := net.ParseCIDR(oobIP) + if err != nil { + return "", fmt.Errorf("uncable to parse Device OOB IP: %w", err) + } + return ip.String(), nil +} diff --git a/internal/controller/cluster.go b/internal/controller/m3cluster.go similarity index 87% rename from internal/controller/cluster.go rename to internal/controller/m3cluster.go index cd71e00..b21f445 100644 --- a/internal/controller/cluster.go +++ b/internal/controller/m3cluster.go @@ -1,10 +1,5 @@ -/* - * Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit. - * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. - * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. - * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. - * Vestibulum commodo. Ut rhoncus gravida arcu. - */ +// Copyright 2024 SAP SE +// SPDX-License-Identifier: Apache-2.0 package controller @@ -36,9 +31,9 @@ import ( const ClusterRoleLabel = "discovery.inf.sap.cloud/clusterRole" -type ClusterController struct { +type Metal3ClusterController struct { client.Client - Nb *netbox.NetboxClient + Nb *netbox.Client Scheme *runtime.Scheme BMCUser string BMCPassword string @@ -49,9 +44,9 @@ type ClusterController struct { // +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete // Reconcile looks up a cluster in netbox and creates baremetal hosts for it -func (c *ClusterController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { +func (c *Metal3ClusterController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { logger := log.FromContext(ctx) - logger.Info("reconciling cluster") + logger.Info("reconciling ironcore cluster") cluster := &clusterv1.Cluster{} err := c.Client.Get(ctx, req.NamespacedName, cluster) if client.IgnoreNotFound(err) != nil { @@ -59,7 +54,7 @@ func (c *ClusterController) Reconcile(ctx context.Context, req ctrl.Request) (ct return ctrl.Result{}, err } role := cluster.Labels[ClusterRoleLabel] - devices, err := c.Nb.LookupCluster(role, cluster.Name) + devices, _, err := c.Nb.LookupCluster(role, "", cluster.Name) if err != nil { logger.Error(err, "unable to lookup cluster in netbox") return ctrl.Result{}, err @@ -71,12 +66,13 @@ func (c *ClusterController) Reconcile(ctx context.Context, req ctrl.Request) (ct return ctrl.Result{}, err } } - return ctrl.Result{RequeueAfter: 300 * time.Second}, nil - // return ctrl.Result{}, nil + return ctrl.Result{ + RequeueAfter: 300 * time.Second, + }, nil } // CreateNetworkDataForDevice uses the device to get to the netbox interfaces and creates a secret containing the network data for this device -func (c *ClusterController) CreateNetworkDataForDevice(ctx context.Context, host *bmov1alpha1.BareMetalHost, cluster clusterv1.Cluster, device *models.Device, role string) error { +func (c *Metal3ClusterController) CreateNetworkDataForDevice(ctx context.Context, host *bmov1alpha1.BareMetalHost, cluster clusterv1.Cluster, device *models.Device, role string) error { vlan, ipStr, err := c.Nb.LookupVLANForDevice(device, role) if err != nil { log.FromContext(ctx).Error(err, "unable to lookup vlan for device") @@ -134,7 +130,7 @@ func (c *ClusterController) CreateNetworkDataForDevice(ctx context.Context, host return c.Create(ctx, result) } -func (c *ClusterController) ReconcileDevice(ctx context.Context, cluster clusterv1.Cluster, device *models.Device) error { +func (c *Metal3ClusterController) ReconcileDevice(ctx context.Context, cluster clusterv1.Cluster, device *models.Device) error { logger := log.FromContext(ctx) logger.Info("reconciling device", "node", device.Name) // check if device is active @@ -241,8 +237,8 @@ func (c *ClusterController) ReconcileDevice(ctx context.Context, cluster cluster return nil } -func (c *ClusterController) AddToManager(mgr manager.Manager) error { - return ctrl.NewControllerManagedBy(mgr).For(&clusterv1.Cluster{}).Complete(c) +func (c *Metal3ClusterController) AddToManager(mgr manager.Manager) error { + return ctrl.NewControllerManagedBy(mgr).Named("metal3Controller").For(&clusterv1.Cluster{}).Complete(c) } func createRedFishURL(device *models.Device) (string, error) { @@ -258,7 +254,7 @@ func createRedFishURL(device *models.Device) (string, error) { } } -func (c *ClusterController) createBmcSecret(cluster clusterv1.Cluster, device *models.Device) (*corev1.Secret, error) { +func (c *Metal3ClusterController) createBmcSecret(cluster clusterv1.Cluster, device *models.Device) (*corev1.Secret, error) { user := c.BMCUser password := c.BMCPassword if user == "" || password == "" { diff --git a/internal/netbox/client.go b/internal/netbox/client.go index 1f8c28a..1b98e4b 100644 --- a/internal/netbox/client.go +++ b/internal/netbox/client.go @@ -1,10 +1,5 @@ -/* - * Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit. - * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. - * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. - * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. - * Vestibulum commodo. Ut rhoncus gravida arcu. - */ +// Copyright 2024 SAP SE +// SPDX-License-Identifier: Apache-2.0 package netbox @@ -18,13 +13,13 @@ import ( "github.com/sapcc/go-netbox-go/virtualization" ) -type NetboxClient struct { +type Client struct { virt *virtualization.Client dcim *dcim.Client ipam *ipam.Client } -func NewNetboxClient(url, token string) (*NetboxClient, error) { +func NewNetboxClient(url, token string) (*Client, error) { virt, err := virtualization.New(url, token, false) if err != nil { return nil, err @@ -37,14 +32,14 @@ func NewNetboxClient(url, token string) (*NetboxClient, error) { if err != nil { return nil, err } - return &NetboxClient{ + return &Client{ virt: virt, dcim: dcim, ipam: ipam, }, nil } -func (n *NetboxClient) GetRegionForDevice(device *models.Device) (string, error) { +func (n *Client) GetRegionForDevice(device *models.Device) (string, error) { site, err := n.dcim.GetSite(device.Site.Id) if err != nil { return "", err @@ -56,7 +51,7 @@ func (n *NetboxClient) GetRegionForDevice(device *models.Device) (string, error) return region.Slug, nil } -func (n *NetboxClient) LookupVLANForDevice(device *models.Device, role string) (vlanid int, address string, err error) { +func (n *Client) LookupVLANForDevice(device *models.Device, role string) (vlanid int, address string, err error) { lir := models.ListInterfacesRequest{ DeviceId: device.Id, } @@ -103,8 +98,8 @@ func (n *NetboxClient) LookupVLANForDevice(device *models.Device, role string) ( return 0, res.Results[0].Address, nil } -// LookupMacForIp get the first interface of LAG1 and return the mac address -func (n *NetboxClient) LookupMacForIP(ipStr string) (string, error) { +// LookupMacForIP get the first interface of LAG1 and return the mac address +func (n *Client) LookupMacForIP(ipStr string) (string, error) { lipr := models.ListIpAddressesRequest{ Address: ipStr, } @@ -152,20 +147,25 @@ func (n *NetboxClient) LookupMacForIP(ipStr string) (string, error) { return macs[names[0]], nil } -func (n *NetboxClient) LookupCluster(role, name string) ([]models.Device, error) { +func (n *Client) LookupCluster(role, region, name string) ([]models.Device, string, error) { lcp := models.ListClusterRequest{ Type: role, } - lcp.Name = name + if region != "" { + lcp.Region = region + } + if name != "" { + lcp.Name = name + } resp, err := n.virt.ListClusters(lcp) if err != nil { - return nil, err + return nil, "", err } if resp.Count == 0 { - return nil, nil + return nil, "", nil } if resp.Count > 1 { - return nil, fmt.Errorf("too many clusters found: %d", resp.Count) + return nil, "", fmt.Errorf("too many clusters found: %d", resp.Count) } cluster := resp.Results[0] ldp := models.ListDevicesRequest{ @@ -173,7 +173,7 @@ func (n *NetboxClient) LookupCluster(role, name string) ([]models.Device, error) } dresp, err := n.dcim.ListDevices(ldp) if err != nil { - return nil, err + return nil, "", err } - return dresp.Results, nil + return dresp.Results, cluster.Name, nil } diff --git a/internal/networkdata/types.go b/internal/networkdata/types.go index 596196c..19fc49c 100644 --- a/internal/networkdata/types.go +++ b/internal/networkdata/types.go @@ -1,10 +1,5 @@ -/* - * Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit. - * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. - * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. - * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. - * Vestibulum commodo. Ut rhoncus gravida arcu. - */ +// Copyright 2024 SAP SE +// SPDX-License-Identifier: Apache-2.0 package networkdata