mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-09-20 06:54:32 +00:00
exit server if not all Ark CRDs exist at startup
Signed-off-by: Steve Kriss <steve@heptio.com>
This commit is contained in:
+76
-16
@@ -38,6 +38,8 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
kubeerrs "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/dynamic"
|
||||
@@ -151,6 +153,7 @@ type server struct {
|
||||
snapshotService cloudprovider.SnapshotService
|
||||
discoveryClient discovery.DiscoveryInterface
|
||||
clientPool dynamic.ClientPool
|
||||
discoveryHelper arkdiscovery.Helper
|
||||
sharedInformerFactory informers.SharedInformerFactory
|
||||
ctx context.Context
|
||||
cancelFunc context.CancelFunc
|
||||
@@ -213,6 +216,15 @@ func (s *server) run() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.initDiscoveryHelper(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// check to ensure all Ark CRDs exist
|
||||
if err := s.arkResourcesExist(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
originalConfig, err := s.loadConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -259,6 +271,68 @@ func (s *server) namespaceExists(namespace string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// initDiscoveryHelper instantiates the server's discovery helper and spawns a
|
||||
// goroutine to call Refresh() every 5 minutes.
|
||||
func (s *server) initDiscoveryHelper() error {
|
||||
discoveryHelper, err := arkdiscovery.NewHelper(s.discoveryClient, s.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.discoveryHelper = discoveryHelper
|
||||
|
||||
go wait.Until(
|
||||
func() {
|
||||
if err := discoveryHelper.Refresh(); err != nil {
|
||||
s.logger.WithError(err).Error("Error refreshing discovery")
|
||||
}
|
||||
},
|
||||
5*time.Minute,
|
||||
s.ctx.Done(),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// arkResourcesExist checks for the existence of each Ark CRD via discovery
|
||||
// and returns an error if any of them don't exist.
|
||||
func (s *server) arkResourcesExist() error {
|
||||
s.logger.Info("Checking existence of Ark custom resource definitions")
|
||||
|
||||
var arkGroupVersion *metav1.APIResourceList
|
||||
for _, gv := range s.discoveryHelper.Resources() {
|
||||
if gv.GroupVersion == api.SchemeGroupVersion.String() {
|
||||
arkGroupVersion = gv
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if arkGroupVersion == nil {
|
||||
return errors.Errorf("Ark API group %s not found", api.SchemeGroupVersion)
|
||||
}
|
||||
|
||||
foundResources := sets.NewString()
|
||||
for _, resource := range arkGroupVersion.APIResources {
|
||||
foundResources.Insert(resource.Kind)
|
||||
}
|
||||
|
||||
var errs []error
|
||||
for kind := range api.CustomResources() {
|
||||
if foundResources.Has(kind) {
|
||||
s.logger.WithField("kind", kind).Debug("Found custom resource")
|
||||
continue
|
||||
}
|
||||
|
||||
errs = append(errs, errors.Errorf("custom resource %s not found in Ark API group %s", kind, api.SchemeGroupVersion))
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return kubeerrs.NewAggregate(errs)
|
||||
}
|
||||
|
||||
s.logger.Info("All Ark custom resource definitions exist")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) loadConfig() (*api.Config, error) {
|
||||
s.logger.Info("Retrieving Ark configuration")
|
||||
var (
|
||||
@@ -537,27 +611,13 @@ func (s *server) runControllers(config *api.Config) error {
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
discoveryHelper, err := arkdiscovery.NewHelper(s.discoveryClient, s.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go wait.Until(
|
||||
func() {
|
||||
if err := discoveryHelper.Refresh(); err != nil {
|
||||
s.logger.WithError(err).Error("Error refreshing discovery")
|
||||
}
|
||||
},
|
||||
5*time.Minute,
|
||||
ctx.Done(),
|
||||
)
|
||||
|
||||
if config.RestoreOnlyMode {
|
||||
s.logger.Info("Restore only mode - not starting the backup, schedule, delete-backup, or GC controllers")
|
||||
} else {
|
||||
backupTracker := controller.NewBackupTracker()
|
||||
|
||||
backupper, err := backup.NewKubernetesBackupper(
|
||||
discoveryHelper,
|
||||
s.discoveryHelper,
|
||||
client.NewDynamicFactory(s.clientPool),
|
||||
podexec.NewPodCommandExecutor(s.kubeClientConfig, s.kubeClient.CoreV1().RESTClient()),
|
||||
s.snapshotService,
|
||||
@@ -633,7 +693,7 @@ func (s *server) runControllers(config *api.Config) error {
|
||||
}
|
||||
|
||||
restorer, err := restore.NewKubernetesRestorer(
|
||||
discoveryHelper,
|
||||
s.discoveryHelper,
|
||||
client.NewDynamicFactory(s.clientPool),
|
||||
s.backupService,
|
||||
s.snapshotService,
|
||||
|
||||
@@ -22,6 +22,8 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
arktest "github.com/heptio/ark/pkg/util/test"
|
||||
)
|
||||
@@ -51,3 +53,47 @@ func TestApplyConfigDefaults(t *testing.T) {
|
||||
assert.Equal(t, 3*time.Minute, c.ScheduleSyncPeriod.Duration)
|
||||
assert.Equal(t, []string{"a", "b"}, c.ResourcePriorities)
|
||||
}
|
||||
|
||||
func TestArkResourcesExist(t *testing.T) {
|
||||
var (
|
||||
fakeDiscoveryHelper = &arktest.FakeDiscoveryHelper{}
|
||||
server = &server{
|
||||
logger: arktest.NewLogger(),
|
||||
discoveryHelper: fakeDiscoveryHelper,
|
||||
}
|
||||
)
|
||||
|
||||
// Ark API group doesn't exist in discovery: should error
|
||||
fakeDiscoveryHelper.ResourceList = []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "foo/v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Name: "Backups",
|
||||
Kind: "Backup",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.Error(t, server.arkResourcesExist())
|
||||
|
||||
// Ark API group doesn't contain any custom resources: should error
|
||||
arkAPIResourceList := &metav1.APIResourceList{
|
||||
GroupVersion: v1.SchemeGroupVersion.String(),
|
||||
}
|
||||
|
||||
fakeDiscoveryHelper.ResourceList = append(fakeDiscoveryHelper.ResourceList, arkAPIResourceList)
|
||||
assert.Error(t, server.arkResourcesExist())
|
||||
|
||||
// Ark API group contains all custom resources: should not error
|
||||
for kind := range v1.CustomResources() {
|
||||
arkAPIResourceList.APIResources = append(arkAPIResourceList.APIResources, metav1.APIResource{
|
||||
Kind: kind,
|
||||
})
|
||||
}
|
||||
assert.NoError(t, server.arkResourcesExist())
|
||||
|
||||
// Ark API group contains some but not all custom resources: should error
|
||||
arkAPIResourceList.APIResources = arkAPIResourceList.APIResources[:3]
|
||||
assert.Error(t, server.arkResourcesExist())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user