Openshift 需要通过 bearer token 的方式和 API 进行调用, 比如基于 Postman 就可以了解到, 输入 bearer token 后
1. 如何获取 Bearer Token
但 Bearer Token 如何获取是个巨大的问题, 一般来说有两种方式
1. 基于 oc 命令行, 如
- [root@master ~]# oc login -u admin
- Logged into "https://master.example.com:8443" as "admin" using existing credentials.
- You have access to the following projects and can switch between them with 'oc project <projectname>':
- * default
- kube-public
- kube-service-catalog
- kube-system
- management-infra
- openshift
- openshift-ansible-service-broker
- openshift-console
- openshift-infra
- openshift-logging
- openshift-monitoring
- openshift-node
- openshift-sdn
- openshift-template-service-broker
- openshift-web-console
- scdf
- Using project "default".
- [root@master ~]# oc whoami -t
- 9GLqCn9yL61TyzRjidM2GRgL-S10z0JSato9Puie70I
2. 基于 curl 命令
- [root@node1 ~]# curl -u admin:welcome1 -kv -H "X-CSRF-Token: xxx" 'https://master.example.com:8443/oauth/authorize?client_id=openshift-challenging-client&response_type=token'
- * About to connect() to master.example.com port 8443 (#0)
- * Trying 192.168.56.103...
- * Connected to master.example.com (192.168.56.103) port 8443 (#0)
- * Initializing NSS with certpath: sql:/etc/pki/nssdb
- * skipping SSL peer certificate verification
- * NSS: client certificate not found (nickname not specified)
- * SSL connection using TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
- * Server certificate:
- * subject: CN=172.30.0.1
- * start date: Nov 30 05:29:38 2018 GMT
- * expire date: Nov 29 05:29:39 2020 GMT
- * common name: 172.30.0.1
- * issuer: CN=openshift-signer@1543555777
- * Server auth using Basic with user 'admin'
- > GET /OAuth/authorize?client_id=openshift-challenging-client&response_type=token HTTP/1.1
- > Authorization: Basic YWRtaW46d2VsY29tZTE=
- > User-Agent: curl/7.29.0
- > Host: master.example.com:8443
- > Accept: */*
- > X-CSRF-Token: xxx
- >
- <HTTP/1.1 302 Found
- < Cache-Control: no-cache, no-store, max-age=0, must-revalidate
- < Expires: Fri, 01 Jan 1990 00:00:00 GMT
- < Location: https://master.example.com:8443/oauth/token/implicit#access_token=iVwykQc-qqsO245VJ9TIZq_lIL31G1mTM2GJHTPFfkI&expires_in=86400&scope=user:full&token_type=Bearer
- < Pragma: no-cache
- < Set-Cookie: ssn=MTU0NDAyNDU1OXxnZV9UaWN5QlpFZ2RULW5vY3o2dVp4SU5WVWZkbWxNd0xfUnFCVzlmRndBSS1Wb2JzY3ZJZHFYb1BPWDNqTWVMV2FjbkJ0bmtlemRMMnpDZ3FSLWUtb0lieVBJQjF0dS1nSWJiZUJrYlFLSngxYVZBa085MUN3VVJkZHJyM2FiNjU1MWkwa3RwcGtHdmJvSmhreWpfRW1MQlFuanYyeEdTcTAybDVuREtEcl9mMHhlXzVYdE5LdG5vNHpKa2QxeGMzczRKRHhzOXzT_k_wyIvwJz72RH5SJor7WYJ3lasYsoVFcdQ6phk75g==; Path=/; HttpOnly; Secure
- < Date: Wed, 05 Dec 2018 15:42:39 GMT
- < Content-Length: 0
- <
- * Connection #0 to host master.example.com left intact
一直想通过 REST 去掉通, 尝试很久, 最后得到的是如下错误
- You have reached this page by following a redirect Location header from an OAuth authorize request.
- If a response_type=token parameter was passed to the /authorize endpoint, that requested an
- "Implicit Grant" OAuth flow (see https://tools.ietf.org/html/rfc6749#section-4.2).
- That flow requires the access token to be returned in the fragment portion of a redirect header.
- Rather than following the redirect here, you can obtain the access token from the Location header
- (see https://tools.ietf.org/html/rfc6749#section-4.2.2):
- 1. Parse the URL in the Location header and extract the fragment portion
- 2. Parse the fragment using the "application/x-www-form-urlencoded" format
- 3. The access_token parameter contains the granted OAuth access token
解决办法:
通过运行一个 java 程序, 通过后端的 shell 去获取, 代码如下:
- import java.io.InputStreamReader;
- public class getToken {
- public void getocpToken() {
- try {
- //Process process = Runtime.getRuntime().exec("curl -u admin:welcome1 -kv -H \"X-CSRF-Token: xxx\"'https://master.example.com:8443/oauth/authorize?client_id=openshift-challenging-client&response_type=token'");
- Process process = Runtime.getRuntime().exec("/root/curl.sh");
- BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
- String line = "";
- while ((line = input.readLine()) != null) {
- System.out.println(line);
- }
- input.close();
- } catch (Exception e){
- e.printStackTrace();
- }
- }
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- getToken sample = new getToken();
- sample.getocpToken();
- }
- }
简单说就是调用了 curl.sh 脚本, 这个脚本是长下面这个样的
- [root@master ~]# cat curl.sh
- curl -u admin:welcome1 -kv --silent -H "X-CSRF-Token: xxx" 'https://master.example.com:8443/oauth/authorize?client_id=openshift-challenging-client&response_type=token' 2>&1 | grep access_token | awk -F '=' '{print $2}' | awk -F '&' '{print $1}'
运行结果如下:
- [root@master ~]# java getToken
- oWcKCjuSfbDaJqbLNeLCP67GuR-lAXmjSPyBplWRbvE
这种方式最大的好处是通过 http 去获取, 这样不需要依赖于 oc 等命令和环境变量, 正是因为通过 http, 而且用 curl, 所以也可以进行容器化, 在容器中运行.
2. 通过代码去删除 Pod
需要注意事项
搞定免证书的 SSL 调用
传入 bearer token
一切就很顺利了, 贴一下代码
HttpDemo.java
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.UnsupportedEncodingException;
- import java.NET.HttpURLConnection;
- import java.NET.MalformedURLException;
- import java.NET.URL;
- import java.util.LinkedHashMap;
- import java.util.Map;
- import javax.NET.ssl.HttpsURLConnection;
- import org.apache.commons.codec.binary.Base64;
- public class HttpDemo {
- private static final String SYS_VULLN_URL_JSON="https://master.example.com:8443/api/v1/namespaces/scdf/pods/kafka-broker-1-9qdqn";
- public static void httpGet(){
- StringBuffer tempStr = new StringBuffer();
- String responseContent="";
- HttpURLConnection conn = null;
- try {
- URL url = new URL(SYS_VULLN_URL_JSON);
- if("https".equalsIgnoreCase(url.getProtocol())){
- SslUtils.ignoreSsl();
- }
- HttpsURLConnection https = (HttpsURLConnection)url.openConnection();
- https.setRequestMethod("DELETE");
- https.setRequestProperty("Authorization", "Bearer 9GLqCn9yL61TyzRjidM2GRgL-S10z0JSato9Puie70I");
- String result = getReturn(https);
- System.out.println(result);
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch(Exception e){
- e.printStackTrace();
- }
- }
- /**
- * Trust every server - dont check for any certificate
- */
- public static String getReturn(HttpURLConnection connection) throws IOException{
- StringBuffer buffer = new StringBuffer();
- try(InputStream inputStream = connection.getInputStream();
- InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
- BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){
- String str = null;
- while ((str = bufferedReader.readLine()) != null) {
- buffer.append(str);
- }
- String result = buffer.toString();
- return result;
- }
- }
- private static void printResponseHeader(HttpURLConnection http) throws UnsupportedEncodingException {
- Map<String, String> header = getHttpResponseHeader(http);
- for (Map.Entry<String, String> entry : header.entrySet()) {
- String key = entry.getKey() != null ? entry.getKey() + ":" : "";
- System.out.println(key + entry.getValue());
- }
- }
- private static Map<String, String> getHttpResponseHeader(
- HttpURLConnection http) throws UnsupportedEncodingException {
- Map<String, String> header = new LinkedHashMap<String, String>();
- for (int i = 0;; i++) {
- String mine = http.getHeaderField(i);
- if (mine == null)
- break;
- header.put(http.getHeaderFieldKey(i), mine);
- }
- return header;
- }
- public static void main(String[] args) {
- httpGet();
- }
- }
SslUtils.java
- import java.security.cert.CertificateException;
- import java.security.cert.X509Certificate;
- import javax.NET.ssl.HostnameVerifier;
- import javax.NET.ssl.HttpsURLConnection;
- import javax.NET.ssl.SSLContext;
- import javax.NET.ssl.SSLSession;
- import javax.NET.ssl.TrustManager;
- import javax.NET.ssl.X509TrustManager;
- public class SslUtils {
- private static void trustAllHttpsCertificates() throws Exception {
- TrustManager[] trustAllCerts = new TrustManager[1];
- TrustManager tm = new miTM();
- trustAllCerts[0] = tm;
- SSLContext sc = SSLContext.getInstance("SSL");
- sc.init(null, trustAllCerts, null);
- HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
- }
- static class miTM implements TrustManager,X509TrustManager {
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
- public boolean isServerTrusted(X509Certificate[] certs) {
- return true;
- }
- public boolean isClientTrusted(X509Certificate[] certs) {
- return true;
- }
- public void checkServerTrusted(X509Certificate[] certs, String authType)
- throws CertificateException {
- return;
- }
- public void checkClientTrusted(X509Certificate[] certs, String authType)
- throws CertificateException {
- return;
- }
- }
- /**
- * 忽略 HTTPS 请求的 SSL 证书, 必须在 openConnection 之前调用
- * @throws Exception
- */
- public static void ignoreSsl() throws Exception{
- HostnameVerifier hv = new HostnameVerifier() {
- public boolean verify(String urlHostName, SSLSession session) {
- return true;
- }
- };
- trustAllHttpsCertificates();
- HttpsURLConnection.setDefaultHostnameVerifier(hv);
- }
- }
好了, 有了 token, 又不需要证书, 大家就可以愉快的玩耍了.
来源: http://www.bubuko.com/infodetail-2874236.html