-
Notifications
You must be signed in to change notification settings - Fork 28
/
openshift-rest-client.js
190 lines (170 loc) · 6.89 KB
/
openshift-rest-client.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
'use strict';
/*
*
* Copyright 2016-2017 Red Hat, Inc, and individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const zlib = require('zlib');
const fs = require('fs');
const path = require('path');
const { Client, alias, KubeConfig } = require('kubernetes-client');
const { getTokenFromBasicAuth, getUserFromAuthToken } = require('./basic-auth-request');
const Request = require('kubernetes-client/backends/request');
const serviceCatalogCRD = require('./specs/service-catalog-crd.json');
// A list of shorthand aliases
const resourceAliases = {
'apps.openshift.io': ['app'],
'authorization.openshift.io': ['authorization'],
'build.openshift.io': ['build'],
'image.openshift.io': ['image'],
'network.openshift.io': ['network'],
'oauth.openshift.io': ['oauth'],
'project.openshift.io': ['project'],
'quota.openshift.io': ['quota'],
'route.openshift.io': ['route'],
'security.openshift.io': ['security'],
'template.openshift.io': ['template'],
'user.openshift.io': ['user']
};
function getNames (resourceType) {
const aliases = [resourceType];
if (resourceAliases[resourceType]) {
return aliases.concat(resourceAliases[resourceType]);
}
return alias(resourceType);
}
// unzip and load the openshift openapi swagger spec file
// Doesn't look like there is a way to query this from a running cluster
// Perhaps, we could try to query https://raw.githubusercontent.com/openshift/origin/HEAD/api/swagger-spec/openshift-openapi-spec.json ?
const spec = JSON.parse(zlib.gunzipSync(fs.readFileSync(path.join(__dirname, 'specs', 'openshift-openapi-spec.json.gz'))));
/**
* Builds the rest client based on provided or default kubernetes configuration.
*
* @param {object} [settings] - settings object for the openshiftClient function
* @param {boolean} [settings.loadSpecFromCluster] - load the api spec from a remote cluster. Defaults to true
* @param {object|string} [settings.config] - custom config object(KubeConfig or object). String value will assume a config file location.
* @param {string} [settings.config.url] - Openshift cluster url
* @param {object} [settings.config.auth] -
* @param {string} [settings.config.auth.token] - auth token used to authenticate to the Openshift Cluster
* @param {string} [settings.config.auth.username] - username to authenticate to Openshift
* @param {string} [settings.config.auth.password] - password to authenticate to Openshift
* @param {boolean} [settings.config.insecureSkipTlsVerify] - flag to ignore TLS verification
* @returns {Promise} Returns the Rest Client
*/
async function openshiftClient (settings = {}) {
let config = settings.config;
// Default the load spec from cluster to true
const { loadSpecFromCluster = true } = settings;
const clientConfig = { backend: null, /* spec, */ getNames };
if (!loadSpecFromCluster) {
clientConfig.spec = spec;
}
const kubeconfig = new KubeConfig();
let fullyUserDefined = false;
if (config) {
// A config is being passed in.
if (typeof config === 'string') {
// This is the config location
// load from file
kubeconfig.loadFromFile(config);
clientConfig.backend = new Request({ kubeconfig });
} else if (typeof config === 'object' && config.auth) {
// Check for the auth username password
if ('user' in config.auth || 'username' in config.auth || 'token' in config.auth) {
// They are trying the basic auth.
// Get the access token using the username and password
// Check to see if we are passing in a username/password
const { insecureSkipTlsVerify, url, authUrl } = config;
let user = config.auth.username || config.auth.user;
const password = config.auth.password || config.auth.pass;
let accessToken;
if (config.auth.token) {
const openshiftUser = await getUserFromAuthToken({ insecureSkipTlsVerify, url, token: config.auth.token });
accessToken = config.auth.token;
user = openshiftUser.metadata.name;
} else {
accessToken = await getTokenFromBasicAuth({ insecureSkipTlsVerify, url, user, password, authUrl });
}
const clusterUrl = url;
// Create clusterName from clusterUrl by removing 'https://'
const clusterName = clusterUrl.replace(/(^\w+:|^)\/\//, '');
config = {
apiVersion: 'v1',
clusters: [
{
cluster: {
server: clusterUrl,
'insecure-skip-tls-verify': insecureSkipTlsVerify
},
name: clusterName
}
],
contexts: [
{
context: {
cluster: clusterName,
user: `${user}/${clusterName}`
},
name: `default/${clusterName}/${user}`
}
],
'current-context': `default/${clusterName}/${user}`,
kind: 'Config',
preferences: {},
users: [
{
name: `${user}/${clusterName}`,
user: {
token: accessToken
}
}
]
};
kubeconfig.loadFromString(JSON.stringify(config));
clientConfig.backend = new Request({ kubeconfig });
}
} else if (config.clusters) {
if (config instanceof KubeConfig) {
// They passed in an actual KubeConfig object
// No need to stringify and reload
clientConfig.backend = new Request({ kubeconfig: config });
} else {
kubeconfig.loadFromString(JSON.stringify(config));
clientConfig.backend = new Request({ kubeconfig });
}
fullyUserDefined = true;
}
} else {
kubeconfig.loadFromDefault();
clientConfig.backend = new Request({ kubeconfig });
}
let client = new Client(clientConfig);
if (loadSpecFromCluster) {
try {
await client.loadSpec();
} catch (err) {
// Warn the user there was an error and loading the other spec
console.warn('Warning: Remote client spec unable to load', err.message);
console.warn('Warning: Loading default spec instead');
clientConfig.spec = spec;
client = new Client(clientConfig);
}
}
// CRD with the service instance stuff, but only to this client, not the cluster
client.addCustomResourceDefinition(serviceCatalogCRD);
client.kubeconfig = fullyUserDefined ? config : kubeconfig;
return client;
}
module.exports = exports = openshiftClient;