@@ -2,81 +2,92 @@ package common
22
33import (
44 "context"
5- "sync "
5+ "fmt "
66
7+ "github.com/awnumar/memguard"
78 corev1 "k8s.io/api/core/v1"
89 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+ "k8s.io/apimachinery/pkg/types"
11+ "sigs.k8s.io/controller-runtime/pkg/client"
912)
1013
11- type SecretResource struct {
12- secret * corev1.Secret
13- once sync.Once
14+ type LockedBufferSecret struct {
15+ metav1.TypeMeta `json:",inline"`
16+ metav1.ObjectMeta `json:"metadata,omitempty"`
17+ LockedData SecretMap `json:"lockedData,omitempty"`
1418}
1519
16- type WaitableSecretResource struct {
17- * SecretResource
18- wg sync.WaitGroup
19- }
20+ type SecretMap map [string ]* memguard.LockedBuffer
2021
21- // Creates a Secret that clears it's data when recCtx is canceled
22- func NewSecret (recCtx context.Context , name , namespace string ) * corev1.Secret {
23- secretResource := NewSecretResource (name , namespace )
24- go func () {
25- <- recCtx .Done ()
26- secretResource .Clear (nil )
27- }()
28- return secretResource .GetSecret ()
22+ func (sm SecretMap ) Destroy () {
23+ for _ , buf := range sm {
24+ buf .Destroy ()
25+ }
2926}
3027
31- func NewWaitableSecret (recCtx context.Context , name , namespace string ) (* corev1.Secret , * sync.WaitGroup ) {
32- waitableSecretResource := NewWaitableSecretResource (name , namespace )
33- go func () {
34- <- recCtx .Done ()
35- waitableSecretResource .Clear (waitableSecretResource .GetWaitGroup ())
36- }()
37- return waitableSecretResource .GetSecret (), waitableSecretResource .GetWaitGroup ()
28+ func (sm SecretMap ) Get (key string ) ([]byte , bool ) {
29+ if buf , found := sm [key ]; found {
30+ return buf .Bytes (), true
31+ }
32+ return []byte {}, false
3833}
3934
40- func NewSecretResource (name , namespace string ) * SecretResource {
41- resource := & SecretResource {
42- secret : & corev1.Secret {
43- ObjectMeta : metav1.ObjectMeta {
44- Name : name ,
45- Namespace : namespace ,
46- },
47- },
35+ func (lockedBufferSecret LockedBufferSecret ) Destroy () {
36+ if lockedBufferSecret .LockedData != nil {
37+ lockedBufferSecret .LockedData .Destroy ()
4838 }
49- return resource
5039}
5140
52- func NewWaitableSecretResource (name , namespace string ) * WaitableSecretResource {
53- resource := & WaitableSecretResource {
54- SecretResource : NewSecretResource (name , namespace ),
55- wg : sync.WaitGroup {},
41+ // Gets a Secret from the k8s client loaded as a LockedBufferSecret
42+ func GetSecret (client client.Client , name string , ns string ) (* LockedBufferSecret , error ) {
43+ if client == nil {
44+ return nil , fmt .Errorf ("the reconciler client could not be found" )
45+ }
46+ secret := & corev1.Secret {}
47+ secret .Name = name
48+ secret .Namespace = ns
49+ err := client .Get (context .TODO (), types.NamespacedName {Name : name , Namespace : ns }, secret )
50+ if err != nil {
51+ return nil , err
5652 }
57- return resource
58- }
5953
60- func (wsr * WaitableSecretResource ) GetWaitGroup () * sync.WaitGroup {
61- return & wsr .wg
54+ lockedBufferSecret := & LockedBufferSecret {}
55+ lockedBufferSecret .TypeMeta = secret .TypeMeta
56+ lockedBufferSecret .ObjectMeta = secret .ObjectMeta
57+ for secretKey , secretValue := range secret .Data {
58+ lockedBufferSecret .LockedData [secretKey ] = memguard .NewBufferFromBytes (secretValue )
59+ }
60+ return lockedBufferSecret , nil
6261}
6362
64- func (r * SecretResource ) GetSecret () * corev1.Secret {
65- return r .secret
63+ // Copies a Locked Buffer Secret into a core Secret with a corresponding cleanup func
64+ func CopySecret (in * LockedBufferSecret , out * corev1.Secret ) func () {
65+ out .TypeMeta = in .TypeMeta
66+ out .ObjectMeta = in .ObjectMeta
67+ for key , buf := range in .LockedData {
68+ out .Data [key ] = buf .Bytes ()
69+ }
70+ return func () {
71+ for key := range out .Data {
72+ delete (out .Data , key )
73+ }
74+ out .Data = nil
75+ }
6676}
6777
68- func (r * SecretResource ) Clear (wg * sync.WaitGroup ) {
69- if r .secret == nil {
70- return
78+ // Returns the client.Get status of Secret name in namespace ns after clearing sensitive byte array content
79+ func CheckSecret (client client.Client , name string , ns string ) error {
80+ if client == nil {
81+ return fmt .Errorf ("the reconciler client could not be found" )
7182 }
7283
73- r . once . Do ( func () {
74- if wg != nil {
75- wg . Wait ()
76- }
77- for secretKey , secretValue := range r . secret .Data {
78- clear (secretValue )
79- delete (r . secret .Data , secretKey )
80- }
81- })
84+ secret := & corev1. Secret {}
85+ secret . Name = name
86+ secret . Namespace = ns
87+ err := client . Get ( context . TODO (), types. NamespacedName { Name : name , Namespace : ns }, secret )
88+ for key , value := range secret .Data {
89+ clear (value )
90+ delete (secret .Data , key )
91+ }
92+ return err
8293}
0 commit comments