mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
[Feature] [Integration] SchedulerV2 (#1744)
This commit is contained in:
parent
ac0a256735
commit
846b6218af
16 changed files with 1169 additions and 3 deletions
|
@ -6,6 +6,7 @@
|
|||
- (Feature) Helm Client Extension
|
||||
- (Feature) (Integration) SchedulerV2 Definition
|
||||
- (Maintenance) Proto Lint
|
||||
- (Feature) (Integration) SchedulerV2
|
||||
|
||||
## [1.2.43](https://github.com/arangodb/kube-arangodb/tree/1.2.43) (2024-10-14)
|
||||
- (Feature) ArangoRoute CRD
|
||||
|
|
59
integrations/scheduler/v2/configuration.go
Normal file
59
integrations/scheduler/v2/configuration.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v2
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
|
||||
type Mod func(c Configuration) Configuration
|
||||
|
||||
func NewConfiguration() Configuration {
|
||||
return Configuration{
|
||||
Namespace: "default",
|
||||
}
|
||||
}
|
||||
|
||||
type Configuration struct {
|
||||
Namespace string
|
||||
|
||||
Deployment string
|
||||
}
|
||||
|
||||
func (c Configuration) Validate() error {
|
||||
if c.Deployment == "" {
|
||||
return errors.Errorf("Invalid empty name of deployment")
|
||||
}
|
||||
|
||||
if c.Namespace == "" {
|
||||
return errors.Errorf("Invalid empty name of namespace")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Configuration) With(mods ...Mod) Configuration {
|
||||
n := c
|
||||
|
||||
for _, mod := range mods {
|
||||
n = mod(n)
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
25
integrations/scheduler/v2/consts.go
Normal file
25
integrations/scheduler/v2/consts.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v2
|
||||
|
||||
const (
|
||||
LabelArangoDBDeploymentName = "deployment.arangodb.com/name"
|
||||
)
|
222
integrations/scheduler/v2/helm.go
Normal file
222
integrations/scheduler/v2/helm.go
Normal file
|
@ -0,0 +1,222 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"helm.sh/helm/v3/pkg/action"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
|
||||
pbSchedulerV2 "github.com/arangodb/kube-arangodb/integrations/scheduler/v2/definition"
|
||||
pbSharedV1 "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
)
|
||||
|
||||
func (i *implementation) Alive(ctx context.Context, in *pbSharedV1.Empty) (*pbSharedV1.Empty, error) {
|
||||
if err := i.client.Alive(ctx); err != nil {
|
||||
logger.Err(err).Warn("Helm is not alive")
|
||||
return nil, status.Errorf(codes.Unavailable, "Service is not alive")
|
||||
}
|
||||
|
||||
return &pbSharedV1.Empty{}, nil
|
||||
}
|
||||
|
||||
func (i *implementation) List(ctx context.Context, in *pbSchedulerV2.SchedulerV2ListRequest) (*pbSchedulerV2.SchedulerV2ListResponse, error) {
|
||||
var mods []util.Mod[action.List]
|
||||
|
||||
mods = append(mods, in.GetOptions().Options()...)
|
||||
mods = append(mods, func(action *action.List) {
|
||||
var s = labels.NewSelector()
|
||||
if action.Selector != "" {
|
||||
if n, err := labels.Parse(action.Selector); err == nil {
|
||||
s = n
|
||||
}
|
||||
}
|
||||
|
||||
if r, err := labels.NewRequirement(LabelArangoDBDeploymentName, selection.DoubleEquals, []string{i.cfg.Deployment}); err != nil {
|
||||
logger.Err(err).Warn("Unable to render selector")
|
||||
} else if r != nil {
|
||||
s = s.Add(*r)
|
||||
}
|
||||
|
||||
action.Selector = s.String()
|
||||
})
|
||||
|
||||
resp, err := i.client.List(ctx, mods...)
|
||||
if err != nil {
|
||||
logger.Err(err).Warn("Unable to run action: List")
|
||||
return nil, status.Errorf(codes.Internal, "Unable to run action: List: %s", err.Error())
|
||||
}
|
||||
|
||||
releases := make(map[string]*pbSchedulerV2.SchedulerV2Release, len(resp))
|
||||
|
||||
for _, r := range resp {
|
||||
releases[r.Name] = newChartReleaseFromHelmRelease(&r)
|
||||
}
|
||||
|
||||
return &pbSchedulerV2.SchedulerV2ListResponse{
|
||||
Releases: releases,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (i *implementation) Status(ctx context.Context, in *pbSchedulerV2.SchedulerV2StatusRequest) (*pbSchedulerV2.SchedulerV2StatusResponse, error) {
|
||||
if in.GetName() == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Name cannot be empty")
|
||||
}
|
||||
|
||||
resp, err := i.client.Status(ctx, in.GetName())
|
||||
if err != nil {
|
||||
logger.Err(err).Warn("Unable to run action: Status")
|
||||
return nil, status.Errorf(codes.Internal, "Unable to run action: Status: %s", err.Error())
|
||||
}
|
||||
|
||||
return &pbSchedulerV2.SchedulerV2StatusResponse{
|
||||
Release: newChartReleaseFromHelmRelease(resp),
|
||||
}, nil
|
||||
}
|
||||
func (i *implementation) StatusObjects(ctx context.Context, in *pbSchedulerV2.SchedulerV2StatusObjectsRequest) (*pbSchedulerV2.SchedulerV2StatusObjectsResponse, error) {
|
||||
if in.GetName() == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Name cannot be empty")
|
||||
}
|
||||
|
||||
resp, objs, err := i.client.StatusObjects(ctx, in.GetName())
|
||||
if err != nil {
|
||||
logger.Err(err).Warn("Unable to run action: Status")
|
||||
return nil, status.Errorf(codes.Internal, "Unable to run action: Status: %s", err.Error())
|
||||
}
|
||||
|
||||
return &pbSchedulerV2.SchedulerV2StatusObjectsResponse{
|
||||
Release: newChartReleaseFromHelmRelease(resp),
|
||||
Objects: newReleaseInfoResourceObjectsFromResourceObjects(objs),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (i *implementation) Install(ctx context.Context, in *pbSchedulerV2.SchedulerV2InstallRequest) (*pbSchedulerV2.SchedulerV2InstallResponse, error) {
|
||||
if in.GetName() == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Name cannot be empty")
|
||||
}
|
||||
|
||||
var mods []util.Mod[action.Install]
|
||||
|
||||
mods = append(mods, in.GetOptions().Options()...)
|
||||
mods = append(mods, func(action *action.Install) {
|
||||
action.ReleaseName = in.GetName()
|
||||
action.Namespace = i.cfg.Namespace
|
||||
|
||||
if action.Labels == nil {
|
||||
action.Labels = map[string]string{}
|
||||
}
|
||||
|
||||
action.Labels[LabelArangoDBDeploymentName] = i.cfg.Deployment
|
||||
})
|
||||
|
||||
resp, err := i.client.Install(ctx, in.GetChart(), in.GetValues(), mods...)
|
||||
if err != nil {
|
||||
logger.Err(err).Warn("Unable to run action: Install")
|
||||
return nil, status.Errorf(codes.Internal, "Unable to run action: Install: %s", err.Error())
|
||||
}
|
||||
|
||||
return &pbSchedulerV2.SchedulerV2InstallResponse{
|
||||
Release: newChartReleaseFromHelmRelease(resp),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (i *implementation) Upgrade(ctx context.Context, in *pbSchedulerV2.SchedulerV2UpgradeRequest) (*pbSchedulerV2.SchedulerV2UpgradeResponse, error) {
|
||||
if in.GetName() == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Name cannot be empty")
|
||||
}
|
||||
|
||||
var mods []util.Mod[action.Upgrade]
|
||||
|
||||
mods = append(mods, in.GetOptions().Options()...)
|
||||
mods = append(mods, func(action *action.Upgrade) {
|
||||
action.Namespace = i.cfg.Namespace
|
||||
|
||||
if action.Labels == nil {
|
||||
action.Labels = map[string]string{}
|
||||
}
|
||||
|
||||
action.Labels[LabelArangoDBDeploymentName] = i.cfg.Deployment
|
||||
})
|
||||
|
||||
resp, err := i.client.Upgrade(ctx, in.GetName(), in.GetChart(), in.GetValues(), mods...)
|
||||
if err != nil {
|
||||
logger.Err(err).Warn("Unable to run action: Upgrade")
|
||||
return nil, status.Errorf(codes.Internal, "Unable to run action: Upgrade: %s", err.Error())
|
||||
}
|
||||
|
||||
var r pbSchedulerV2.SchedulerV2UpgradeResponse
|
||||
|
||||
if q := resp.Before; q != nil {
|
||||
r.Before = newChartReleaseFromHelmRelease(q)
|
||||
}
|
||||
|
||||
if q := resp.After; q != nil {
|
||||
r.After = newChartReleaseFromHelmRelease(q)
|
||||
}
|
||||
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
func (i *implementation) Uninstall(ctx context.Context, in *pbSchedulerV2.SchedulerV2UninstallRequest) (*pbSchedulerV2.SchedulerV2UninstallResponse, error) {
|
||||
if in.GetName() == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Name cannot be empty")
|
||||
}
|
||||
|
||||
var mods []util.Mod[action.Uninstall]
|
||||
|
||||
mods = append(mods, in.GetOptions().Options()...)
|
||||
|
||||
resp, err := i.client.Uninstall(ctx, in.GetName(), mods...)
|
||||
if err != nil {
|
||||
logger.Err(err).Warn("Unable to run action: Uninstall")
|
||||
return nil, status.Errorf(codes.Internal, "Unable to run action: Uninstall: %s", err.Error())
|
||||
}
|
||||
|
||||
return &pbSchedulerV2.SchedulerV2UninstallResponse{
|
||||
Info: resp.Info,
|
||||
Release: newChartReleaseFromHelmRelease(&resp.Release),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (i *implementation) Test(ctx context.Context, in *pbSchedulerV2.SchedulerV2TestRequest) (*pbSchedulerV2.SchedulerV2TestResponse, error) {
|
||||
if in.GetName() == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Name cannot be empty")
|
||||
}
|
||||
|
||||
var mods []util.Mod[action.ReleaseTesting]
|
||||
|
||||
mods = append(mods, in.GetOptions().Options()...)
|
||||
|
||||
resp, err := i.client.Test(ctx, in.GetName(), mods...)
|
||||
if err != nil {
|
||||
logger.Err(err).Warn("Unable to run action: Test")
|
||||
return nil, status.Errorf(codes.Internal, "Unable to run action: Test: %s", err.Error())
|
||||
}
|
||||
|
||||
return &pbSchedulerV2.SchedulerV2TestResponse{
|
||||
Release: newChartReleaseFromHelmRelease(resp),
|
||||
}, nil
|
||||
}
|
76
integrations/scheduler/v2/implementation.go
Normal file
76
integrations/scheduler/v2/implementation.go
Normal file
|
@ -0,0 +1,76 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
pbSchedulerV2 "github.com/arangodb/kube-arangodb/integrations/scheduler/v2/definition"
|
||||
pbSharedV1 "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helm"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/svc"
|
||||
)
|
||||
|
||||
var _ pbSchedulerV2.SchedulerV2Server = &implementation{}
|
||||
var _ svc.Handler = &implementation{}
|
||||
|
||||
func New(client helm.Client, cfg Configuration) (svc.Handler, error) {
|
||||
return newInternal(client, cfg)
|
||||
}
|
||||
|
||||
func newInternal(client helm.Client, c Configuration) (*implementation, error) {
|
||||
if err := c.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &implementation{
|
||||
cfg: c,
|
||||
client: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type implementation struct {
|
||||
cfg Configuration
|
||||
|
||||
client helm.Client
|
||||
|
||||
pbSchedulerV2.UnimplementedSchedulerV2Server
|
||||
}
|
||||
|
||||
func (i *implementation) Name() string {
|
||||
return pbSchedulerV2.Name
|
||||
}
|
||||
|
||||
func (i *implementation) Register(registrar *grpc.Server) {
|
||||
pbSchedulerV2.RegisterSchedulerV2Server(registrar, i)
|
||||
}
|
||||
|
||||
func (i *implementation) Health() svc.HealthState {
|
||||
return svc.Healthy
|
||||
}
|
||||
|
||||
func (i *implementation) InvalidateCache(ctx context.Context, in *pbSharedV1.Empty) (*pbSharedV1.Empty, error) {
|
||||
i.client.Invalidate()
|
||||
|
||||
return &pbSharedV1.Empty{}, nil
|
||||
}
|
277
integrations/scheduler/v2/implementation_test.go
Normal file
277
integrations/scheduler/v2/implementation_test.go
Normal file
|
@ -0,0 +1,277 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"helm.sh/helm/v3/pkg/action"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/integrations/scheduler/v2/definition"
|
||||
pbSharedV1 "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helm"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/tests"
|
||||
)
|
||||
|
||||
func cleanup(t *testing.T, c helm.Client) func() {
|
||||
t.Run("Cleanup Pre", func(t *testing.T) {
|
||||
items, err := c.List(context.Background(), func(in *action.List) {
|
||||
in.All = true
|
||||
in.StateMask = action.ListDeployed | action.ListUninstalled | action.ListUninstalling | action.ListPendingInstall | action.ListPendingUpgrade | action.ListPendingRollback | action.ListSuperseded | action.ListFailed | action.ListUnknown
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, item := range items {
|
||||
t.Run(item.Name, func(t *testing.T) {
|
||||
_, err := c.Uninstall(context.Background(), item.Name)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return func() {
|
||||
t.Run("Cleanup Post", func(t *testing.T) {
|
||||
items, err := c.List(context.Background(), func(in *action.List) {
|
||||
in.All = true
|
||||
in.StateMask = action.ListDeployed | action.ListUninstalled | action.ListUninstalling | action.ListPendingInstall | action.ListPendingUpgrade | action.ListPendingRollback | action.ListSuperseded | action.ListFailed | action.ListUnknown
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, item := range items {
|
||||
t.Run(item.Name, func(t *testing.T) {
|
||||
_, err := c.Uninstall(context.Background(), item.Name)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Implementation(t *testing.T) {
|
||||
ctx, c := context.WithCancel(context.Background())
|
||||
defer c()
|
||||
|
||||
scheduler, h := Client(t, ctx, func(c Configuration) Configuration {
|
||||
c.Namespace = tests.FakeNamespace
|
||||
c.Deployment = tests.FakeNamespace
|
||||
return c
|
||||
})
|
||||
|
||||
values, err := helm.NewValues(map[string]string{
|
||||
"A": "B",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
defer cleanup(t, h)()
|
||||
|
||||
t.Run("Alive", func(t *testing.T) {
|
||||
_, err := scheduler.Alive(context.Background(), &pbSharedV1.Empty{})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Check API Resources", func(t *testing.T) {
|
||||
o, err := scheduler.DiscoverAPIResources(context.Background(), &definition.SchedulerV2DiscoverAPIResourcesRequest{
|
||||
Version: "v1",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
for _, z := range o.Resources {
|
||||
t.Logf("Kind: %s", z.GetKind())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Check API Resource", func(t *testing.T) {
|
||||
|
||||
oz, err := scheduler.DiscoverAPIResource(context.Background(), &definition.SchedulerV2DiscoverAPIResourceRequest{
|
||||
Version: "v1",
|
||||
Kind: "ConfigMap",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, oz.GetResource())
|
||||
})
|
||||
|
||||
t.Run("Check API Resource - Missing", func(t *testing.T) {
|
||||
|
||||
oz, err := scheduler.DiscoverAPIResource(context.Background(), &definition.SchedulerV2DiscoverAPIResourceRequest{
|
||||
Version: "v1",
|
||||
Kind: "ConfigMap2",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, oz.GetResource())
|
||||
})
|
||||
|
||||
t.Run("Status on Missing", func(t *testing.T) {
|
||||
status, err := scheduler.Status(context.Background(), &definition.SchedulerV2StatusRequest{
|
||||
Name: "test",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Nil(t, status.GetRelease())
|
||||
})
|
||||
|
||||
t.Run("List Empty", func(t *testing.T) {
|
||||
status, err := scheduler.List(context.Background(), &definition.SchedulerV2ListRequest{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, status.GetReleases(), 0)
|
||||
})
|
||||
|
||||
t.Run("Install", func(t *testing.T) {
|
||||
status, err := scheduler.Install(context.Background(), &definition.SchedulerV2InstallRequest{
|
||||
Name: "test",
|
||||
Values: nil,
|
||||
Chart: example_1_0_0,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, status.GetRelease())
|
||||
})
|
||||
|
||||
t.Run("List After", func(t *testing.T) {
|
||||
status, err := scheduler.List(context.Background(), &definition.SchedulerV2ListRequest{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, status.GetReleases(), 1)
|
||||
})
|
||||
|
||||
t.Run("Install Outside", func(t *testing.T) {
|
||||
resp, err := h.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) {
|
||||
in.ReleaseName = "test-outside"
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, resp)
|
||||
})
|
||||
|
||||
t.Run("List After - Still should not see first one", func(t *testing.T) {
|
||||
status, err := scheduler.List(context.Background(), &definition.SchedulerV2ListRequest{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, status.GetReleases(), 1)
|
||||
})
|
||||
|
||||
t.Run("Install Second", func(t *testing.T) {
|
||||
status, err := scheduler.Install(context.Background(), &definition.SchedulerV2InstallRequest{
|
||||
Name: "test-x",
|
||||
Values: nil,
|
||||
Chart: example_1_0_0,
|
||||
Options: &definition.SchedulerV2InstallRequestOptions{
|
||||
Labels: map[string]string{
|
||||
"X": "X",
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, status.GetRelease())
|
||||
})
|
||||
|
||||
t.Run("Install Second Outside", func(t *testing.T) {
|
||||
resp, err := h.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) {
|
||||
in.ReleaseName = "test-outside-x"
|
||||
in.Labels = map[string]string{
|
||||
"X": "X",
|
||||
}
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, resp)
|
||||
})
|
||||
|
||||
t.Run("List After - Should see 2 services", func(t *testing.T) {
|
||||
status, err := scheduler.List(context.Background(), &definition.SchedulerV2ListRequest{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, status.GetReleases(), 2)
|
||||
})
|
||||
|
||||
t.Run("List After - Filter one", func(t *testing.T) {
|
||||
status, err := scheduler.List(context.Background(), &definition.SchedulerV2ListRequest{
|
||||
Options: &definition.SchedulerV2ListRequestOptions{
|
||||
Selectors: map[string]string{
|
||||
"X": "X",
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, status.GetReleases(), 1)
|
||||
})
|
||||
|
||||
t.Run("Check - Version 1", func(t *testing.T) {
|
||||
status, err := scheduler.Status(context.Background(), &definition.SchedulerV2StatusRequest{
|
||||
Name: "test",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, status.GetRelease())
|
||||
|
||||
require.EqualValues(t, 1, status.GetRelease().GetVersion())
|
||||
t.Logf("Data: %s", string(status.GetRelease().GetValues()))
|
||||
require.Len(t, status.GetRelease().GetValues(), 4)
|
||||
})
|
||||
|
||||
t.Run("Upgrade", func(t *testing.T) {
|
||||
status, err := scheduler.Upgrade(context.Background(), &definition.SchedulerV2UpgradeRequest{
|
||||
Name: "test",
|
||||
Values: values,
|
||||
Chart: example_1_0_0,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, status.GetAfter())
|
||||
t.Logf("Data: %s", string(status.GetAfter().GetValues()))
|
||||
require.Len(t, status.GetAfter().GetValues(), len(values))
|
||||
})
|
||||
|
||||
t.Run("Check - Version 2", func(t *testing.T) {
|
||||
status, err := scheduler.Status(context.Background(), &definition.SchedulerV2StatusRequest{
|
||||
Name: "test",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, status.GetRelease())
|
||||
|
||||
require.EqualValues(t, 2, status.GetRelease().GetVersion())
|
||||
t.Logf("Data: %s", string(status.GetRelease().GetValues()))
|
||||
require.Len(t, status.GetRelease().GetValues(), len(values))
|
||||
})
|
||||
|
||||
t.Run("Test", func(t *testing.T) {
|
||||
status, err := scheduler.Test(context.Background(), &definition.SchedulerV2TestRequest{
|
||||
Name: "test",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, status.GetRelease())
|
||||
})
|
||||
|
||||
t.Run("Uninstall", func(t *testing.T) {
|
||||
status, err := scheduler.Uninstall(context.Background(), &definition.SchedulerV2UninstallRequest{
|
||||
Name: "test",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, status.GetRelease())
|
||||
t.Logf("Response: %s", status.GetInfo())
|
||||
})
|
||||
}
|
102
integrations/scheduler/v2/kubernetes.go
Normal file
102
integrations/scheduler/v2/kubernetes.go
Normal file
|
@ -0,0 +1,102 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
pbSchedulerV2 "github.com/arangodb/kube-arangodb/integrations/scheduler/v2/definition"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helm"
|
||||
)
|
||||
|
||||
func (i *implementation) DiscoverAPIResources(ctx context.Context, in *pbSchedulerV2.SchedulerV2DiscoverAPIResourcesRequest) (*pbSchedulerV2.SchedulerV2DiscoverAPIResourcesResponse, error) {
|
||||
if in.GetVersion() == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Version cannot be empty")
|
||||
}
|
||||
|
||||
resp, err := i.client.DiscoverKubernetesApiVersions(schema.GroupVersion{
|
||||
Group: in.GetGroup(),
|
||||
Version: in.GetVersion(),
|
||||
})
|
||||
if err != nil {
|
||||
logger.Err(err).Warn("Unable to run action: DiscoverAPIResources")
|
||||
return nil, status.Errorf(codes.Internal, "Unable to run action: DiscoverAPIResources: %s", err.Error())
|
||||
}
|
||||
|
||||
resources := make([]*pbSchedulerV2.SchedulerV2DiscoverAPIResource, 0, len(resp))
|
||||
|
||||
for _, v := range resp {
|
||||
resources = append(resources, newKubernetesApiResourceFromDiscoveryResource(v))
|
||||
}
|
||||
|
||||
return &pbSchedulerV2.SchedulerV2DiscoverAPIResourcesResponse{
|
||||
Resources: resources,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (i *implementation) DiscoverAPIResource(ctx context.Context, in *pbSchedulerV2.SchedulerV2DiscoverAPIResourceRequest) (*pbSchedulerV2.SchedulerV2DiscoverAPIResourceResponse, error) {
|
||||
if in.GetVersion() == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Version cannot be empty")
|
||||
}
|
||||
if in.GetKind() == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Kind cannot be empty")
|
||||
}
|
||||
|
||||
resp, err := i.client.DiscoverKubernetesApiVersionKind(schema.GroupVersionKind{
|
||||
Group: in.GetGroup(),
|
||||
Version: in.GetVersion(),
|
||||
Kind: in.GetKind(),
|
||||
})
|
||||
if err != nil {
|
||||
logger.Err(err).Warn("Unable to run action: DiscoverAPIResource")
|
||||
return nil, status.Errorf(codes.Internal, "Unable to run action: DiscoverAPIResource: %s", err.Error())
|
||||
}
|
||||
|
||||
if resp != nil {
|
||||
return &pbSchedulerV2.SchedulerV2DiscoverAPIResourceResponse{
|
||||
Resource: newKubernetesApiResourceFromDiscoveryResource(*resp),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &pbSchedulerV2.SchedulerV2DiscoverAPIResourceResponse{}, nil
|
||||
}
|
||||
|
||||
func (i *implementation) KubernetesGet(ctx context.Context, in *pbSchedulerV2.SchedulerV2KubernetesGetRequest) (*pbSchedulerV2.SchedulerV2KubernetesGetResponse, error) {
|
||||
reqs := make(helm.Resources, len(in.GetResources()))
|
||||
|
||||
for id := range reqs {
|
||||
reqs[id] = in.GetResources()[id].AsHelmResource()
|
||||
}
|
||||
|
||||
resp, err := i.client.NativeGet(ctx, reqs...)
|
||||
if err != nil {
|
||||
logger.Err(err).Warn("Unable to run action: KubernetesGet")
|
||||
return nil, status.Errorf(codes.Internal, "Unable to run action: KubernetesGet: %s", err.Error())
|
||||
}
|
||||
|
||||
return &pbSchedulerV2.SchedulerV2KubernetesGetResponse{
|
||||
Objects: newReleaseInfoResourceObjectsFromResourceObjects(resp),
|
||||
}, nil
|
||||
}
|
25
integrations/scheduler/v2/logger.go
Normal file
25
integrations/scheduler/v2/logger.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v2
|
||||
|
||||
import "github.com/arangodb/kube-arangodb/pkg/logging"
|
||||
|
||||
var logger = logging.Global().RegisterAndGetLogger("integration-scheduler-v2", logging.Info)
|
128
integrations/scheduler/v2/suite.go
Normal file
128
integrations/scheduler/v2/suite.go
Normal file
|
@ -0,0 +1,128 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
pbSchedulerV2 "github.com/arangodb/kube-arangodb/integrations/scheduler/v2/definition"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helm"
|
||||
)
|
||||
|
||||
func newChartReleaseFromHelmRelease(in *helm.Release) *pbSchedulerV2.SchedulerV2Release {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var rel pbSchedulerV2.SchedulerV2Release
|
||||
|
||||
rel.Name = in.Name
|
||||
rel.Namespace = in.Namespace
|
||||
rel.Values = in.Values
|
||||
rel.Version = int64(in.Version)
|
||||
rel.Labels = in.Labels
|
||||
rel.Info = newChartReleaseInfoFromHelmRelease(in.Info)
|
||||
|
||||
return &rel
|
||||
}
|
||||
|
||||
func newChartReleaseInfoFromHelmRelease(in helm.ReleaseInfo) *pbSchedulerV2.SchedulerV2ReleaseInfo {
|
||||
var rel pbSchedulerV2.SchedulerV2ReleaseInfo
|
||||
|
||||
rel.FirstDeployed = timestamppb.New(in.FirstDeployed)
|
||||
rel.LastDeployed = timestamppb.New(in.LastDeployed)
|
||||
rel.Deleted = timestamppb.New(in.Deleted)
|
||||
rel.Description = in.Description
|
||||
rel.Notes = in.Notes
|
||||
rel.Status = pbSchedulerV2.FromHelmStatus(in.Status)
|
||||
rel.Resources = newChartReleaseResourcesInfoFromHelmRelease(in.Resources)
|
||||
|
||||
return &rel
|
||||
}
|
||||
|
||||
func newChartReleaseResourcesInfoFromHelmRelease(in helm.Resources) []*pbSchedulerV2.SchedulerV2ReleaseInfoResource {
|
||||
if len(in) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var r = make([]*pbSchedulerV2.SchedulerV2ReleaseInfoResource, len(in))
|
||||
|
||||
for id := range r {
|
||||
r[id] = newChartReleaseResourceInfoFromHelmRelease(in[id])
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func newChartReleaseResourceInfoFromHelmRelease(in helm.Resource) *pbSchedulerV2.SchedulerV2ReleaseInfoResource {
|
||||
var r pbSchedulerV2.SchedulerV2ReleaseInfoResource
|
||||
|
||||
r.Gvk = &pbSchedulerV2.SchedulerV2GVK{
|
||||
Group: in.Group,
|
||||
Version: in.Version,
|
||||
Kind: in.Kind,
|
||||
}
|
||||
|
||||
r.Name = in.Name
|
||||
r.Namespace = in.Namespace
|
||||
|
||||
return &r
|
||||
}
|
||||
|
||||
func newKubernetesApiResourceFromDiscoveryResource(in meta.APIResource) *pbSchedulerV2.SchedulerV2DiscoverAPIResource {
|
||||
return &pbSchedulerV2.SchedulerV2DiscoverAPIResource{
|
||||
Name: in.Name,
|
||||
SingularName: in.SingularName,
|
||||
Namespaced: in.Namespaced,
|
||||
Group: in.Group,
|
||||
Version: in.Version,
|
||||
Kind: in.Kind,
|
||||
Verbs: in.Verbs,
|
||||
ShortNames: in.ShortNames,
|
||||
Categories: in.Categories,
|
||||
StorageVersionHash: in.StorageVersionHash,
|
||||
}
|
||||
}
|
||||
|
||||
func newReleaseInfoResourceObjectsFromResourceObjects(in []helm.ResourceObject) []*pbSchedulerV2.SchedulerV2ReleaseInfoResourceObject {
|
||||
res := make([]*pbSchedulerV2.SchedulerV2ReleaseInfoResourceObject, len(in))
|
||||
|
||||
for id := range res {
|
||||
res[id] = newReleaseInfoResourceObjectFromResourceObject(in[id])
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func newReleaseInfoResourceObjectFromResourceObject(in helm.ResourceObject) *pbSchedulerV2.SchedulerV2ReleaseInfoResourceObject {
|
||||
var r pbSchedulerV2.SchedulerV2ReleaseInfoResourceObject
|
||||
|
||||
r.Resource = newChartReleaseResourceInfoFromHelmRelease(in.Resource)
|
||||
|
||||
if d := in.Object; d != nil {
|
||||
r.Data = &pbSchedulerV2.SchedulerV2ReleaseInfoResourceObjectData{
|
||||
Data: d.Data,
|
||||
}
|
||||
}
|
||||
|
||||
return &r
|
||||
}
|
BIN
integrations/scheduler/v2/suite/example-1.0.0.tgz
Normal file
BIN
integrations/scheduler/v2/suite/example-1.0.0.tgz
Normal file
Binary file not shown.
82
integrations/scheduler/v2/suite_test.go
Normal file
82
integrations/scheduler/v2/suite_test.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
pbSchedulerV2 "github.com/arangodb/kube-arangodb/integrations/scheduler/v2/definition"
|
||||
"github.com/arangodb/kube-arangodb/pkg/logging"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helm"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/svc"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/tests"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/tests/tgrpc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logging.Global().ApplyLogLevels(map[string]logging.Level{
|
||||
logging.TopicAll: logging.Debug,
|
||||
})
|
||||
}
|
||||
|
||||
//go:embed suite/example-1.0.0.tgz
|
||||
var example_1_0_0 []byte
|
||||
|
||||
func Handler(t *testing.T, ctx context.Context, client helm.Client, mods ...Mod) svc.Handler {
|
||||
handler, err := New(client, NewConfiguration().With(mods...))
|
||||
require.NoError(t, err)
|
||||
|
||||
return handler
|
||||
}
|
||||
|
||||
func Client(t *testing.T, ctx context.Context, mods ...Mod) (pbSchedulerV2.SchedulerV2Client, helm.Client) {
|
||||
z, ok := os.LookupEnv("TEST_KUBECONFIG")
|
||||
if !ok {
|
||||
t.Skipf("TEST_KUBECONFIG is not set")
|
||||
}
|
||||
|
||||
cfg, err := clientcmd.BuildConfigFromFlags("", z)
|
||||
require.NoError(t, err)
|
||||
|
||||
client, err := kclient.NewClient("test", cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
h, err := helm.NewClient(helm.Configuration{
|
||||
Namespace: tests.FakeNamespace,
|
||||
Client: client,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
local := svc.NewService(svc.Configuration{
|
||||
Address: "127.0.0.1:0",
|
||||
}, Handler(t, ctx, h, mods...))
|
||||
|
||||
start := local.Start(ctx)
|
||||
|
||||
return tgrpc.NewGRPCClient(t, ctx, pbSchedulerV2.NewSchedulerV2Client, start.Address()), h
|
||||
}
|
|
@ -109,7 +109,7 @@ func (r *Resources) EnsureArangoProfiles(ctx context.Context, cachedStatus inspe
|
|||
|
||||
integration, err := sidecar.NewIntegration(&schedulerContainerResourcesApi.Image{
|
||||
Image: util.NewType(r.context.GetOperatorImage()),
|
||||
}, spec.Integration.GetSidecar())
|
||||
}, spec.Integration.GetSidecar(), r.arangoDeploymentProfileTemplate())
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
@ -133,6 +133,8 @@ func (r *Resources) EnsureArangoProfiles(ctx context.Context, cachedStatus inspe
|
|||
gen(constants.ProfilesIntegrationAuthz, constants.ProfilesIntegrationV0, sidecar.IntegrationAuthorizationV0{}),
|
||||
gen(constants.ProfilesIntegrationAuthn, constants.ProfilesIntegrationV1, sidecar.IntegrationAuthenticationV1{Spec: spec, DeploymentName: apiObject.GetName()}),
|
||||
gen(constants.ProfilesIntegrationSched, constants.ProfilesIntegrationV1, sidecar.IntegrationSchedulerV1{}),
|
||||
gen(constants.ProfilesIntegrationSched, constants.ProfilesIntegrationV2, sidecar.IntegrationSchedulerV2{}),
|
||||
gen(constants.ProfilesIntegrationEnvoy, constants.ProfilesIntegrationV3, sidecar.IntegrationEnvoyV3{Spec: spec}),
|
||||
); err != nil {
|
||||
return err
|
||||
} else if changed {
|
||||
|
@ -142,6 +144,10 @@ func (r *Resources) EnsureArangoProfiles(ctx context.Context, cachedStatus inspe
|
|||
return reconcileRequired.Reconcile(ctx)
|
||||
}
|
||||
|
||||
func (r *Resources) arangoDeploymentProfileTemplate() *schedulerApi.ProfileTemplate {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Resources) ensureArangoProfilesFactory(ctx context.Context, cachedStatus inspectorInterface.Inspector, expected ...func() (string, *schedulerApi.ArangoProfile, error)) (bool, error) {
|
||||
var changed bool
|
||||
|
||||
|
|
81
pkg/integrations/scheduler_v2.go
Normal file
81
pkg/integrations/scheduler_v2.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package integrations
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
pbImplSchedulerV2 "github.com/arangodb/kube-arangodb/integrations/scheduler/v2"
|
||||
pbSchedulerV2 "github.com/arangodb/kube-arangodb/integrations/scheduler/v2/definition"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/constants"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helm"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/svc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerer.Register(pbSchedulerV2.Name, func() Integration {
|
||||
return &schedulerV2{}
|
||||
})
|
||||
}
|
||||
|
||||
type schedulerV2 struct {
|
||||
Configuration pbImplSchedulerV2.Configuration
|
||||
}
|
||||
|
||||
func (b *schedulerV2) Name() string {
|
||||
return pbSchedulerV2.Name
|
||||
}
|
||||
|
||||
func (b *schedulerV2) Description() string {
|
||||
return "SchedulerV2 Integration"
|
||||
}
|
||||
|
||||
func (b *schedulerV2) Register(cmd *cobra.Command, fs FlagEnvHandler) error {
|
||||
return errors.Errors(
|
||||
fs.StringVar(&b.Configuration.Namespace, "namespace", constants.NamespaceWithDefault("default"), "Kubernetes Namespace"),
|
||||
fs.StringVar(&b.Configuration.Deployment, "deployment", "", "ArangoDeployment Name"),
|
||||
)
|
||||
}
|
||||
|
||||
func (b *schedulerV2) Handler(ctx context.Context, cmd *cobra.Command) (svc.Handler, error) {
|
||||
client, ok := kclient.GetDefaultFactory().Client()
|
||||
if !ok {
|
||||
return nil, errors.Errorf("Unable to create Kubernetes Client")
|
||||
}
|
||||
|
||||
helm, err := helm.NewClient(helm.Configuration{
|
||||
Namespace: b.Configuration.Namespace,
|
||||
Client: client,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Unable to create Helm Client")
|
||||
}
|
||||
|
||||
return pbImplSchedulerV2.New(helm, b.Configuration)
|
||||
}
|
||||
|
||||
func (*schedulerV2) Init(ctx context.Context, cmd *cobra.Command) error {
|
||||
return nil
|
||||
}
|
|
@ -116,7 +116,7 @@ func NewIntegrationEnablement(integrations ...Integration) (*schedulerApi.Profil
|
|||
}, nil
|
||||
}
|
||||
|
||||
func NewIntegration(image *schedulerContainerResourcesApi.Image, integration *schedulerIntegrationApi.Sidecar) (*schedulerApi.ProfileTemplate, error) {
|
||||
func NewIntegration(image *schedulerContainerResourcesApi.Image, integration *schedulerIntegrationApi.Sidecar, profiles ...*schedulerApi.ProfileTemplate) (*schedulerApi.ProfileTemplate, error) {
|
||||
// Arguments
|
||||
|
||||
exePath := k8sutil.BinaryPath()
|
||||
|
@ -212,5 +212,11 @@ func NewIntegration(image *schedulerContainerResourcesApi.Image, integration *sc
|
|||
Env: envs,
|
||||
}
|
||||
|
||||
return &pt, nil
|
||||
res := &pt
|
||||
|
||||
for _, prof := range profiles {
|
||||
res = res.With(prof)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
|
73
pkg/integrations/sidecar/integration.scheduler.v2.go
Normal file
73
pkg/integrations/sidecar/integration.scheduler.v2.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package sidecar
|
||||
|
||||
import (
|
||||
core "k8s.io/api/core/v1"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type IntegrationSchedulerV2 struct {
|
||||
Core *Core
|
||||
|
||||
DeploymentName string
|
||||
Spec api.DeploymentSpec
|
||||
}
|
||||
|
||||
func (i IntegrationSchedulerV2) Name() []string {
|
||||
return []string{"SCHEDULER", "V2"}
|
||||
}
|
||||
|
||||
func (i IntegrationSchedulerV2) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i IntegrationSchedulerV2) Envs() ([]core.EnvVar, error) {
|
||||
var envs = []core.EnvVar{
|
||||
{
|
||||
Name: "INTEGRATION_SCHEDULER_V2",
|
||||
Value: "true",
|
||||
},
|
||||
{
|
||||
Name: "INTEGRATION_SCHEDULER_V2_NAMESPACE",
|
||||
ValueFrom: &core.EnvVarSource{
|
||||
FieldRef: &core.ObjectFieldSelector{
|
||||
FieldPath: "metadata.namespace",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "INTEGRATION_SCHEDULER_V2_DEPLOYMENT",
|
||||
Value: i.DeploymentName,
|
||||
},
|
||||
}
|
||||
|
||||
return i.Core.Envs(i, envs...), nil
|
||||
}
|
||||
|
||||
func (i IntegrationSchedulerV2) GlobalEnvs() ([]core.EnvVar, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (i IntegrationSchedulerV2) Volumes() ([]core.Volume, []core.VolumeMount, error) {
|
||||
return nil, nil, nil
|
||||
}
|
|
@ -31,11 +31,14 @@ const (
|
|||
ProfilesIntegrationAuthn = "authn"
|
||||
ProfilesIntegrationAuthz = "authz"
|
||||
ProfilesIntegrationSched = "sched"
|
||||
ProfilesIntegrationEnvoy = "envoy"
|
||||
)
|
||||
|
||||
const (
|
||||
ProfilesIntegrationV0 = "v0"
|
||||
ProfilesIntegrationV1 = "v1"
|
||||
ProfilesIntegrationV2 = "v2"
|
||||
ProfilesIntegrationV3 = "v3"
|
||||
)
|
||||
|
||||
func NewProfileIntegration(name, version string) (string, string) {
|
||||
|
|
Loading…
Reference in a new issue