mirror of
				https://github.com/1Password/onepassword-operator.git
				synced 2025-10-31 11:49:40 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			142 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package kube
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"encoding/base64"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"time"
 | |
| 
 | |
| 	//nolint:staticcheck // ST1001
 | |
| 	. "github.com/onsi/ginkgo/v2"
 | |
| 	//nolint:staticcheck // ST1001
 | |
| 	. "github.com/onsi/gomega"
 | |
| 	corev1 "k8s.io/api/core/v1"
 | |
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | |
| 	"sigs.k8s.io/controller-runtime/pkg/client"
 | |
| 
 | |
| 	"github.com/1Password/onepassword-operator/pkg/testhelper/system"
 | |
| )
 | |
| 
 | |
| type Secret struct {
 | |
| 	client client.Client
 | |
| 	config *Config
 | |
| 	name   string
 | |
| }
 | |
| 
 | |
| // CreateFromEnvVar creates a kubernetes secret from an environment variable
 | |
| func (s *Secret) CreateFromEnvVar(ctx context.Context, envVar string) *corev1.Secret {
 | |
| 	By("Creating '" + s.name + "' secret from environment variable")
 | |
| 
 | |
| 	// Derive a short-lived context so this API call won't hang indefinitely.
 | |
| 	c, cancel := context.WithTimeout(ctx, 10*time.Second)
 | |
| 	defer cancel()
 | |
| 
 | |
| 	value, ok := os.LookupEnv(envVar)
 | |
| 	Expect(ok).To(BeTrue())
 | |
| 	Expect(value).NotTo(BeEmpty())
 | |
| 
 | |
| 	secret := &corev1.Secret{
 | |
| 		ObjectMeta: metav1.ObjectMeta{
 | |
| 			Name:      s.name,
 | |
| 			Namespace: s.config.Namespace,
 | |
| 		},
 | |
| 		StringData: map[string]string{
 | |
| 			"token": value,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	err := s.client.Create(c, secret)
 | |
| 	Expect(err).NotTo(HaveOccurred())
 | |
| 
 | |
| 	return secret
 | |
| }
 | |
| 
 | |
| // CreateFromFile creates a kubernetes secret from a file
 | |
| func (s *Secret) CreateFromFile(ctx context.Context, fileName string, content []byte) *corev1.Secret {
 | |
| 	By("Creating '" + s.name + "' secret from file " + fileName)
 | |
| 
 | |
| 	// Derive a short-lived context so this API call won't hang indefinitely.
 | |
| 	c, cancel := context.WithTimeout(ctx, 10*time.Second)
 | |
| 	defer cancel()
 | |
| 
 | |
| 	secret := &corev1.Secret{
 | |
| 		ObjectMeta: metav1.ObjectMeta{
 | |
| 			Name:      s.name,
 | |
| 			Namespace: s.config.Namespace,
 | |
| 		},
 | |
| 		Data: map[string][]byte{
 | |
| 			filepath.Base(fileName): content,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	err := s.client.Create(c, secret)
 | |
| 	Expect(err).NotTo(HaveOccurred())
 | |
| 
 | |
| 	return secret
 | |
| }
 | |
| 
 | |
| // CreateOpCredentials creates a kubernetes secret from 1password-credentials.json file in the project root
 | |
| // encodes it in base64 and saves it to op-session file
 | |
| func (s *Secret) CreateOpCredentials(ctx context.Context) *corev1.Secret {
 | |
| 	rootDir, err := system.GetProjectRoot()
 | |
| 	Expect(err).NotTo(HaveOccurred())
 | |
| 
 | |
| 	credentialsFilePath := filepath.Join(rootDir, "1password-credentials.json")
 | |
| 	data, err := os.ReadFile(credentialsFilePath)
 | |
| 	Expect(err).NotTo(HaveOccurred())
 | |
| 
 | |
| 	encoded := base64.RawURLEncoding.EncodeToString(data)
 | |
| 
 | |
| 	return s.CreateFromFile(ctx, "op-session", []byte(encoded))
 | |
| }
 | |
| 
 | |
| // Get retrieves a kubernetes secret
 | |
| func (s *Secret) Get(ctx context.Context) *corev1.Secret {
 | |
| 	By("Getting '" + s.name + "' secret")
 | |
| 
 | |
| 	// Derive a short-lived context so this API call won't hang indefinitely.
 | |
| 	c, cancel := context.WithTimeout(ctx, 10*time.Second)
 | |
| 	defer cancel()
 | |
| 
 | |
| 	secret := &corev1.Secret{}
 | |
| 	err := s.client.Get(c, client.ObjectKey{Name: s.name, Namespace: s.config.Namespace}, secret)
 | |
| 	Expect(err).NotTo(HaveOccurred())
 | |
| 
 | |
| 	return secret
 | |
| }
 | |
| 
 | |
| // Delete deletes a kubernetes secret
 | |
| func (s *Secret) Delete(ctx context.Context) {
 | |
| 	By("Deleting '" + s.name + "' secret")
 | |
| 
 | |
| 	// Derive a short-lived context so this API call won't hang indefinitely.
 | |
| 	c, cancel := context.WithTimeout(ctx, 10*time.Second)
 | |
| 	defer cancel()
 | |
| 
 | |
| 	secret := &corev1.Secret{
 | |
| 		ObjectMeta: metav1.ObjectMeta{
 | |
| 			Name:      s.name,
 | |
| 			Namespace: s.config.Namespace,
 | |
| 		},
 | |
| 	}
 | |
| 	err := s.client.Delete(c, secret)
 | |
| 	Expect(err).NotTo(HaveOccurred())
 | |
| }
 | |
| 
 | |
| // CheckIfExists repeatedly attempts to retrieve the given Secret
 | |
| // from the cluster until it is found or the test's timeout expires.
 | |
| func (s *Secret) CheckIfExists(ctx context.Context) {
 | |
| 	By("Checking '" + s.name + "' secret")
 | |
| 
 | |
| 	Eventually(func(g Gomega) {
 | |
| 		// Derive a short-lived context so this API call won't hang indefinitely.
 | |
| 		attemptCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
 | |
| 		defer cancel()
 | |
| 
 | |
| 		secret := &corev1.Secret{}
 | |
| 		err := s.client.Get(attemptCtx, client.ObjectKey{Name: s.name, Namespace: s.config.Namespace}, secret)
 | |
| 		g.Expect(err).NotTo(HaveOccurred())
 | |
| 	}, s.config.TestConfig.Timeout, s.config.TestConfig.Interval).Should(Succeed())
 | |
| }
 | 
