Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: send kube version in user-agent of aiven API clients #655

Merged
merged 1 commit into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ on:
- v*

jobs:
bump_version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: |
sed -i "s/const operatorVersion = \".*\"/const operatorVersion = \"${GITHUB_REF_NAME#v}\"/" main.go
- uses: Amraneze/[email protected]
with:
repository: ${{ github.repository }}
branch_name: ${{ github.ref_name }}
github_token: ${{ secrets.AIVEN_CI_PAT__VALID_WHILE_ALEKS_IS_EMPLOYED }}
commit_message: "chore(version): bump operator version"
files_to_commit: main.go
build_default_release_manifest:
runs-on: ubuntu-latest
steps:
Expand Down
16 changes: 9 additions & 7 deletions controllers/basic_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ type (
Controller struct {
client.Client

Log logr.Logger
Scheme *runtime.Scheme
Recorder record.EventRecorder
DefaultToken string
AvGenClient avngen.Client
Log logr.Logger
Scheme *runtime.Scheme
Recorder record.EventRecorder
DefaultToken string
AvGenClient avngen.Client
KubeVersion string
OperatorVersion string
}

// Handlers represents Aiven API handlers
Expand Down Expand Up @@ -123,13 +125,13 @@ func (c *Controller) reconcileInstance(ctx context.Context, req ctrl.Request, h
return ctrl.Result{}, errNoTokenProvided
}

avn, err := NewAivenClient(token)
avn, err := NewAivenClient(token, c.KubeVersion, c.OperatorVersion)
if err != nil {
c.Recorder.Event(o, corev1.EventTypeWarning, eventUnableToCreateClient, err.Error())
return ctrl.Result{}, fmt.Errorf("cannot initialize aiven client: %w", err)
}

avnGen, err := NewAivenGeneratedClient(token)
avnGen, err := NewAivenGeneratedClient(token, c.KubeVersion, c.OperatorVersion)
if err != nil {
c.Recorder.Event(o, corev1.EventTypeWarning, eventUnableToCreateClient, err.Error())
return ctrl.Result{}, fmt.Errorf("cannot initialize aiven generated client: %w", err)
Expand Down
16 changes: 7 additions & 9 deletions controllers/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package controllers
import (
"context"
"errors"
"fmt"
"net/http"
"reflect"
"strconv"
Expand Down Expand Up @@ -44,12 +45,9 @@ const (
errConditionCreateOrUpdate errCondition = "CreateOrUpdate"
)

var (
version = "dev"
errTerminationProtectionOn = errors.New("termination protection is on")
)
var errTerminationProtectionOn = errors.New("termination protection is on")

func checkServiceIsRunning(ctx context.Context, avn *aiven.Client, avnGen avngen.Client, project, serviceName string) (bool, error) {
func checkServiceIsRunning(ctx context.Context, _ *aiven.Client, avnGen avngen.Client, project, serviceName string) (bool, error) {
s, err := avnGen.ServiceGet(ctx, project, serviceName)
if err != nil {
// if service is not found, it is not running
Expand Down Expand Up @@ -135,13 +133,13 @@ func isAivenServerError(err error) bool {
}

// NewAivenClient returns Aiven client (aiven/aiven-go-client/v2)
func NewAivenClient(token string) (*aiven.Client, error) {
return aiven.NewTokenClient(token, "k8s-operator/"+version)
func NewAivenClient(token, kubeVersion, operatorVersion string) (*aiven.Client, error) {
return aiven.NewTokenClient(token, fmt.Sprintf("k8s-operator/%s/%s", kubeVersion, operatorVersion))
}

// NewAivenGeneratedClient returns Aiven generated client client (aiven/go-client-codegen)
func NewAivenGeneratedClient(token string) (avngen.Client, error) {
return avngen.NewClient(avngen.TokenOpt(token), avngen.UserAgentOpt("k8s-operator/"+version))
func NewAivenGeneratedClient(token, kubeVersion, operatorVersion string) (avngen.Client, error) {
return avngen.NewClient(avngen.TokenOpt(token), avngen.UserAgentOpt(fmt.Sprintf("k8s-operator/%s/%s", kubeVersion, operatorVersion)))
}

func fromAnyPointer[T any](v *T) T {
Expand Down
56 changes: 29 additions & 27 deletions controllers/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
)

func SetupControllers(mgr ctrl.Manager, defaultToken string) error {
func SetupControllers(mgr ctrl.Manager, defaultToken, kubeVersion, operatorVersion string) error {
if err := (&SecretFinalizerGCController{
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("SecretFinalizerGCController"),
Expand All @@ -16,120 +16,120 @@ func SetupControllers(mgr ctrl.Manager, defaultToken string) error {
}

if err := (&ProjectReconciler{
Controller: newController(mgr, "Project", defaultToken),
Controller: newController(mgr, "Project", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller Project: %w", err)
}

if err := (&PostgreSQLReconciler{
Controller: newController(mgr, "PostgreSQL", defaultToken),
Controller: newController(mgr, "PostgreSQL", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller PostgreSQL: %w", err)
}

if err := (&ConnectionPoolReconciler{
Controller: newController(mgr, "ConnectionPool", defaultToken),
Controller: newController(mgr, "ConnectionPool", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller ConnectionPool: %w", err)
}

if err := (&DatabaseReconciler{
Controller: newController(mgr, "Database", defaultToken),
Controller: newController(mgr, "Database", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller Database: %w", err)
}

if err := (&KafkaReconciler{
Controller: newController(mgr, "Kafka", defaultToken),
Controller: newController(mgr, "Kafka", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller Kafka: %w", err)
}

if err := (&ProjectVPCReconciler{
Controller: newController(mgr, "ProjectVPC", defaultToken),
Controller: newController(mgr, "ProjectVPC", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller ProjectVPC: %w", err)
}

if err := (&KafkaTopicReconciler{
Controller: newController(mgr, "KafkaTopic", defaultToken),
Controller: newController(mgr, "KafkaTopic", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller KafkaTopic: %w", err)
}

if err := (&KafkaACLReconciler{
Controller: newController(mgr, "KafkaACL", defaultToken),
Controller: newController(mgr, "KafkaACL", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller KafkaACL: %w", err)
}

if err := (&KafkaConnectReconciler{
Controller: newController(mgr, "KafkaConnect", defaultToken),
Controller: newController(mgr, "KafkaConnect", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller KafkaConnect: %w", err)
}

if err := (&ServiceUserReconciler{
Controller: newController(mgr, "ServiceUser", defaultToken),
Controller: newController(mgr, "ServiceUser", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller ServiceUser: %w", err)
}

if err := (&KafkaSchemaReconciler{
Controller: newController(mgr, "KafkaSchema", defaultToken),
Controller: newController(mgr, "KafkaSchema", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller KafkaSchema: %w", err)
}

if err := (&ServiceIntegrationReconciler{
Controller: newController(mgr, "ServiceIntegration", defaultToken),
Controller: newController(mgr, "ServiceIntegration", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller ServiceIntegration: %w", err)
}
if err := (&KafkaConnectorReconciler{
Controller: newController(mgr, "KafkaConnector", defaultToken),
Controller: newController(mgr, "KafkaConnector", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller KafkaConnector: %w", err)
}

if err := (&RedisReconciler{
Controller: newController(mgr, "Redis", defaultToken),
Controller: newController(mgr, "Redis", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller Redis: %w", err)
}

if err := (&OpenSearchReconciler{
Controller: newController(mgr, "OpenSearch", defaultToken),
Controller: newController(mgr, "OpenSearch", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller OpenSearch: %w", err)
}

if err := (&ClickhouseReconciler{
Controller: newController(mgr, "Clickhouse", defaultToken),
Controller: newController(mgr, "Clickhouse", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller Clickhouse: %w", err)
}

if err := (&ClickhouseUserReconciler{
Controller: newController(mgr, "ClickhouseUser", defaultToken),
Controller: newController(mgr, "ClickhouseUser", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller ClickhouseUser: %w", err)
}

if err := (&MySQLReconciler{
Controller: newController(mgr, "MySQL", defaultToken),
Controller: newController(mgr, "MySQL", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller MySQL: %w", err)
}

if err := (&CassandraReconciler{
Controller: newController(mgr, "Cassandra", defaultToken),
Controller: newController(mgr, "Cassandra", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller Cassandra: %w", err)
}

if err := (&GrafanaReconciler{
Controller: newController(mgr, "Grafana", defaultToken),
Controller: newController(mgr, "Grafana", defaultToken, kubeVersion, operatorVersion),
}).SetupWithManager(mgr); err != nil {
return fmt.Errorf("controller Grafana: %w", err)
}
Expand All @@ -138,12 +138,14 @@ func SetupControllers(mgr ctrl.Manager, defaultToken string) error {
return nil
}

func newController(mgr ctrl.Manager, name, defaultToken string) Controller {
func newController(mgr ctrl.Manager, name, defaultToken, kubeVersion, operatorVersion string) Controller {
return Controller{
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName(name),
Scheme: mgr.GetScheme(),
Recorder: mgr.GetEventRecorderFor(strings.ToLower(name) + "-reconciler"),
DefaultToken: defaultToken,
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName(name),
Scheme: mgr.GetScheme(),
Recorder: mgr.GetEventRecorderFor(strings.ToLower(name) + "-reconciler"),
DefaultToken: defaultToken,
KubeVersion: kubeVersion,
OperatorVersion: operatorVersion,
}
}
17 changes: 16 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/discovery"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth"
ctrl "sigs.k8s.io/controller-runtime"
Expand All @@ -28,6 +29,9 @@ var (
setupLog = ctrl.Log.WithName("setup")
)

// operatorVersion is the current version of the operator.
const operatorVersion = "0.17.0"

const port = 9443

func init() {
Expand Down Expand Up @@ -79,8 +83,19 @@ func main() {
os.Exit(1)
}

discoveryClient, err := discovery.NewDiscoveryClientForConfig(mgr.GetConfig())
if err != nil {
setupLog.Error(err, "unable to create discovery client")
os.Exit(1)
}
kubeVersion, err := discoveryClient.ServerVersion()
if err != nil {
setupLog.Error(err, "unable to get kube version")
os.Exit(1)
}

defaultToken := os.Getenv("DEFAULT_AIVEN_TOKEN")
err = controllers.SetupControllers(mgr, defaultToken)
err = controllers.SetupControllers(mgr, defaultToken, kubeVersion.String(), operatorVersion)
if err != nil {
setupLog.Error(err, "controllers setup error")
}
Expand Down
26 changes: 20 additions & 6 deletions tests/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/kelseyhightower/envconfig"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/discovery"
"k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -34,6 +35,10 @@ const (
secretRefKey = "token"
)

// operatorVersion defines the version of the operator that is used in the tests.
// It is defined as "test" to be able to differentiate it from the actual operator version when running tests.
const operatorVersion = "test"

type testConfig struct {
Token string `envconfig:"AIVEN_TOKEN" required:"true"`
Project string `envconfig:"AIVEN_PROJECT_NAME" required:"true"`
Expand Down Expand Up @@ -103,11 +108,6 @@ func setupSuite() (*envtest.Environment, error) {
return nil, err
}

avnClient, err = controllers.NewAivenClient(cfg.Token)
if err != nil {
return nil, err
}

mgr, err := ctrl.NewManager(c, ctrl.Options{
Scheme: scheme.Scheme,
MetricsBindAddress: "0",
Expand All @@ -131,12 +131,26 @@ func setupSuite() (*envtest.Environment, error) {
ctx, cancel := testCtx()
defer cancel()

discoveryClient, err := discovery.NewDiscoveryClientForConfig(mgr.GetConfig())
if err != nil {
return nil, fmt.Errorf("unable to create discovery client: %w", err)
}
kubeVersion, err := discoveryClient.ServerVersion()
if err != nil {
return nil, fmt.Errorf("unable to get k8s version: %w", err)
}

avnClient, err = controllers.NewAivenClient(cfg.Token, kubeVersion.String()+"-test", operatorVersion+"-test")
if err != nil {
return nil, err
}

err = k8sClient.Create(ctx, secret)
if err != nil {
return nil, err
}

err = controllers.SetupControllers(mgr, cfg.Token)
err = controllers.SetupControllers(mgr, cfg.Token, kubeVersion.String(), operatorVersion)
if err != nil {
return nil, fmt.Errorf("unable to setup controllers: %w", err)
}
Expand Down
Loading