mirror of
https://github.com/fluxcd/flux2.git
synced 2026-02-24 08:31:47 +00:00
logs since tests
Signed-off-by: Tomas Tulka <tomas.tulka@gmail.com>
This commit is contained in:
parent
f3dd2122be
commit
2db8753fc7
4 changed files with 95 additions and 12 deletions
|
|
@ -36,7 +36,6 @@ import (
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util"
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/flags"
|
"github.com/fluxcd/flux2/internal/flags"
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var logsCmd = &cobra.Command{
|
var logsCmd = &cobra.Command{
|
||||||
|
|
@ -96,13 +95,7 @@ func logsCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
var pods []corev1.Pod
|
clientset, err := rootCtx.kubeManager.NewClientset(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
clientset, err := kubernetes.NewForConfig(cfg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -111,6 +104,7 @@ func logsCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
return fmt.Errorf("no argument required")
|
return fmt.Errorf("no argument required")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pods []corev1.Pod
|
||||||
pods, err = getPods(ctx, clientset, fluxSelector)
|
pods, err = getPods(ctx, clientset, fluxSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -131,7 +125,7 @@ func logsCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
if len(logsArgs.sinceTime) > 0 {
|
if len(logsArgs.sinceTime) > 0 {
|
||||||
t, err := util.ParseRFC3339(logsArgs.sinceTime, metav1.Now)
|
t, err := util.ParseRFC3339(logsArgs.sinceTime, metav1.Now)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("%s is not a valid (RFC3339) time", logsArgs.sinceTime)
|
||||||
}
|
}
|
||||||
logOpts.SinceTime = &t
|
logOpts.SinceTime = &t
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +149,7 @@ func logsCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
return podLogs(ctx, requests)
|
return podLogs(ctx, requests)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPods(ctx context.Context, c *kubernetes.Clientset, label string) ([]corev1.Pod, error) {
|
func getPods(ctx context.Context, c kubernetes.Interface, label string) ([]corev1.Pod, error) {
|
||||||
var ret []corev1.Pod
|
var ret []corev1.Pod
|
||||||
|
|
||||||
opts := metav1.ListOptions{
|
opts := metav1.ListOptions{
|
||||||
|
|
|
||||||
64
cmd/flux/logs_test.go
Normal file
64
cmd/flux/logs_test.go
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLogsNoArgs(t *testing.T) {
|
||||||
|
cmd := cmdTestCase{
|
||||||
|
args: "logs",
|
||||||
|
wantError: false,
|
||||||
|
}
|
||||||
|
cmd.runTestCmd(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLogsAllNamespaces(t *testing.T) {
|
||||||
|
cmd := cmdTestCase{
|
||||||
|
args: "logs --all-namespaces",
|
||||||
|
wantError: false,
|
||||||
|
}
|
||||||
|
cmd.runTestCmd(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLogsSince(t *testing.T) {
|
||||||
|
cmd := cmdTestCase{
|
||||||
|
args: "logs --since=2m",
|
||||||
|
wantError: false,
|
||||||
|
}
|
||||||
|
cmd.runTestCmd(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLogsSinceInvalid(t *testing.T) {
|
||||||
|
cmd := cmdTestCase{
|
||||||
|
args: "logs --since=XXX",
|
||||||
|
wantError: true,
|
||||||
|
goldenValue: `invalid argument "XXX" for "--since" flag: time: invalid duration "XXX"`,
|
||||||
|
}
|
||||||
|
cmd.runTestCmd(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLogsSinceTime(t *testing.T) {
|
||||||
|
cmd := cmdTestCase{
|
||||||
|
args: "logs --since-time=2021-08-06T14:26:25.546Z",
|
||||||
|
wantError: false,
|
||||||
|
}
|
||||||
|
cmd.runTestCmd(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLogsSinceTimeInvalid(t *testing.T) {
|
||||||
|
cmd := cmdTestCase{
|
||||||
|
args: "logs --since-time=XXX",
|
||||||
|
wantError: true,
|
||||||
|
goldenValue: "XXX is not a valid (RFC3339) time",
|
||||||
|
}
|
||||||
|
cmd.runTestCmd(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLogsSinceOnlyOneAllowed(t *testing.T) {
|
||||||
|
cmd := cmdTestCase{
|
||||||
|
args: "logs --since=2m --since-time=2021-08-06T14:26:25.546Z",
|
||||||
|
wantError: true,
|
||||||
|
goldenValue: "at most one of `sinceTime` or `sinceSeconds` may be specified",
|
||||||
|
}
|
||||||
|
cmd.runTestCmd(t)
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,8 @@ import (
|
||||||
"github.com/mattn/go-shellwords"
|
"github.com/mattn/go-shellwords"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
|
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
fakeclientset "k8s.io/client-go/kubernetes/fake"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||||
)
|
)
|
||||||
|
|
@ -50,13 +52,18 @@ func readYamlObjects(objectFile string) ([]client.Object, error) {
|
||||||
|
|
||||||
// A KubeManager that can create objects that are subject to a test.
|
// A KubeManager that can create objects that are subject to a test.
|
||||||
type fakeKubeManager struct {
|
type fakeKubeManager struct {
|
||||||
fakeClient client.WithWatch
|
fakeClient client.WithWatch
|
||||||
|
fakeClientset kubernetes.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fakeKubeManager) NewClient(kubeconfig string, kubecontext string) (client.WithWatch, error) {
|
func (m *fakeKubeManager) NewClient(kubeconfig string, kubecontext string) (client.WithWatch, error) {
|
||||||
return m.fakeClient, nil
|
return m.fakeClient, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *fakeKubeManager) NewClientset(kubeconfig string, kubecontext string) (kubernetes.Interface, error) {
|
||||||
|
return m.fakeClientset, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *fakeKubeManager) CreateObjects(clientObjects []client.Object) error {
|
func (m *fakeKubeManager) CreateObjects(clientObjects []client.Object) error {
|
||||||
for _, obj := range clientObjects {
|
for _, obj := range clientObjects {
|
||||||
err := m.fakeClient.Create(context.Background(), obj)
|
err := m.fakeClient.Create(context.Background(), obj)
|
||||||
|
|
@ -69,8 +76,10 @@ func (m *fakeKubeManager) CreateObjects(clientObjects []client.Object) error {
|
||||||
|
|
||||||
func NewFakeKubeManager() *fakeKubeManager {
|
func NewFakeKubeManager() *fakeKubeManager {
|
||||||
c := fakeclient.NewClientBuilder().WithScheme(utils.NewScheme()).Build()
|
c := fakeclient.NewClientBuilder().WithScheme(utils.NewScheme()).Build()
|
||||||
|
cs := fakeclientset.NewSimpleClientset()
|
||||||
return &fakeKubeManager{
|
return &fakeKubeManager{
|
||||||
fakeClient: c,
|
fakeClient: c,
|
||||||
|
fakeClientset: cs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import (
|
||||||
apiruntime "k8s.io/apimachinery/pkg/runtime"
|
apiruntime "k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
sigyaml "k8s.io/apimachinery/pkg/util/yaml"
|
sigyaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
@ -135,6 +136,7 @@ func KubeConfig(kubeConfigPath string, kubeContext string) (*rest.Config, error)
|
||||||
// facilitate unit testing and provide a fake client.
|
// facilitate unit testing and provide a fake client.
|
||||||
type KubeManager interface {
|
type KubeManager interface {
|
||||||
NewClient(string, string) (client.WithWatch, error)
|
NewClient(string, string) (client.WithWatch, error)
|
||||||
|
NewClientset(string, string) (kubernetes.Interface, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type defaultKubeManager struct{}
|
type defaultKubeManager struct{}
|
||||||
|
|
@ -161,6 +163,20 @@ func (m defaultKubeManager) NewClient(kubeConfigPath string, kubeContext string)
|
||||||
return kubeClient, nil
|
return kubeClient, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m defaultKubeManager) NewClientset(kubeConfigPath string, kubeContext string) (kubernetes.Interface, error) {
|
||||||
|
cfg, err := KubeConfig(kubeConfigPath, kubeContext)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("kubernetes clientset initialization failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
clientset, err := kubernetes.NewForConfig(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("kubernetes clientset initialization failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return clientset, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Create the Scheme, methods for serializing and deserializing API objects
|
// Create the Scheme, methods for serializing and deserializing API objects
|
||||||
// which can be shared by tests.
|
// which can be shared by tests.
|
||||||
func NewScheme() *apiruntime.Scheme {
|
func NewScheme() *apiruntime.Scheme {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue