1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Feature] Agency Lock bugfix (#1335)

This commit is contained in:
Adam Janikowski 2023-06-14 12:24:44 +02:00 committed by GitHub
parent de90967fd6
commit d83a1cec84
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 176 additions and 432 deletions

View file

@ -6,6 +6,7 @@
- (Feature) Metrics Counter
- (Feature) Requests Bytes Counter
- (Feature) Agency Poll System
- (Bugfix) (CE) Agency Lock bugfix
## [1.2.29](https://github.com/arangodb/kube-arangodb/tree/1.2.29) (2023-06-08)
- (Maintenance) Add govulncheck to pipeline, update golangci-linter

View file

@ -24,7 +24,7 @@ import "github.com/spf13/cobra"
func Register(cmd *cobra.Command) {
f := cmd.Flags()
f.StringVar(&input.Namespace, "namespace", "default", "Kubernetes namespace")
f.StringVarP(&input.Namespace, "namespace", "n", "default", "Kubernetes namespace")
f.BoolVar(&input.HideSensitiveData, "hide-sensitive-data", true, "Hide sensitive data")
f.BoolVar(&input.PodLogs, "pod-logs", true, "Collect pod logs")
}

View file

@ -51,7 +51,7 @@ func agencyDump(logger zerolog.Logger, files chan<- shared.File) error {
return errors.Newf("Client is not initialised")
}
deployments, err := ListDeployments(k)
deployments, err := listArangoDeployments(k.Arango())()
if err != nil {
return err
}
@ -102,7 +102,7 @@ func discoverExecFunc() (ArangoOperatorExecFunc, error) {
return nil, errors.Newf("Client is not initialised")
}
pods, err := ListPods(k)
pods, err := listPods(k.Kubernetes())()
if err != nil {
return nil, err
}

View file

@ -30,6 +30,7 @@ import (
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/debug_package/cli"
"github.com/arangodb/kube-arangodb/pkg/debug_package/shared"
arangoClient "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
)
@ -38,20 +39,32 @@ func Deployments() shared.Factory {
return shared.NewFactory("deployments", true, deployments)
}
func listArangoDeployments(client arangoClient.Interface) func() ([]*api.ArangoDeployment, error) {
return func() ([]*api.ArangoDeployment, error) {
return ListObjects[*api.ArangoDeploymentList, *api.ArangoDeployment](context.Background(), client.DatabaseV1().ArangoDeployments(cli.GetInput().Namespace), func(result *api.ArangoDeploymentList) []*api.ArangoDeployment {
q := make([]*api.ArangoDeployment, len(result.Items))
for id, e := range result.Items {
q[id] = e.DeepCopy()
}
return q
})
}
}
func deployments(logger zerolog.Logger, files chan<- shared.File) error {
k, ok := kclient.GetDefaultFactory().Client()
if !ok {
return errors.Newf("Client is not initialised")
}
deployments, err := ListDeployments(k)
deploymentList, err := listArangoDeployments(k.Arango())()
if err != nil {
return err
}
deploymentList := deployments.AsList()
errDeployments := make([]error, len(deployments))
errDeployments := make([]error, len(deploymentList))
for id := range deploymentList {
errDeployments[id] = deployment(k, deploymentList[id], files)

View file

@ -21,8 +21,13 @@
package kubernetes
import (
"github.com/rs/zerolog"
"context"
"github.com/rs/zerolog"
core "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
"github.com/arangodb/kube-arangodb/pkg/debug_package/cli"
"github.com/arangodb/kube-arangodb/pkg/debug_package/shared"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
@ -32,26 +37,27 @@ func Events() shared.Factory {
return shared.NewFactory("kubernetes-events", true, events)
}
func listEvents(client kubernetes.Interface) func() ([]*core.Event, error) {
return func() ([]*core.Event, error) {
return ListObjects[*core.EventList, *core.Event](context.Background(), client.CoreV1().Events(cli.GetInput().Namespace), func(result *core.EventList) []*core.Event {
q := make([]*core.Event, len(result.Items))
for id, e := range result.Items {
q[id] = e.DeepCopy()
}
return q
})
}
}
func events(logger zerolog.Logger, files chan<- shared.File) error {
k, ok := kclient.GetDefaultFactory().Client()
if !ok {
return errors.Newf("Client is not initialised")
}
events, err := ListEvents(k)
if err != nil {
return err
}
files <- shared.NewYAMLFile("kubernetes/events.yaml", func() ([]interface{}, error) {
q := make([]interface{}, 0, len(events))
for _, e := range events {
q = append(q, e)
}
return q, nil
})
files <- shared.NewYAMLFile("kubernetes/events.yaml", listEvents(k.Kubernetes()))
return nil
}

View file

@ -0,0 +1,71 @@
//
// DISCLAIMER
//
// Copyright 2023 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 kubernetes
import (
"context"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
)
type ObjectList[T meta.Object] map[types.UID]T
func (d ObjectList[T]) AsList() []T {
list := make([]T, 0, len(d))
for _, p := range d {
list = append(list, p)
}
return list
}
func MapObjects[L k8sutil.ListContinue, T meta.Object](ctx context.Context, k k8sutil.ListAPI[L], extract func(result L) []T) (ObjectList[T], error) {
objects := ObjectList[T]{}
if err := k8sutil.APIList[L](ctx, k, meta.ListOptions{}, func(result L, err error) error {
if err != nil {
return err
}
for _, obj := range extract(result) {
obj.SetManagedFields(nil)
objects[obj.GetUID()] = obj
}
return nil
}); err != nil {
return nil, err
}
return objects, nil
}
func ListObjects[L k8sutil.ListContinue, T meta.Object](ctx context.Context, k k8sutil.ListAPI[L], extract func(result L) []T) ([]T, error) {
objects, err := MapObjects[L, T](ctx, k, extract)
if err != nil {
return nil, err
}
return objects.AsList(), nil
}

View file

@ -1,70 +0,0 @@
//
// DISCLAIMER
//
// Copyright 2023 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 kubernetes
import (
"context"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/debug_package/cli"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
)
type DeploymentList map[types.UID]*api.ArangoDeployment
func (d DeploymentList) AsList() []*api.ArangoDeployment {
deploymentList := make([]*api.ArangoDeployment, 0, len(d))
for _, p := range d {
deploymentList = append(deploymentList, p)
}
return deploymentList
}
func ListDeployments(k kclient.Client) (DeploymentList, error) {
deployments := DeploymentList{}
next := ""
for {
deps, err := k.Arango().DatabaseV1().ArangoDeployments(cli.GetInput().Namespace).List(context.Background(), meta.ListOptions{
Continue: next,
})
if err != nil {
return nil, err
}
for _, d := range deps.Items {
deployments[d.UID] = d.DeepCopy()
deployments[d.UID].ManagedFields = nil
}
if deps.Continue == "" {
break
}
next = deps.Continue
}
return deployments, nil
}

View file

@ -1,70 +0,0 @@
//
// DISCLAIMER
//
// Copyright 2023 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 kubernetes
import (
"context"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"github.com/arangodb/kube-arangodb/pkg/debug_package/cli"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
)
type EventList map[types.UID]*core.Event
func (d EventList) AsList() []*core.Event {
eventList := make([]*core.Event, 0, len(d))
for _, p := range d {
eventList = append(eventList, p)
}
return eventList
}
func ListEvents(k kclient.Client) (EventList, error) {
events := EventList{}
next := ""
for {
deps, err := k.Kubernetes().CoreV1().Events(cli.GetInput().Namespace).List(context.Background(), meta.ListOptions{
Continue: next,
})
if err != nil {
return nil, err
}
for _, d := range deps.Items {
events[d.UID] = d.DeepCopy()
events[d.UID].ManagedFields = nil
}
if deps.Continue == "" {
break
}
next = deps.Continue
}
return events, nil
}

View file

@ -1,70 +0,0 @@
//
// DISCLAIMER
//
// Copyright 2023 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 kubernetes
import (
"context"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"github.com/arangodb/kube-arangodb/pkg/debug_package/cli"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
)
type PodList map[types.UID]*core.Pod
func (d PodList) AsList() []*core.Pod {
podList := make([]*core.Pod, 0, len(d))
for _, p := range d {
podList = append(podList, p)
}
return podList
}
func ListPods(k kclient.Client) (PodList, error) {
pods := PodList{}
next := ""
for {
deps, err := k.Kubernetes().CoreV1().Pods(cli.GetInput().Namespace).List(context.Background(), meta.ListOptions{
Continue: next,
})
if err != nil {
return nil, err
}
for _, d := range deps.Items {
pods[d.UID] = d.DeepCopy()
pods[d.UID].ManagedFields = nil
}
if deps.Continue == "" {
break
}
next = deps.Continue
}
return pods, nil
}

View file

@ -1,70 +0,0 @@
//
// DISCLAIMER
//
// Copyright 2023 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 kubernetes
import (
"context"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"github.com/arangodb/kube-arangodb/pkg/debug_package/cli"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
)
type SecretList map[types.UID]*core.Secret
func (d SecretList) AsList() []*core.Secret {
secretList := make([]*core.Secret, 0, len(d))
for _, p := range d {
secretList = append(secretList, p)
}
return secretList
}
func ListSecrets(k kclient.Client) (SecretList, error) {
secrets := SecretList{}
next := ""
for {
deps, err := k.Kubernetes().CoreV1().Secrets(cli.GetInput().Namespace).List(context.Background(), meta.ListOptions{
Continue: next,
})
if err != nil {
return nil, err
}
for _, d := range deps.Items {
secrets[d.UID] = d.DeepCopy()
secrets[d.UID].ManagedFields = nil
}
if deps.Continue == "" {
break
}
next = deps.Continue
}
return secrets, nil
}

View file

@ -1,70 +0,0 @@
//
// DISCLAIMER
//
// Copyright 2023 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 kubernetes
import (
"context"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"github.com/arangodb/kube-arangodb/pkg/debug_package/cli"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
)
type ServiceList map[types.UID]*core.Service
func (d ServiceList) AsList() []*core.Service {
serviceList := make([]*core.Service, 0, len(d))
for _, p := range d {
serviceList = append(serviceList, p)
}
return serviceList
}
func ListServices(k kclient.Client) (ServiceList, error) {
services := ServiceList{}
next := ""
for {
deps, err := k.Kubernetes().CoreV1().Services(cli.GetInput().Namespace).List(context.Background(), meta.ListOptions{
Continue: next,
})
if err != nil {
return nil, err
}
for _, d := range deps.Items {
services[d.UID] = d.DeepCopy()
services[d.UID].ManagedFields = nil
}
if deps.Continue == "" {
break
}
next = deps.Continue
}
return services, nil
}

View file

@ -27,6 +27,7 @@ import (
"github.com/rs/zerolog"
core "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
"github.com/arangodb/kube-arangodb/pkg/debug_package/cli"
"github.com/arangodb/kube-arangodb/pkg/debug_package/shared"
@ -38,31 +39,37 @@ func Pods() shared.Factory {
return shared.NewFactory("kubernetes-pods", true, pods)
}
func listPods(client kubernetes.Interface) func() ([]*core.Pod, error) {
return func() ([]*core.Pod, error) {
return ListObjects[*core.PodList, *core.Pod](context.Background(), client.CoreV1().Pods(cli.GetInput().Namespace), func(result *core.PodList) []*core.Pod {
q := make([]*core.Pod, len(result.Items))
for id, e := range result.Items {
q[id] = e.DeepCopy()
}
return q
})
}
}
func pods(logger zerolog.Logger, files chan<- shared.File) error {
k, ok := kclient.GetDefaultFactory().Client()
if !ok {
return errors.Newf("Client is not initialised")
}
pods, err := ListPods(k)
pods, err := listPods(k.Kubernetes())()
if err != nil {
return err
}
podsList := pods.AsList()
files <- shared.NewYAMLFile("kubernetes/pods.yaml", func() ([]interface{}, error) {
q := make([]interface{}, len(podsList))
for id := range podsList {
q[id] = podsList[id]
}
return q, nil
files <- shared.NewYAMLFile("kubernetes/pods.yaml", func() ([]*core.Pod, error) {
return pods, nil
})
if cli.GetInput().PodLogs {
if err := podsLogs(k, files, podsList...); err != nil {
if err := podsLogs(k, files, pods...); err != nil {
logger.Err(err).Msgf("Error while collecting pod logs")
}
}

View file

@ -21,8 +21,13 @@
package kubernetes
import (
"github.com/rs/zerolog"
"context"
"github.com/rs/zerolog"
core "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
"github.com/arangodb/kube-arangodb/pkg/debug_package/cli"
"github.com/arangodb/kube-arangodb/pkg/debug_package/shared"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
@ -32,26 +37,27 @@ func Secrets() shared.Factory {
return shared.NewFactory("kubernetes-secrets", true, secrets)
}
func listSecrets(client kubernetes.Interface) func() ([]*core.Secret, error) {
return func() ([]*core.Secret, error) {
return ListObjects[*core.SecretList, *core.Secret](context.Background(), client.CoreV1().Secrets(cli.GetInput().Namespace), func(result *core.SecretList) []*core.Secret {
q := make([]*core.Secret, len(result.Items))
for id, e := range result.Items {
q[id] = e.DeepCopy()
}
return q
})
}
}
func secrets(logger zerolog.Logger, files chan<- shared.File) error {
k, ok := kclient.GetDefaultFactory().Client()
if !ok {
return errors.Newf("Client is not initialised")
}
secrets, err := ListSecrets(k)
if err != nil {
return err
}
files <- shared.NewYAMLFile("kubernetes/secrets.yaml", func() ([]interface{}, error) {
q := make([]interface{}, 0, len(secrets))
for _, e := range secrets {
q = append(q, e)
}
return q, nil
})
files <- shared.NewYAMLFile("kubernetes/secrets.yaml", listSecrets(k.Kubernetes()))
return nil
}

View file

@ -25,8 +25,11 @@ import (
"fmt"
"github.com/rs/zerolog"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"github.com/arangodb/kube-arangodb/pkg/debug_package/cli"
"github.com/arangodb/kube-arangodb/pkg/debug_package/shared"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
@ -36,25 +39,33 @@ func Services() shared.Factory {
return shared.NewFactory("kubernetes-services", true, services)
}
func listServices(client kubernetes.Interface) func() ([]*core.Service, error) {
return func() ([]*core.Service, error) {
return ListObjects[*core.ServiceList, *core.Service](context.Background(), client.CoreV1().Services(cli.GetInput().Namespace), func(result *core.ServiceList) []*core.Service {
q := make([]*core.Service, len(result.Items))
for id, e := range result.Items {
q[id] = e.DeepCopy()
}
return q
})
}
}
func services(logger zerolog.Logger, files chan<- shared.File) error {
k, ok := kclient.GetDefaultFactory().Client()
if !ok {
return errors.Newf("Client is not initialised")
}
services, err := ListServices(k)
services, err := listServices(k.Kubernetes())()
if err != nil {
return err
}
files <- shared.NewYAMLFile("kubernetes/services.yaml", func() ([]interface{}, error) {
q := make([]interface{}, 0, len(services))
for _, e := range services {
q = append(q, e)
}
return q, nil
files <- shared.NewYAMLFile("kubernetes/services.yaml", func() ([]*core.Service, error) {
return services, nil
})
for _, svc := range services {

View file

@ -25,7 +25,6 @@ import (
"encoding/json"
"github.com/rs/zerolog"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
)
@ -36,34 +35,18 @@ type File interface {
Write() ([]byte, error)
}
func NewJSONFile(path string, write func() ([]interface{}, error)) File {
func NewJSONFile[T interface{}](path string, write func() ([]T, error)) File {
return NewFile(path, func() ([]byte, error) {
obj, err := write()
if err != nil {
return nil, err
}
for z := range obj {
obj[z] = cleanObject(&obj[z])
}
return json.Marshal(obj)
})
}
func cleanObject(obj interface{}) interface{} {
if obj == nil {
return nil
}
if v, ok := obj.(meta.Object); ok {
v.SetManagedFields(nil)
}
return obj
}
func NewYAMLFile(path string, write func() ([]interface{}, error)) File {
func NewYAMLFile[T interface{}](path string, write func() ([]T, error)) File {
return NewFile(path, func() ([]byte, error) {
obj, err := write()
if err != nil {
@ -72,10 +55,6 @@ func NewYAMLFile(path string, write func() ([]interface{}, error)) File {
buff := bytes.NewBuffer(nil)
for z := range obj {
obj[z] = cleanObject(&obj[z])
}
for z := range obj {
d, err := yaml.Marshal(obj[z])
if err != nil {

View file

@ -110,7 +110,7 @@ func (s *simpleStateLoader[T]) Refresh(ctx context.Context, discovery agencyCach
return err
}
if s.index != cfg.CommitIndex {
if !s.valid || s.index != cfg.CommitIndex {
// Full reload
state, err := GetAgencyState[T](ctx, conn)
if err != nil {