@@ -12,35 +12,37 @@ namespace k8s
12
12
public partial class KubernetesClientConfiguration
13
13
{
14
14
/// <summary>
15
- /// Gets CurrentContext
16
- /// </summary>
17
- public string CurrentContext { get ; private set ; }
18
-
19
- /// <summary>
20
- /// kubeconfig Default Location
15
+ /// kubeconfig Default Location
21
16
/// </summary>
22
17
private static readonly string KubeConfigDefaultLocation =
23
18
RuntimeInformation . IsOSPlatform ( OSPlatform . Windows )
24
19
? Path . Combine ( Environment . GetEnvironmentVariable ( "USERPROFILE" ) , @".kube\config" )
25
20
: Path . Combine ( Environment . GetEnvironmentVariable ( "HOME" ) , ".kube/config" ) ;
26
21
27
22
/// <summary>
28
- /// Initializes a new instance of the <see cref="KubernetesClientConfiguration"/> from config file
23
+ /// Gets CurrentContext
24
+ /// </summary>
25
+ public string CurrentContext { get ; private set ; }
26
+
27
+ /// <summary>
28
+ /// Initializes a new instance of the <see cref="KubernetesClientConfiguration" /> from config file
29
29
/// </summary>
30
30
/// <param name="masterUrl">kube api server endpoint</param>
31
31
/// <param name="kubeconfigPath">kubeconfig filepath</param>
32
- public static KubernetesClientConfiguration BuildConfigFromConfigFile ( string masterUrl = null , string kubeconfigPath = null )
32
+ public static KubernetesClientConfiguration BuildConfigFromConfigFile ( string masterUrl = null ,
33
+ string kubeconfigPath = null )
33
34
{
34
- return BuildConfigFromConfigFile ( new FileInfo ( kubeconfigPath ?? KubeConfigDefaultLocation ) , null , masterUrl ) ;
35
+ return BuildConfigFromConfigFile ( new FileInfo ( kubeconfigPath ?? KubeConfigDefaultLocation ) , null ,
36
+ masterUrl ) ;
35
37
}
36
38
37
39
/// <summary>
38
- ///
39
40
/// </summary>
40
41
/// <param name="kubeconfig">Fileinfo of the kubeconfig, cannot be null</param>
41
42
/// <param name="currentContext">override the context in config file, set null if do not want to override</param>
42
43
/// <param name="masterUrl">overrider kube api server endpoint, set null if do not want to override</param>
43
- public static KubernetesClientConfiguration BuildConfigFromConfigFile ( FileInfo kubeconfig , string currentContext = null , string masterUrl = null )
44
+ public static KubernetesClientConfiguration BuildConfigFromConfigFile ( FileInfo kubeconfig ,
45
+ string currentContext = null , string masterUrl = null )
44
46
{
45
47
if ( kubeconfig == null )
46
48
{
@@ -49,54 +51,59 @@ public static KubernetesClientConfiguration BuildConfigFromConfigFile(FileInfo k
49
51
50
52
var k8SConfig = LoadKubeConfig ( kubeconfig ) ;
51
53
var k8SConfiguration = new KubernetesClientConfiguration ( ) ;
52
- k8SConfiguration . Initialize ( k8SConfig , currentContext ) ;
54
+
55
+ currentContext = currentContext ?? k8SConfig . CurrentContext ;
56
+
57
+ // only init context if context if set
58
+ if ( currentContext != null )
59
+ {
60
+ k8SConfiguration . InitializeContext ( k8SConfig , currentContext ) ;
61
+ }
53
62
54
63
if ( ! string . IsNullOrWhiteSpace ( masterUrl ) )
55
64
{
56
65
k8SConfiguration . Host = masterUrl ;
57
66
}
67
+
68
+ if ( string . IsNullOrWhiteSpace ( k8SConfiguration . Host ) )
69
+ {
70
+ throw new KubeConfigException ( "Cannot infer server host url either from context or masterUrl" ) ;
71
+ }
72
+
58
73
return k8SConfiguration ;
59
74
}
60
-
61
75
62
76
/// <summary>
63
- /// Validates and Intializes Client Configuration
77
+ /// Validates and Intializes Client Configuration
64
78
/// </summary>
65
79
/// <param name="k8SConfig">Kubernetes Configuration</param>
66
80
/// <param name="currentContext">Current Context</param>
67
- private void Initialize ( K8SConfiguration k8SConfig , string currentContext = null )
81
+ private void InitializeContext ( K8SConfiguration k8SConfig , string currentContext )
68
82
{
69
- if ( k8SConfig . Contexts == null )
70
- {
71
- throw new KubeConfigException ( "No contexts found in kubeconfig" ) ;
72
- }
73
-
74
- if ( k8SConfig . Clusters == null )
75
- {
76
- throw new KubeConfigException ( $ "No clusters found in kubeconfig") ;
77
- }
78
-
79
- if ( k8SConfig . Users == null )
80
- {
81
- throw new KubeConfigException ( $ "No users found in kubeconfig") ;
82
- }
83
-
84
83
// current context
85
- currentContext = currentContext ?? k8SConfig . CurrentContext ;
86
- Context activeContext =
84
+ var activeContext =
87
85
k8SConfig . Contexts . FirstOrDefault (
88
86
c => c . Name . Equals ( currentContext , StringComparison . OrdinalIgnoreCase ) ) ;
89
87
if ( activeContext == null )
90
88
{
91
89
throw new KubeConfigException ( $ "CurrentContext: { currentContext } not found in contexts in kubeconfig") ;
92
90
}
93
91
94
- this . CurrentContext = activeContext . Name ;
92
+ CurrentContext = activeContext . Name ;
95
93
96
94
// cluster
95
+ SetClusterDetails ( k8SConfig , activeContext ) ;
96
+
97
+ // user
98
+ SetUserDetails ( k8SConfig , activeContext ) ;
99
+ }
100
+
101
+ private void SetClusterDetails ( K8SConfiguration k8SConfig , Context activeContext )
102
+ {
97
103
var clusterDetails =
98
104
k8SConfig . Clusters . FirstOrDefault ( c => c . Name . Equals ( activeContext . ContextDetails . Cluster ,
99
105
StringComparison . OrdinalIgnoreCase ) ) ;
106
+
100
107
if ( clusterDetails ? . ClusterEndpoint == null )
101
108
{
102
109
throw new KubeConfigException ( $ "Cluster not found for context { activeContext } in kubeconfig") ;
@@ -106,33 +113,49 @@ private void Initialize(K8SConfiguration k8SConfig, string currentContext = null
106
113
{
107
114
throw new KubeConfigException ( $ "Server not found for current-context { activeContext } in kubeconfig") ;
108
115
}
116
+ Host = clusterDetails . ClusterEndpoint . Server ;
109
117
110
- if ( ! clusterDetails . ClusterEndpoint . SkipTlsVerify &&
111
- string . IsNullOrWhiteSpace ( clusterDetails . ClusterEndpoint . CertificateAuthorityData ) &&
112
- string . IsNullOrWhiteSpace ( clusterDetails . ClusterEndpoint . CertificateAuthority ) )
113
- {
114
- throw new KubeConfigException (
115
- $ "neither certificate-authority-data nor certificate-authority not found for current-context :{ activeContext } in kubeconfig") ;
116
- }
118
+ SkipTlsVerify = clusterDetails . ClusterEndpoint . SkipTlsVerify ;
117
119
118
- this . Host = clusterDetails . ClusterEndpoint . Server ;
119
- if ( ! string . IsNullOrEmpty ( clusterDetails . ClusterEndpoint . CertificateAuthorityData ) )
120
+ try
120
121
{
121
- string data = clusterDetails . ClusterEndpoint . CertificateAuthorityData ;
122
- this . SslCaCert = new X509Certificate2 ( Convert . FromBase64String ( data ) ) ;
122
+ var uri = new Uri ( Host ) ;
123
+ if ( uri . Scheme == "https" )
124
+ {
125
+
126
+ // check certificate for https
127
+ if ( ! clusterDetails . ClusterEndpoint . SkipTlsVerify &&
128
+ string . IsNullOrWhiteSpace ( clusterDetails . ClusterEndpoint . CertificateAuthorityData ) &&
129
+ string . IsNullOrWhiteSpace ( clusterDetails . ClusterEndpoint . CertificateAuthority ) )
130
+ {
131
+ throw new KubeConfigException (
132
+ $ "neither certificate-authority-data nor certificate-authority not found for current-context :{ activeContext } in kubeconfig") ;
133
+ }
134
+
135
+ if ( ! string . IsNullOrEmpty ( clusterDetails . ClusterEndpoint . CertificateAuthorityData ) )
136
+ {
137
+ var data = clusterDetails . ClusterEndpoint . CertificateAuthorityData ;
138
+ SslCaCert = new X509Certificate2 ( Convert . FromBase64String ( data ) ) ;
139
+ }
140
+ else if ( ! string . IsNullOrEmpty ( clusterDetails . ClusterEndpoint . CertificateAuthority ) )
141
+ {
142
+ SslCaCert = new X509Certificate2 ( clusterDetails . ClusterEndpoint . CertificateAuthority ) ;
143
+ }
144
+ }
123
145
}
124
- else if ( ! string . IsNullOrEmpty ( clusterDetails . ClusterEndpoint . CertificateAuthority ) )
146
+ catch ( UriFormatException e )
125
147
{
126
- this . SslCaCert = new X509Certificate2 ( clusterDetails . ClusterEndpoint . CertificateAuthority ) ;
148
+ throw new KubeConfigException ( "Bad Server host url" , e ) ;
127
149
}
128
- this . SkipTlsVerify = clusterDetails . ClusterEndpoint . SkipTlsVerify ;
129
-
130
- // user
131
- this . SetUserDetails ( k8SConfig , activeContext ) ;
132
150
}
133
151
134
152
private void SetUserDetails ( K8SConfiguration k8SConfig , Context activeContext )
135
153
{
154
+ if ( string . IsNullOrWhiteSpace ( activeContext . ContextDetails . User ) )
155
+ {
156
+ return ;
157
+ }
158
+
136
159
var userDetails = k8SConfig . Users . FirstOrDefault ( c => c . Name . Equals ( activeContext . ContextDetails . User ,
137
160
StringComparison . OrdinalIgnoreCase ) ) ;
138
161
@@ -151,31 +174,31 @@ private void SetUserDetails(K8SConfiguration k8SConfig, Context activeContext)
151
174
// Basic and bearer tokens are mutually exclusive
152
175
if ( ! string . IsNullOrWhiteSpace ( userDetails . UserCredentials . Token ) )
153
176
{
154
- this . AccessToken = userDetails . UserCredentials . Token ;
177
+ AccessToken = userDetails . UserCredentials . Token ;
155
178
userCredentialsFound = true ;
156
179
}
157
180
else if ( ! string . IsNullOrWhiteSpace ( userDetails . UserCredentials . UserName ) &&
158
181
! string . IsNullOrWhiteSpace ( userDetails . UserCredentials . Password ) )
159
182
{
160
- this . Username = userDetails . UserCredentials . UserName ;
161
- this . Password = userDetails . UserCredentials . Password ;
183
+ Username = userDetails . UserCredentials . UserName ;
184
+ Password = userDetails . UserCredentials . Password ;
162
185
userCredentialsFound = true ;
163
186
}
164
187
165
188
// Token and cert based auth can co-exist
166
189
if ( ! string . IsNullOrWhiteSpace ( userDetails . UserCredentials . ClientCertificateData ) &&
167
190
! string . IsNullOrWhiteSpace ( userDetails . UserCredentials . ClientKeyData ) )
168
191
{
169
- this . ClientCertificateData = userDetails . UserCredentials . ClientCertificateData ;
170
- this . ClientCertificateKeyData = userDetails . UserCredentials . ClientKeyData ;
192
+ ClientCertificateData = userDetails . UserCredentials . ClientCertificateData ;
193
+ ClientCertificateKeyData = userDetails . UserCredentials . ClientKeyData ;
171
194
userCredentialsFound = true ;
172
195
}
173
196
174
197
if ( ! string . IsNullOrWhiteSpace ( userDetails . UserCredentials . ClientCertificate ) &&
175
198
! string . IsNullOrWhiteSpace ( userDetails . UserCredentials . ClientKey ) )
176
199
{
177
- this . ClientCertificateFilePath = userDetails . UserCredentials . ClientCertificate ;
178
- this . ClientKeyFilePath = userDetails . UserCredentials . ClientKey ;
200
+ ClientCertificateFilePath = userDetails . UserCredentials . ClientCertificate ;
201
+ ClientKeyFilePath = userDetails . UserCredentials . ClientKey ;
179
202
userCredentialsFound = true ;
180
203
}
181
204
@@ -187,7 +210,7 @@ private void SetUserDetails(K8SConfiguration k8SConfig, Context activeContext)
187
210
}
188
211
189
212
/// <summary>
190
- /// Loads Kube Config
213
+ /// Loads Kube Config
191
214
/// </summary>
192
215
/// <param name="kubeconfig">Kube config file contents</param>
193
216
/// <returns>Instance of the <see cref="K8SConfiguration"/> class</returns>
@@ -197,11 +220,10 @@ private static K8SConfiguration LoadKubeConfig(FileInfo kubeconfig)
197
220
{
198
221
throw new KubeConfigException ( $ "kubeconfig file not found at { kubeconfig . FullName } ") ;
199
222
}
200
- var kubeconfigContent = File . ReadAllText ( kubeconfig . FullName ) ;
201
223
202
224
var deserializeBuilder = new DeserializerBuilder ( ) ;
203
225
var deserializer = deserializeBuilder . Build ( ) ;
204
- return deserializer . Deserialize < K8SConfiguration > ( kubeconfigContent ) ;
226
+ return deserializer . Deserialize < K8SConfiguration > ( kubeconfig . OpenText ( ) ) ;
205
227
}
206
228
}
207
- }
229
+ }
0 commit comments