1- // Copyright (c) 2020, 2021 , Oracle and/or its affiliates.
1+ // Copyright (c) 2020, 2022 , Oracle and/or its affiliates.
22// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33
44package oracle .weblogic .kubernetes .actions .impl ;
55
66import java .util .ArrayList ;
77import java .util .Base64 ;
8+ import java .util .Collections ;
89import java .util .List ;
9- import java .util .concurrent .TimeUnit ;
10+ import java .util .Map ;
11+ import java .util .Optional ;
1012
1113import io .kubernetes .client .openapi .ApiException ;
12- import io .kubernetes .client .openapi .models .V1ObjectReference ;
14+ import io .kubernetes .client .openapi .models .V1ObjectMeta ;
1315import io .kubernetes .client .openapi .models .V1Secret ;
1416import io .kubernetes .client .openapi .models .V1SecretList ;
15- import io .kubernetes .client .openapi .models .V1ServiceAccount ;
16- import io .kubernetes .client .openapi .models .V1ServiceAccountList ;
1717import oracle .weblogic .kubernetes .actions .impl .primitive .Kubernetes ;
1818import oracle .weblogic .kubernetes .logging .LoggingFacade ;
1919
20- import static oracle .weblogic .kubernetes .TestConstants .OKD ;
21- import static oracle .weblogic .kubernetes .actions .impl .primitive .Kubernetes .listServiceAccounts ;
22- import static oracle .weblogic .kubernetes .actions .impl .primitive .Kubernetes .readSecretByReference ;
20+ import static oracle .weblogic .kubernetes .utils .CommonTestUtils .testUntil ;
2321import static oracle .weblogic .kubernetes .utils .ThreadSafeLogger .getLogger ;
24- import static org .junit .jupiter .api .Assertions .assertDoesNotThrow ;
2522
2623public class Secret {
2724
@@ -56,52 +53,52 @@ public static boolean delete(String name, String namespace) {
5653 public static String getSecretOfServiceAccount (String namespace , String serviceAccountName ) {
5754
5855 LoggingFacade logger = getLogger ();
59- List <V1Secret > v1Secrets = new ArrayList <>();
60- List <V1ServiceAccount > v1ServiceAccounts = new ArrayList <>();
61- List <V1Secret > v1SaSecrets = new ArrayList <>();
62- String token = null ;
63-
64- if (!OKD ) {
65- V1SecretList secretList = listSecrets (namespace );
66- if (secretList != null ) {
67- v1Secrets = secretList .getItems ();
68- }
6956
70- for (V1Secret v1Secret : v1Secrets ) {
71- if (v1Secret .getMetadata () != null && v1Secret .getMetadata ().getName () != null ) {
72- logger .info (" secret name = {0}" , v1Secret .getMetadata ().getName ());
73- if (v1Secret .getMetadata ().getName ().startsWith (serviceAccountName )) {
74- return v1Secret .getMetadata ().getName ();
75- }
76- }
77- }
78- } else {
79- logger .info ("service account = {0}" , serviceAccountName );
80- logger .info ("namespace = {0}" , namespace );
81- V1ServiceAccountList serviceAccountList = listServiceAccounts (namespace );
82- if (serviceAccountList != null ) {
83- v1ServiceAccounts = serviceAccountList .getItems ();
57+ logger .info ("service account = {0}" , serviceAccountName );
58+ logger .info ("namespace = {0}" , namespace );
59+ V1SecretList secretList = listSecrets (namespace );
60+ for (V1Secret v1Secret : secretList .getItems ()) {
61+ V1ObjectMeta meta = Optional .ofNullable (v1Secret ).map (V1Secret ::getMetadata ).orElse (new V1ObjectMeta ());
62+ Map <String , String > annotations =
63+ Optional .of (meta ).map (V1ObjectMeta ::getAnnotations ).orElse (Collections .emptyMap ());
64+ String saName = annotations .get ("kubernetes.io/service-account.name" );
65+ if (serviceAccountName .equals (saName )) {
66+ logger .info ("secret name = {0}" , meta .getName ());
67+ return meta .getName ();
8468 }
69+ }
8570
86- try {
87- for (V1ServiceAccount v1ServiceAccount : v1ServiceAccounts ) {
88- if (v1ServiceAccount .getMetadata () != null && v1ServiceAccount .getMetadata ().getName () != null ) {
89- if (v1ServiceAccount .getMetadata ().getName ().startsWith (serviceAccountName )) {
90- List <V1ObjectReference > saSecretList = v1ServiceAccount .getSecrets ();
91- for (V1ObjectReference reference : saSecretList ) {
92- // Get the secret.
93- V1Secret secret = readSecretByReference (reference , namespace );
94- logger .info ("secret token = {0}" , secret .getMetadata ().getName ());
95- return secret .getMetadata ().getName ();
96- }
97- }
98- }
99- }
100- } catch (ApiException apie ) {
101- logger .info (" got ApiException" );
102- }
71+ logger .info ("No secret found for service account; creating one" );
72+ String saSecretName = serviceAccountName + "-" + "sa-token" ;
73+ V1Secret saSecret = new V1Secret ()
74+ .type ("kubernetes.io/service-account-token" )
75+ .metadata (new V1ObjectMeta ()
76+ .name (saSecretName )
77+ .namespace (namespace )
78+ .putAnnotationsItem ("kubernetes.io/service-account.name" , serviceAccountName ));
79+
80+ try {
81+ Kubernetes .createSecret (saSecret );
82+ } catch (ApiException e ) {
83+ logger .severe ("failed to create secret for service account" , e );
84+ return "" ;
10385 }
104- return "" ;
86+
87+ testUntil (
88+ () -> hasToken (saSecretName , namespace ),
89+ logger ,
90+ "Waiting for token to be populated in secret" );
91+
92+ return saSecretName ;
93+ }
94+
95+ private static boolean hasToken (String saSecretName , String namespace ) throws ApiException {
96+ V1Secret secret = Kubernetes .getSecret (saSecretName , namespace );
97+ if (secret != null ) {
98+ Map <String , byte []> data = Optional .of (secret ).map (V1Secret ::getData ).orElse (Collections .emptyMap ());
99+ return data .containsKey ("token" );
100+ }
101+ return false ;
105102 }
106103
107104 /**
@@ -112,38 +109,26 @@ public static String getSecretOfServiceAccount(String namespace, String serviceA
112109 * @return the encoded token of the secret
113110 */
114111 public static String getSecretEncodedToken (String namespace , String secretName ) {
115- LoggingFacade logger = getLogger ();
116- for (int i = 0 ; i < 10 ; i ++) {
117- String token = getToken (namespace , secretName );
118- if (token != null ) {
119- logger .info ("Got the token {0}" , token );
120- return token ;
121- }
122- logger .info ("Token is null, retrying after 5 seconds" );
123- assertDoesNotThrow (() -> TimeUnit .SECONDS .sleep (5 ));
124- }
125- logger .warning ("Secret token is null" );
126- return null ;
127- }
128112
129- private static String getToken (String namespace , String secretName ) {
130- String token = null ;
131113 List <V1Secret > v1Secrets = new ArrayList <>();
114+
132115 V1SecretList secretList = listSecrets (namespace );
133116 if (secretList != null ) {
134117 v1Secrets = secretList .getItems ();
135118 }
119+
136120 for (V1Secret v1Secret : v1Secrets ) {
137121 if (v1Secret .getMetadata () != null && v1Secret .getMetadata ().getName () != null ) {
138122 if (v1Secret .getMetadata ().getName ().equals (secretName )) {
139- if (v1Secret .getData () != null && v1Secret . getData (). get ( "token" ) != null ) {
123+ if (v1Secret .getData () != null ) {
140124 byte [] encodedToken = v1Secret .getData ().get ("token" );
141- token = Base64 .getEncoder ().encodeToString (encodedToken );
125+ return Base64 .getEncoder ().encodeToString (encodedToken );
142126 }
143127 }
144128 }
145129 }
146- return token ;
130+
131+ return "" ;
147132 }
148133
149134 /**
0 commit comments