1
1
package init
2
2
3
3
import (
4
+ "context"
5
+ "errors"
4
6
"fmt"
5
7
"reflect"
8
+ "strings"
6
9
7
10
apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1"
8
11
v1 "kusionstack.io/kusion/pkg/apis/status/v1"
12
+ "kusionstack.io/kusion/pkg/engine/operation/graph"
9
13
"kusionstack.io/kusion/pkg/engine/runtime"
10
14
"kusionstack.io/kusion/pkg/engine/runtime/kubernetes"
11
15
"kusionstack.io/kusion/pkg/engine/runtime/kubernetes/kubeops"
12
16
"kusionstack.io/kusion/pkg/engine/runtime/terraform"
17
+ "kusionstack.io/kusion/pkg/secrets"
18
+ "kusionstack.io/kusion/pkg/workspace"
13
19
)
14
20
15
21
var SupportRuntimes = map [apiv1.Type ]InitFn {
16
22
runtime .Kubernetes : kubernetes .NewKubernetesRuntime ,
17
23
runtime .Terraform : terraform .NewTerraformRuntime ,
18
24
}
19
25
26
+ var contextKeys = []string {
27
+ kubeops .KubeConfigContentKey ,
28
+ apiv1 .EnvAwsAccessKeyID ,
29
+ apiv1 .EnvAwsSecretAccessKey ,
30
+ apiv1 .EnvAlicloudAccessKey ,
31
+ apiv1 .EnvAlicloudSecretKey ,
32
+ }
33
+
20
34
// InitFn runtime init func
21
- type InitFn func (resource * apiv1.Resource ) (runtime.Runtime , error )
35
+ type InitFn func (spec apiv1.Spec ) (runtime.Runtime , error )
22
36
23
- func Runtimes (resources apiv1.Resources ) (map [apiv1.Type ]runtime.Runtime , v1.Status ) {
37
+ func Runtimes (spec apiv1.Spec ) (map [apiv1.Type ]runtime.Runtime , v1.Status ) {
38
+ // Parse the secret ref in the Context of Spec.
39
+ if err := parseContextSecretRef (& spec ); err != nil {
40
+ return nil , v1 .NewErrorStatus (err )
41
+ }
42
+ resources := spec .Resources
24
43
runtimesMap := map [apiv1.Type ]runtime.Runtime {}
25
44
if resources == nil {
26
45
return runtimesMap , nil
@@ -32,7 +51,7 @@ func Runtimes(resources apiv1.Resources) (map[apiv1.Type]runtime.Runtime, v1.Sta
32
51
for _ , resource := range resources {
33
52
rt := resource .Type
34
53
if runtimesMap [rt ] == nil {
35
- r , err := SupportRuntimes [rt ](& resource )
54
+ r , err := SupportRuntimes [rt ](spec )
36
55
if err != nil {
37
56
return nil , v1 .NewErrorStatus (fmt .Errorf ("init %s runtime failed. %w" , rt , err ))
38
57
}
@@ -65,3 +84,51 @@ func validResources(resources apiv1.Resources) v1.Status {
65
84
}
66
85
return nil
67
86
}
87
+
88
+ // parseContextSecretRef parses the external secret ref of the credentials
89
+ // in the Context of Spec.
90
+ func parseContextSecretRef (spec * apiv1.Spec ) error {
91
+ // Copy the Context of Spec.
92
+ parsedContext := apiv1.GenericConfig {}
93
+ for k , v := range spec .Context {
94
+ parsedContext [k ] = v
95
+ }
96
+
97
+ // Retrieve the context with the specified keys from spec and parse the external secret ref.
98
+ for _ , key := range contextKeys {
99
+ contextStr , err := workspace .GetStringFromGenericConfig (spec .Context , key )
100
+ if err != nil {
101
+ return err
102
+ }
103
+
104
+ if contextStr != "" {
105
+ // Replace the secret store ref.
106
+ if strings .HasPrefix (contextStr , graph .SecretRefPrefix ) {
107
+ externalSecretRef , err := graph .ParseExternalSecretDataRef (contextStr )
108
+ if err != nil {
109
+ return err
110
+ }
111
+
112
+ provider , exist := secrets .GetProvider (spec .SecretStore .Provider )
113
+ if ! exist {
114
+ return errors .New ("no matched secret store found, please check workspace yaml" )
115
+ }
116
+ secretStore , err := provider .NewSecretStore (spec .SecretStore )
117
+ if err != nil {
118
+ return err
119
+ }
120
+ secretData , err := secretStore .GetSecret (context .Background (), * externalSecretRef )
121
+ if err != nil {
122
+ return err
123
+ }
124
+
125
+ parsedContext [key ] = string (secretData )
126
+ }
127
+ }
128
+ }
129
+
130
+ // Reset the Context with the parsed values.
131
+ spec .Context = parsedContext
132
+
133
+ return nil
134
+ }
0 commit comments