-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Datasource authentication updates #1289
Changes from 2 commits
e80d391
9b81fd7
e4b2e4f
1e4e4c1
25b30f9
83f5afa
2def4bc
8150c9e
1f2108b
f0c5b16
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,10 +75,15 @@ data: | |
"adminUsername": "admin", | ||
"hostname": "kruize-db-service", | ||
"name": "kruizeDB", | ||
"password": "admin", | ||
"port": 5432, | ||
"sslMode": "require", | ||
"username": "admin" | ||
"authentication": { | ||
"type": "basic", | ||
"credentials": { | ||
"username": "admin", | ||
"password": "admin" | ||
} | ||
} | ||
} | ||
} | ||
kruizeconfigjson: | | ||
|
@@ -92,7 +97,7 @@ data: | |
"savetodb": "true", | ||
"dbdriver": "jdbc:postgresql://", | ||
"plots": "true", | ||
"local": "false", | ||
"local": "true", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let default value set to false , Until ROS move into thanos |
||
"logAllHttpReqAndResp": "true", | ||
"hibernate": { | ||
"dialect": "org.hibernate.dialect.PostgreSQLDialect", | ||
|
@@ -107,12 +112,17 @@ data: | |
}, | ||
"logging" : { | ||
"cloudwatch": { | ||
"accessKeyId": "", | ||
"logGroup": "kruize-logs", | ||
"logStream": "kruize-stream", | ||
"region": "", | ||
"secretAccessKey": "", | ||
"logLevel": "INFO" | ||
"authentication": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let make this PR limited scope .. Only datasource authentication |
||
"type": "apiKey", | ||
"credentials": { | ||
"accessKeyId": "", | ||
"secretAccessKey": "" | ||
} | ||
} | ||
} | ||
}, | ||
"datasource": [ | ||
|
@@ -121,7 +131,13 @@ data: | |
"provider": "prometheus", | ||
"serviceName": "", | ||
"namespace": "", | ||
"url": "https://prometheus-k8s.openshift-monitoring.svc.cluster.local:9091" | ||
"url": "https://prometheus-k8s.openshift-monitoring.svc.cluster.local:9091", | ||
"authentication": { | ||
"type": "bearer", | ||
"credentials": { | ||
"tokenFilePath": "/var/run/secrets/kubernetes.io/serviceaccount/token" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
create table IF NOT EXISTS kruize_datasources (version varchar(255), name varchar(255), provider varchar(255), serviceName varchar(255), namespace varchar(255), url varchar(255), primary key (name)); | ||
create table IF NOT EXISTS kruize_datasources (version varchar(255), name varchar(255), provider varchar(255), serviceName varchar(255), namespace varchar(255), url varchar(255), authentication jsonb, primary key (name)); | ||
create table IF NOT EXISTS kruize_dsmetadata (id serial, version varchar(255), datasource_name varchar(255), cluster_name varchar(255), namespace varchar(255), workload_type varchar(255), workload_name varchar(255), container_name varchar(255), container_image_name varchar(255), primary key (id)); | ||
alter table kruize_experiments add column metadata_id bigint references kruize_dsmetadata(id), alter column datasource type varchar(255); | ||
create table IF NOT EXISTS kruize_metric_profiles (api_version varchar(255), kind varchar(255), metadata jsonb, name varchar(255) not null, k8s_type varchar(255), profile_version float(53) not null, slo jsonb, primary key (name)); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.autotune.common.auth; | ||
|
||
public class APIKeyAuthenticationStrategy implements AuthenticationStrategy { | ||
private final String apiKey; | ||
|
||
public APIKeyAuthenticationStrategy(String apiKey) { | ||
this.apiKey = apiKey; | ||
} | ||
|
||
@Override | ||
public String applyAuthentication() { | ||
return "Api-Key " + apiKey; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package com.autotune.common.auth; | ||
|
||
import org.apache.http.client.methods.HttpRequestBase; | ||
|
||
import java.util.Base64; | ||
|
||
public class AuthenticationConfig { | ||
private final String type; // "basic", "bearer", "apiKey", "oauth2" | ||
private final Credentials credentials; | ||
|
||
public AuthenticationConfig(String type, Credentials credentials) { | ||
this.type = type; | ||
this.credentials = credentials; | ||
} | ||
|
||
public String getType() { | ||
return type; | ||
} | ||
|
||
public Credentials getCredentials() { | ||
return credentials; | ||
} | ||
|
||
public void applyAuthentication(HttpRequestBase httpRequestBase) { | ||
switch (type) { | ||
case "Basic": | ||
String basicAuth = Base64.getEncoder().encodeToString((credentials.getUsername() + ":" + credentials.getPassword()).getBytes()); | ||
httpRequestBase.setHeader("Authorization", "Basic " + basicAuth); | ||
break; | ||
case "Bearer": | ||
httpRequestBase.setHeader("Authorization", "Bearer " + credentials.getTokenFilePath()); | ||
break; | ||
case "APIKey": | ||
httpRequestBase.setHeader("Authorization", "ApiKey " + credentials.getApiKey()); | ||
break; | ||
case "OAuth2": | ||
// Assume the token is already retrieved and set | ||
httpRequestBase.setHeader("Authorization", "Bearer " + credentials.getTokenFilePath()); | ||
break; | ||
default: | ||
throw new IllegalArgumentException("Unsupported authentication type: " + type); | ||
} | ||
} | ||
|
||
// Static method to return a no-auth config | ||
public static AuthenticationConfig noAuth() { | ||
return new AuthenticationConfig("none", null); // Type "none" or similar to indicate no auth | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "AuthenticationConfig{" + | ||
"type='" + type + '\'' + | ||
", credentials=" + credentials + | ||
'}'; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. EOF missing |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.autotune.common.auth; | ||
|
||
public interface AuthenticationStrategy { | ||
String applyAuthentication(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.autotune.common.auth; | ||
|
||
public class AuthenticationStrategyFactory { | ||
|
||
public static AuthenticationStrategy createAuthenticationStrategy(AuthenticationConfig authConfig) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also support for no auth stratgey There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Support for no auth has been added in the AuthenticationConfig class: |
||
String type = authConfig.getType(); | ||
switch (type) { | ||
case "basic": | ||
String username = authConfig.getCredentials().getUsername(); | ||
String password = authConfig.getCredentials().getPassword(); | ||
return new BasicAuthenticationStrategy(username, password); | ||
case "bearer": | ||
String tokenFilePath = authConfig.getCredentials().getTokenFilePath(); | ||
return new BearerAuthenticationStrategy(tokenFilePath); | ||
case "apiKey": | ||
String apiKey = authConfig.getCredentials().getApiKey(); | ||
return new APIKeyAuthenticationStrategy(apiKey); | ||
case "oauth2": | ||
String tokenEndpoint = authConfig.getCredentials().getTokenEndpoint(); | ||
String clientId = authConfig.getCredentials().getClientId(); | ||
String clientSecret = authConfig.getCredentials().getClientSecret(); | ||
return new OAuth2AuthenticationStrategy(tokenEndpoint, clientId, clientSecret); | ||
default: | ||
throw new IllegalArgumentException("Unknown authentication type: " + type); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.autotune.common.auth; | ||
|
||
import java.util.Base64; | ||
|
||
public class BasicAuthenticationStrategy implements AuthenticationStrategy { | ||
private final String username; | ||
private final String password; | ||
|
||
public BasicAuthenticationStrategy(String username, String password) { | ||
this.username = username; | ||
this.password = password; | ||
} | ||
|
||
@Override | ||
public String applyAuthentication() { | ||
String auth = username + ":" + password; | ||
return "Basic " + Base64.getEncoder().encodeToString(auth.getBytes()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.autotune.common.auth; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.FileReader; | ||
import java.io.IOException; | ||
|
||
public class BearerAuthenticationStrategy implements AuthenticationStrategy { | ||
private final String tokenFilePath; | ||
|
||
public BearerAuthenticationStrategy(String tokenFilePath) { | ||
this.tokenFilePath = tokenFilePath; | ||
} | ||
|
||
@Override | ||
public String applyAuthentication() { | ||
// Read token from file | ||
try { | ||
BufferedReader reader = new BufferedReader(new FileReader(tokenFilePath)); | ||
String token = reader.readLine(); | ||
reader.close(); | ||
return "Bearer " + token; | ||
} catch (IOException e) { | ||
throw new RuntimeException("Failed to read Bearer token: " + e.getMessage()); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package com.autotune.common.auth; | ||
|
||
public class Credentials { | ||
private String grantType; // OAuth2 | ||
private String clientId; // OAuth2 | ||
private String clientSecret; // OAuth2 | ||
private String username; // Basic auth | ||
private String password; // Basic auth | ||
private String tokenEndpoint; // OAuth2 | ||
private String tokenFilePath; // Bearer token | ||
private String apiKey; // API key | ||
private String headerName; // API key header name | ||
|
||
public Credentials(String username, String password) { | ||
this.username = username; | ||
this.password = password; | ||
} | ||
|
||
public Credentials() { | ||
} | ||
|
||
public String getUsername() { | ||
return username; | ||
} | ||
|
||
public String getGrantType() { | ||
return grantType; | ||
} | ||
|
||
public String getClientSecret() { | ||
return clientSecret; | ||
} | ||
|
||
public String getClientId() { | ||
return clientId; | ||
} | ||
|
||
public String getTokenEndpoint() { | ||
return tokenEndpoint; | ||
} | ||
|
||
public String getHeaderName() { | ||
return headerName; | ||
} | ||
|
||
public String getApiKey() { | ||
return apiKey; | ||
} | ||
|
||
public String getTokenFilePath() { | ||
return tokenFilePath; | ||
} | ||
|
||
public String getPassword() { | ||
return password; | ||
} | ||
|
||
public void setGrantType(String grantType) { | ||
this.grantType = grantType; | ||
} | ||
|
||
public void setClientId(String clientId) { | ||
this.clientId = clientId; | ||
} | ||
|
||
public void setClientSecret(String clientSecret) { | ||
this.clientSecret = clientSecret; | ||
} | ||
|
||
public void setUsername(String username) { | ||
this.username = username; | ||
} | ||
|
||
public void setPassword(String password) { | ||
this.password = password; | ||
} | ||
|
||
public void setTokenEndpoint(String tokenEndpoint) { | ||
this.tokenEndpoint = tokenEndpoint; | ||
} | ||
|
||
public void setTokenFilePath(String tokenFilePath) { | ||
this.tokenFilePath = tokenFilePath; | ||
} | ||
|
||
public void setApiKey(String apiKey) { | ||
this.apiKey = apiKey; | ||
} | ||
|
||
public void setHeaderName(String headerName) { | ||
this.headerName = headerName; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Credentials{" + | ||
"grantType='" + grantType + '\'' + | ||
", clientId='" + clientId + '\'' + | ||
", clientSecret='" + clientSecret + '\'' + | ||
", username='" + username + '\'' + | ||
", password='" + password + '\'' + | ||
", tokenEndpoint='" + tokenEndpoint + '\'' + | ||
", tokenFilePath='" + tokenFilePath + '\'' + | ||
", apiKey='" + apiKey + '\'' + | ||
", headerName='" + headerName + '\'' + | ||
'}'; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. EOF missing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this PR is limited to datasource auth , But not for DB ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted