Skip to content

Commit

Permalink
add new table for auth to make way for common auth
Browse files Browse the repository at this point in the history
Signed-off-by: Saad Khan <[email protected]>
  • Loading branch information
khansaad committed Oct 8, 2024
1 parent 14e4e4c commit 177cb49
Show file tree
Hide file tree
Showing 12 changed files with 208 additions and 110 deletions.
3 changes: 2 additions & 1 deletion migrations/kruize_local_ddl.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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_datasources (version varchar(255), name varchar(255), provider varchar(255), serviceName varchar(255), namespace varchar(255), url varchar(255), authentication_id serial, FOREIGN KEY (authentication_id) REFERENCES kruize_authentication(id), 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 experiment_type varchar(255), 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));
alter table kruize_recommendations add column experiment_type varchar(255);
create table IF NOT EXISTS kruize_authentication (id serial, credentials jsonb, service_type varchar(255), primary key (id));
5 changes: 5 additions & 0 deletions src/main/java/com/autotune/common/auth/AuthType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.autotune.common.auth;

public enum AuthType {
BASIC, BEARER, API_KEY, OAUTH2, NONE
}
49 changes: 28 additions & 21 deletions src/main/java/com/autotune/common/auth/AuthenticationConfig.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
package com.autotune.common.auth;

import com.autotune.analyzer.utils.AnalyzerConstants;
import com.autotune.utils.KruizeConstants;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AuthenticationConfig {
private String type; // "basic", "bearer", "apiKey", "oauth2"
private AuthType type;
private Credentials credentials;
private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationConfig.class);

public AuthenticationConfig(String type, Credentials credentials) {
public AuthenticationConfig(AuthType type, Credentials credentials) {
this.type = type;
this.credentials = credentials;
}

public AuthenticationConfig() {
}

public String getType() {
public AuthType getType() {
return type;
}

Expand All @@ -30,27 +29,35 @@ public Credentials getCredentials() {
public static AuthenticationConfig createAuthenticationConfigObject(JSONObject authenticationObj) {
// Parse and map authentication methods if they exist
if (authenticationObj != null) {
String type = authenticationObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TYPE);
AuthType type = AuthType.valueOf(authenticationObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TYPE));
JSONObject credentialsObj = authenticationObj.getJSONObject(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CREDENTIALS);

Credentials credentials = new Credentials();
switch (type.toLowerCase()) {
case KruizeConstants.AuthenticationConstants.BASIC:
credentials.setUsername(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_USERNAME));
credentials.setPassword(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_PASSWORD));
Credentials credentials = null; // Initialize credentials as null, and create specific subclass instances based on the type
switch (type) {
case BASIC:
BasicAuthCredentials basicCredentials = new BasicAuthCredentials();
basicCredentials.setUsername(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_USERNAME));
basicCredentials.setPassword(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_PASSWORD));
credentials = basicCredentials;
break;
case KruizeConstants.AuthenticationConstants.BEARER:
credentials.setTokenFilePath(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TOKEN_FILE));
case BEARER:
BearerTokenCredentials bearerCredentials = new BearerTokenCredentials();
bearerCredentials.setTokenFilePath(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TOKEN_FILE));
credentials = bearerCredentials;
break;
case KruizeConstants.AuthenticationConstants.API_KEY:
credentials.setApiKey(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_API_KEY));
credentials.setHeaderName(credentialsObj.optString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_HEADER_NAME, "X-API-Key"));
case API_KEY:
ApiKeyCredentials apiKeyCredentials = new ApiKeyCredentials();
apiKeyCredentials.setApiKey(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_API_KEY));
apiKeyCredentials.setHeaderName(credentialsObj.optString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_HEADER_NAME, "X-API-Key"));
credentials = apiKeyCredentials;
break;
case KruizeConstants.AuthenticationConstants.OAUTH2:
credentials.setTokenEndpoint(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TOKEN_ENDPOINT));
credentials.setClientId(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CLIENT_ID));
credentials.setClientSecret(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CLIENT_SECRET));
credentials.setGrantType(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_GRANT_TYPE));
case OAUTH2:
OAuth2Credentials oauth2Credentials = new OAuth2Credentials();
oauth2Credentials.setTokenEndpoint(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TOKEN_ENDPOINT));
oauth2Credentials.setClientId(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CLIENT_ID));
oauth2Credentials.setClientSecret(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CLIENT_SECRET));
oauth2Credentials.setGrantType(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_GRANT_TYPE));
credentials = oauth2Credentials;
break;
default:
LOGGER.error(KruizeConstants.AuthenticationConstants.UNKNOWN_AUTHENTICATION + "{}", type);
Expand All @@ -63,7 +70,7 @@ public static AuthenticationConfig createAuthenticationConfigObject(JSONObject a

// Static method to return a no-auth config
public static AuthenticationConfig noAuth() {
return new AuthenticationConfig(AnalyzerConstants.NONE, null);
return new AuthenticationConfig(AuthType.NONE, null);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@
public class AuthenticationStrategyFactory {

public static AuthenticationStrategy createAuthenticationStrategy(AuthenticationConfig authConfig) {
String type = authConfig.getType();
AuthType type = authConfig.getType();
switch (type) {
case KruizeConstants.AuthenticationConstants.NONE:
case NONE:
return new NoAuthStrategy();
case KruizeConstants.AuthenticationConstants.BASIC:
String username = authConfig.getCredentials().getUsername();
String password = authConfig.getCredentials().getPassword();
case BASIC:
String username = ((BasicAuthCredentials) authConfig.getCredentials()).getUsername();
String password = ((BasicAuthCredentials) authConfig.getCredentials()).getPassword();
return new BasicAuthenticationStrategy(username, password);
case KruizeConstants.AuthenticationConstants.BEARER:
String tokenFilePath = authConfig.getCredentials().getTokenFilePath();
case BEARER:
String tokenFilePath = ((BearerTokenCredentials) authConfig.getCredentials()).getTokenFilePath();
return new BearerAuthenticationStrategy(tokenFilePath);
case KruizeConstants.AuthenticationConstants.API_KEY:
String apiKey = authConfig.getCredentials().getApiKey();
case API_KEY:
String apiKey = ((ApiKeyCredentials) authConfig.getCredentials()).getApiKey();
return new APIKeyAuthenticationStrategy(apiKey);
case KruizeConstants.AuthenticationConstants.OAUTH2:
String tokenEndpoint = authConfig.getCredentials().getTokenEndpoint();
String clientId = authConfig.getCredentials().getClientId();
String clientSecret = authConfig.getCredentials().getClientSecret();
case OAUTH2:
String tokenEndpoint = ((OAuth2Credentials) authConfig.getCredentials()).getTokenEndpoint();
String clientId = ((OAuth2Credentials) authConfig.getCredentials()).getClientId();
String clientSecret = ((OAuth2Credentials) authConfig.getCredentials()).getClientSecret();
return new OAuth2AuthenticationStrategy(tokenEndpoint, clientId, clientSecret);
default:
throw new IllegalArgumentException(KruizeConstants.AuthenticationConstants.UNKNOWN_AUTHENTICATION+ type);
Expand Down
108 changes: 49 additions & 59 deletions src/main/java/com/autotune/common/auth/Credentials.java
Original file line number Diff line number Diff line change
@@ -1,108 +1,98 @@
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 abstract class Credentials {
}

public String getUsername() {
return username;
}
class OAuth2Credentials extends Credentials {
private String grantType;
private String clientId;
private String clientSecret;
private String tokenEndpoint;

public String getGrantType() {
return grantType;
}

public String getClientSecret() {
return clientSecret;
public void setGrantType(String grantType) {
this.grantType = grantType;
}

public String getClientId() {
return clientId;
}

public String getTokenEndpoint() {
return tokenEndpoint;
}

public String getHeaderName() {
return headerName;
public void setClientId(String clientId) {
this.clientId = clientId;
}

public String getApiKey() {
return apiKey;
public String getClientSecret() {
return clientSecret;
}

public String getTokenFilePath() {
return tokenFilePath;
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}

public String getPassword() {
return password;
public String getTokenEndpoint() {
return tokenEndpoint;
}

public void setGrantType(String grantType) {
this.grantType = grantType;
public void setTokenEndpoint(String tokenEndpoint) {
this.tokenEndpoint = tokenEndpoint;
}
}

public void setClientId(String clientId) {
this.clientId = clientId;
}
class BasicAuthCredentials extends Credentials {
private String username;
private String password;

public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

public void setTokenEndpoint(String tokenEndpoint) {
this.tokenEndpoint = tokenEndpoint;
class BearerTokenCredentials extends Credentials {
private String tokenFilePath;

public String getTokenFilePath() {
return tokenFilePath;
}

public void setTokenFilePath(String tokenFilePath) {
this.tokenFilePath = tokenFilePath;
}
}

class ApiKeyCredentials extends Credentials {
private String apiKey;
private String headerName;

public String getApiKey() {
return apiKey;
}

public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}

public void setHeaderName(String headerName) {
this.headerName = headerName;
public String getHeaderName() {
return 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 + '\'' +
'}';
public void setHeaderName(String headerName) {
this.headerName = headerName;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -165,16 +165,15 @@ public void addDataSourcesFromConfigFile(String configFileName) {

DataSourceInfo datasource;
// Validate input
if (!validateInput(name, provider, serviceName, dataSourceURL, namespace)) {
if (!validateInput(name, provider, serviceName, dataSourceURL, namespace)) { //TODO: add validations for auth
continue;
}
if (dataSourceURL.isEmpty()) {
datasource = new DataSourceInfo(name, provider, serviceName, namespace, null);
datasource = new DataSourceInfo(name, provider, serviceName, namespace, null, authConfig);
} else {
datasource = new DataSourceInfo(name, provider, serviceName, namespace, new URL(dataSourceURL));
datasource = new DataSourceInfo(name, provider, serviceName, namespace, new URL(dataSourceURL), authConfig);
}
// set the authentication config
datasource.setAuthenticationConfig(authConfig);
// add the datasource
addDataSource(datasource);
}
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class DataSourceInfo {

private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DataSourceInfo.class);

public DataSourceInfo(String name, String provider, String serviceName, String namespace, URL url) {
public DataSourceInfo(String name, String provider, String serviceName, String namespace, URL url, AuthenticationConfig authConfig) {
this.name = name;
this.provider = provider;
if (null == url) {
Expand All @@ -54,6 +54,7 @@ public DataSourceInfo(String name, String provider, String serviceName, String n
}
this.serviceName = serviceName;
this.namespace = namespace;
this.authenticationConfig = authConfig;
}

/**
Expand Down Expand Up @@ -135,7 +136,6 @@ public String toString() {
", serviceName='" + serviceName + '\'' +
", namespace='" + namespace + '\'' +
", url=" + url +
", authenticationConfig=" + authenticationConfig +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
import com.autotune.analyzer.exceptions.MonitoringAgentNotFoundException;
import com.autotune.analyzer.exceptions.TooManyRecursiveCallsException;
import com.autotune.analyzer.utils.AnalyzerConstants;
import com.autotune.common.auth.AuthenticationConfig;
import com.autotune.common.auth.AuthenticationStrategy;
import com.autotune.common.auth.AuthenticationStrategyFactory;
import com.autotune.common.datasource.prometheus.PrometheusDataOperatorImpl;
import com.autotune.common.exceptions.datasource.ServiceNotFound;
import com.autotune.common.target.kubernetes.service.KubernetesServices;
Expand Down Expand Up @@ -199,7 +196,7 @@ public static DataSourceInfo getMonitoringAgent(String dataSource) throws Monito
monitoringAgentEndpoint = getServiceEndpoint(KruizeDeploymentInfo.monitoring_service);
}
if (dataSource.equals(AnalyzerConstants.PROMETHEUS_DATA_SOURCE)) {
monitoringAgent = new DataSourceInfo(KruizeDeploymentInfo.monitoring_agent, AnalyzerConstants.PROMETHEUS_DATA_SOURCE, null, null, new URL(monitoringAgentEndpoint));
monitoringAgent = new DataSourceInfo(KruizeDeploymentInfo.monitoring_agent, AnalyzerConstants.PROMETHEUS_DATA_SOURCE, null, null, new URL(monitoringAgentEndpoint), null);
}
}

Expand Down
Loading

0 comments on commit 177cb49

Please sign in to comment.