11package io .kubernetes .client .util ;
22
33import io .kubernetes .client .ApiClient ;
4+ import io .kubernetes .client .ApiException ;
5+ import io .kubernetes .client .Configuration ;
6+ import io .kubernetes .client .apis .CoreV1Api ;
7+ import io .kubernetes .client .models .V1Pod ;
8+ import io .kubernetes .client .models .V1PodList ;
49
510import java .io .BufferedReader ;
11+ import java .io .ByteArrayInputStream ;
612import java .io .FileReader ;
713import java .io .FileInputStream ;
14+ import java .io .FileNotFoundException ;
15+ import java .io .InputStream ;
16+ import java .io .InputStreamReader ;
817import java .io .IOException ;
18+ import java .io .Reader ;
19+ import java .io .UnsupportedEncodingException ;
20+ import java .security .KeyStoreException ;
21+ import java .security .NoSuchAlgorithmException ;
22+ import java .security .UnrecoverableKeyException ;
23+ import java .security .cert .CertificateException ;
24+ import java .util .ArrayList ;
25+ import java .util .List ;
26+ import java .util .Map ;
27+
28+ import javax .net .ssl .KeyManager ;
29+ import javax .net .ssl .KeyManagerFactory ;
30+
31+ import org .yaml .snakeyaml .Yaml ;
32+ import org .yaml .snakeyaml .constructor .SafeConstructor ;
933
1034public class Config {
1135 private static final String SERVICEACCOUNT_ROOT =
@@ -63,4 +87,110 @@ public static ApiClient fromToken(String url, String token, boolean validateSSL)
6387 client .setAccessToken (token );
6488 return client ;
6589 }
66- }
90+
91+ public static ApiClient fromConfig (String fileName ) throws IOException {
92+ return fromConfig (new FileReader (fileName ));
93+ }
94+
95+ public static ApiClient fromConfig (InputStream stream ) {
96+ return fromConfig (new InputStreamReader (stream ));
97+ }
98+
99+ public static ApiClient fromConfig (Reader input ) {
100+ // Note to the reader: I considered creating a Config object
101+ // and parsing into that instead of using Maps, but honestly
102+ // this seemed cleaner than a bunch of boilerplate classes
103+ Yaml yaml = new Yaml (new SafeConstructor ());
104+ Object config = yaml .load (input );
105+ Map <String , Object > configMap = (Map <String , Object >)config ;
106+
107+ ArrayList <Object > clusters = (ArrayList <Object >)configMap .get ("clusters" );
108+ ArrayList <Object > contexts = (ArrayList <Object >)configMap .get ("contexts" );
109+ ArrayList <Object > users = (ArrayList <Object >)configMap .get ("users" );
110+ String currentContext = (String )configMap .get ("current-context" );
111+
112+ Map <String , Object > contextMap = findObject (contexts , currentContext );
113+ if (contextMap == null ) {
114+ return null ;
115+ }
116+ contextMap = (Map <String , Object >)contextMap .get ("context" );
117+
118+ String user = (String )contextMap .get ("user" );
119+ String cluster = (String )contextMap .get ("cluster" );
120+
121+ Map <String , Object > clusterMap = findObject (clusters , cluster );
122+ if (clusterMap == null ) {
123+ return null ;
124+ }
125+ clusterMap = (Map <String , Object >)clusterMap .get ("cluster" );
126+
127+ Map <String , Object > userMap = findObject (users , user );
128+ if (user == null ) {
129+ return null ;
130+ }
131+ userMap = (Map <String , Object >)userMap .get ("user" );
132+
133+ String server = (String ) clusterMap .get ("server" );
134+ String caCert = (String ) clusterMap .get ("certificate-authority-data" );
135+ String caCertFile = (String ) clusterMap .get ("certificate-authority" );
136+
137+ ApiClient client = new ApiClient ();
138+ client .setBasePath (server );
139+
140+ String clientCertificate = (String ) userMap .get ("client-certificate" );
141+ String clientCertificateData = (String ) userMap .get ("client-certificate-data" );
142+ String clientKey = (String ) userMap .get ("client-key" );
143+ String clientKeyData = (String ) userMap .get ("client-key-data" );
144+
145+ try {
146+ KeyManager [] mgrs = SSLUtils .keyManagers (
147+ clientCertificateData , clientCertificate ,
148+ clientKeyData , clientKey ,
149+ "RSA" , "" ,
150+ null , null );
151+ client .setKeyManagers (mgrs );
152+ } catch (Exception ex ) {
153+ ex .printStackTrace ();
154+ }
155+
156+ // It's silly to have to do it in this order, but each SSL setup
157+ // consumes the CA cert, so if we do this before the client certs
158+ // are injected the cert input stream is exhausted and things get
159+ // grumpy'
160+ if (caCert != null ) {
161+ try {
162+ client .setSslCaCert (new ByteArrayInputStream (caCert .getBytes ("UTF-8" )));
163+ } catch (UnsupportedEncodingException ex ) {
164+ ex .printStackTrace ();
165+ }
166+ } else if (caCertFile != null ) {
167+ try {
168+ client .setSslCaCert (new FileInputStream (caCertFile ));
169+ } catch (FileNotFoundException ex ) {
170+ ex .printStackTrace ();
171+ }
172+ }
173+
174+ Object authProvider = userMap .get ("auth-provider" );
175+ if (authProvider != null ) {
176+ Map <String , Object > authProviderMap = (Map <String , Object >) authProvider ;
177+ Map <String , Object > authConfig = (Map <String , Object >) authProviderMap .get ("config" );
178+ if (authConfig != null ) {
179+ String token = (String ) authConfig .get ("access-token" );
180+ client .setAccessToken (token );
181+ }
182+ }
183+
184+ return client ;
185+ }
186+
187+ private static Map <String , Object > findObject (ArrayList <Object > list , String name ) {
188+ for (Object obj : list ) {
189+ Map <String , Object > map = (Map <String , Object >)obj ;
190+ if (name .equals ((String )map .get ("name" ))) {
191+ return map ;
192+ }
193+ }
194+ return null ;
195+ }
196+ }
0 commit comments