1
0
mirror of synced 2026-04-14 18:56:56 +00:00

Add flux create secret receiver command

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
This commit is contained in:
Stefan Prodan
2026-04-10 12:09:42 +03:00
parent 3d4eec61fe
commit 02734f28ba
10 changed files with 377 additions and 3 deletions

View File

@@ -42,6 +42,12 @@ const (
KnownHostsSecretKey = "known_hosts"
BearerTokenKey = "bearerToken"
TrustPolicyKey = "trustpolicy.json"
TokenSecretKey = "token"
EmailSecretKey = "email"
AudienceSecretKey = "audience"
// WebhookURLAnnotation is the annotation key for the computed webhook URL.
WebhookURLAnnotation = "notification.toolkit.fluxcd.io/webhook"
// Deprecated: Replaced by CACrtSecretKey, but kept for backwards
// compatibility with deprecated TLS flags.
@@ -82,6 +88,12 @@ type Options struct {
GitHubAppInstallationID string
GitHubAppPrivateKey string
GitHubAppBaseURL string
// Receiver options
ReceiverType string
Token string
Hostname string
EmailClaim string
}
type VerificationCrt struct {

View File

@@ -18,7 +18,10 @@ package sourcesecret
import (
"bytes"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"net"
@@ -260,6 +263,55 @@ func GenerateGitHubApp(options Options) (*manifestgen.Manifest, error) {
return secretToManifest(secret, options)
}
func GenerateReceiver(options Options) (*manifestgen.Manifest, error) {
token := options.Token
if token == "" {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
return nil, fmt.Errorf("failed to generate random token: %w", err)
}
token = hex.EncodeToString(b)
}
if options.Hostname == "" {
return nil, fmt.Errorf("hostname is required")
}
// Compute the webhook path using the same algorithm as notification-controller.
// See: github.com/fluxcd/notification-controller/api/v1.Receiver.GetWebhookPath
digest := sha256.Sum256([]byte(token + options.Name + options.Namespace))
webhookPath := fmt.Sprintf("/hook/%x", digest)
webhookURL := fmt.Sprintf("https://%s%s", options.Hostname, webhookPath)
secret := &corev1.Secret{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Secret",
},
ObjectMeta: metav1.ObjectMeta{
Name: options.Name,
Namespace: options.Namespace,
Labels: options.Labels,
Annotations: map[string]string{
WebhookURLAnnotation: webhookURL,
},
},
StringData: map[string]string{
TokenSecretKey: token,
},
}
if options.ReceiverType == "gcr" {
if options.EmailClaim == "" {
return nil, fmt.Errorf("email-claim is required for gcr receiver type")
}
secret.StringData[EmailSecretKey] = options.EmailClaim
secret.StringData[AudienceSecretKey] = webhookURL
}
return secretToManifest(secret, options)
}
func LoadKeyPairFromPath(path, password string) (*ssh.KeyPair, error) {
if path == "" {
return nil, nil