Skip to content

Commit

Permalink
add-namespace-utils
Browse files Browse the repository at this point in the history
  • Loading branch information
fabriziopandini committed Apr 10, 2020
1 parent efe6b70 commit 5a0a11c
Showing 1 changed file with 118 additions and 0 deletions.
118 changes: 118 additions & 0 deletions test/framework/management_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,20 @@ package framework
import (
"context"
"fmt"
"os"
"path"
"path/filepath"
"time"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
"sigs.k8s.io/cluster-api/util"
"sigs.k8s.io/controller-runtime/pkg/client"

"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -158,3 +167,112 @@ func WaitForDeploymentsAvailable(ctx context.Context, input WaitForDeploymentsAv

}, intervals...).Should(BeTrue(), "Deployment %s/%s failed to get status.Available = True condition", input.Deployment.GetNamespace(), input.Deployment.GetName())
}

// CreateNamespaceInput is the input type for CreateNamespace.
type CreateNamespaceInput struct {
Creator Creator
Name string
}

// CreateNamespace is used to create a namespace object.
// If name is empty, a "test-" + util.RandomString(6) name will be generated.
func CreateNamespace(ctx context.Context, input CreateNamespaceInput, intervals ...interface{}) *corev1.Namespace {
Expect(ctx).NotTo(BeNil(), "ctx is required for DeleteNamespace")
Expect(input.Creator).NotTo(BeNil(), "input.Creator is required for CreateNamespace")
if input.Name == "" {
input.Name = fmt.Sprintf("test-%s", util.RandomString(6))
}

ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: input.Name,
},
}
By(fmt.Sprintf("Creating namespace %s", input.Name))
Eventually(func() error {
return input.Creator.Create(context.TODO(), ns)
}, intervals...).Should(Succeed())

return ns
}

// DeleteNamespaceInput is the input type for DeleteNamespace.
type DeleteNamespaceInput struct {
Deleter Deleter
Name string
}

// DeleteNamespace is used to delete namespace object.
func DeleteNamespace(ctx context.Context, input DeleteNamespaceInput, intervals ...interface{}) {
Expect(ctx).NotTo(BeNil(), "ctx is required for DeleteNamespace")
Expect(input.Deleter).NotTo(BeNil(), "input.Deleter is required for DeleteNamespace")
Expect(input.Name).NotTo(BeEmpty(), "input.Name is required for DeleteNamespace")
ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: input.Name,
},
}
By(fmt.Sprintf("Deleting namespace %s", input.Name))
Eventually(func() error {
return input.Deleter.Delete(context.TODO(), ns)
}, intervals...).Should(Succeed())
}

// WatchNamespaceEventsInput is the input type for WatchNamespaceEvents.
type WatchNamespaceEventsInput struct {
ClientSet *kubernetes.Clientset
Name string
LogPath string
}

// WatchNamespaceEvents creates a watcher that streams namespace events into a file.
// Example usage:
// ctx, cancelWatches := context.WithCancel(context.Background())
// go func() {
// defer GinkgoRecover()
// framework.WatchNamespaceEvents(ctx, framework.WatchNamespaceEventsInput{
// ClientSet: clientSet,
// Name: namespace.Name,
// LogPath: logPath,
// })
// }()
// defer cancelWatches()
func WatchNamespaceEvents(ctx context.Context, input WatchNamespaceEventsInput) {
Expect(ctx).NotTo(BeNil(), "ctx is required for WatchNamespaceEvents")
Expect(input.ClientSet).NotTo(BeNil(), "input.ClientSet is required for WatchNamespaceEvents")
Expect(input.Name).NotTo(BeEmpty(), "input.Name is required for WatchNamespaceEvents")

logFile := path.Join(input.LogPath, "resources", input.Name, "events.log")
fmt.Fprintf(GinkgoWriter, "Creating directory: %s\n", filepath.Dir(logFile))
Expect(os.MkdirAll(filepath.Dir(logFile), 0755)).To(Succeed())

f, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
Expect(err).NotTo(HaveOccurred())
defer f.Close()

informerFactory := informers.NewSharedInformerFactoryWithOptions(
input.ClientSet,
10*time.Minute,
informers.WithNamespace(input.Name),
)
eventInformer := informerFactory.Core().V1().Events().Informer()
eventInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
e := obj.(*corev1.Event)
f.WriteString(fmt.Sprintf("[New Event] %s/%s\n\tresource: %s/%s/%s\n\treason: %s\n\tmessage: %s\n\tfull: %#v\n",
e.Namespace, e.Name, e.InvolvedObject.APIVersion, e.InvolvedObject.Kind, e.InvolvedObject.Name, e.Reason, e.Message, e))
},
UpdateFunc: func(_, obj interface{}) {
e := obj.(*corev1.Event)
f.WriteString(fmt.Sprintf("[Updated Event] %s/%s\n\tresource: %s/%s/%s\n\treason: %s\n\tmessage: %s\n\tfull: %#v\n",
e.Namespace, e.Name, e.InvolvedObject.APIVersion, e.InvolvedObject.Kind, e.InvolvedObject.Name, e.Reason, e.Message, e))
},
DeleteFunc: func(obj interface{}) {},
})

stopInformer := make(chan struct{})
defer close(stopInformer)
informerFactory.Start(stopInformer)
<-ctx.Done()
stopInformer <- struct{}{}
}

0 comments on commit 5a0a11c

Please sign in to comment.