Skip to content
This repository has been archived by the owner on Jul 31, 2023. It is now read-only.

Commit

Permalink
Merge pull request #63 from kappnav/152-usernameSpecialChar-moveToAnn…
Browse files Browse the repository at this point in the history
…otations

Move command action user from label to annotation
  • Loading branch information
kinueng authored Mar 4, 2020
2 parents d6fd6f7 + f49d15e commit a04343c
Showing 1 changed file with 101 additions and 19 deletions.
120 changes: 101 additions & 19 deletions src/main/java/application/rest/v1/ActionsEndpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ public class ActionsEndpoint extends KAppNavEndpoint {
private static final String KAPPNAV_JOB_ACTION_TEXT = "kappnav-job-action-text";

// App nav job labels
private static final String LABELS_PROPERTY_NAME = "labels";
private static final String KAPPNAV_JOB_TYPE = "kappnav-job-type";
private static final String KAPPNAV_JOB_ACTION_NAME = "kappnav-job-action-name";
private static final String KAPPNAV_JOB_USER_ID = "kappnav-job-user-id";

private static final String KAPPNAV_JOB_COMPONENT_KIND = "kappnav-job-component-kind";
private static final String KAPPNAV_JOB_COMPONENT_SUB_KIND = "kappnav-job-component-sub-kind";
Expand All @@ -131,6 +131,12 @@ public class ActionsEndpoint extends KAppNavEndpoint {

private static final String STATUS_PROPERTY_NAME = "status";
private static final String COMPLETION_TIME_PROPERTY_NAME = "completionTime";

// Annotation properties.
private static final String METADATA_PROPERTY_NAME = "metadata";
private static final String ANNOTATIONS_PROPERTY_NAME = "annotations";
private static final String KAPPNAV_JOB_USER_ID = "kappnav-job-user-id";

@Inject
private ComponentInfoRegistry registry;

Expand Down Expand Up @@ -293,9 +299,6 @@ public Response getCommands(@CookieParam("kappnav-user") @DefaultValue("") @Para

// Build the selector for the query.
final Selector s = new Selector().addMatchLabel(KAPPNAV_JOB_TYPE, KAPPNAV_JOB_COMMAND_TYPE);
if (user != null && !user.isEmpty()) {
s.addMatchLabel(KAPPNAV_JOB_USER_ID, user);
}

// convert time to timestamp in yyyy-MM-dd'T'HH:mm:sss format
Timestamp timelaterTimestamp = convertTimeStringToTimestamp(time);
Expand All @@ -313,10 +316,20 @@ public Response getCommands(@CookieParam("kappnav-user") @DefaultValue("") @Para
List<JsonObject> commands = getItemsAsList(client, batch.listNamespacedJob(GLOBAL_NAMESPACE, null, null, null, null, labelSelector, null, null, null, null));
final CommandsResponse response = new CommandsResponse();

commands.forEach(v -> {
commands.forEach(v -> {
if (v.get(KIND_PROPERTY_NAME) == null) {
v.addProperty(KIND_PROPERTY_NAME, JOB_KIND);
}
}

if(user != null && !user.isEmpty()) {
// Only return jobs belonging to the user
final String job_username = getCommandActionUserName(v);
if(! user.equals(job_username)) {
// Completely skip this command because it does
// not belong to the user requested by the API caller
return;
}
}

if (time == null || time.isEmpty()) {
//no time specified, return all jobs
Expand Down Expand Up @@ -345,6 +358,7 @@ public Response getCommands(@CookieParam("kappnav-user") @DefaultValue("") @Para
}
}
});

// If there are jobs, get actions available for jobs and add to response
if ( ! commands.isEmpty() && response.size() > 0) {
JsonObject job= commands.get(0); // get first job, any job, so we can retrieve actions
Expand Down Expand Up @@ -525,10 +539,15 @@ private String resolve(ApiClient client, String name, String kind, String apiVer
return resolvedValue.getValue();
}

private Response executeCommand(String jsonstr, String name, String kind, String apiVersion, String namespace, String commandName, String appName, String appNamespace, String user) {
String methodName = "executeCommand";
private Response executeCommand(String jsonstr, String name, String kind, String apiVersion, String namespace,
String commandName, String appName, String appNamespace, String user) {

final String methodName = "executeCommand";
if (Logger.isErrorEnabled()) {
Logger.log(className, methodName, Logger.LogType.ENTRY, "Name=" + name + ", kind="+ kind + ", apiVersion="+apiVersion + ", namespace="+namespace + ", commandName="+commandName + ", appName="+appName + ", appNamespace=" + appNamespace + ", user=" +user);
Logger.log(className, methodName, Logger.LogType.ENTRY,
"name=" + name + ", kind=" + kind + ", apiVersion=" + apiVersion + ", namespace=" + namespace
+ ", commandName=" + commandName + ", appName=" + appName + ", appNamespace=" + appNamespace
+ ", user=" + user);
}

try {
Expand Down Expand Up @@ -630,10 +649,10 @@ private Response executeCommand(String jsonstr, String name, String kind, String

// Add context labels to the job, allowing for queries using selectors.
final Map<String,String> labels = createJobLabels(client, resource, name, kind,
namespace, appName, appNamespace, commandName, user);
namespace, appName, appNamespace, commandName);
meta.setLabels(labels);

final Map<String,String> annotations = createJobAnnotations(text);
final Map<String,String> annotations = createJobAnnotations(text, user);
if (annotations != null) {
meta.setAnnotations(annotations);
}
Expand Down Expand Up @@ -733,27 +752,33 @@ private void setSecurityContextAndServiceAccountName(ApiClient client, V1PodSpec
spec.setServiceAccountName(config.getkAppNavServiceAccountName());
}

private Map<String,String> createJobAnnotations(String text) {
private Map<String,String> createJobAnnotations(String text, String user) {
Map<String, String> annotations = new HashMap<String, String>();

if (text != null && !text.isEmpty()) {
return Collections.singletonMap(KAPPNAV_JOB_ACTION_TEXT, text);
annotations.put(KAPPNAV_JOB_ACTION_TEXT, text);
}
if(user != null && !user.isEmpty()) {
annotations.put(KAPPNAV_JOB_USER_ID, user);
}

if(! annotations.isEmpty()) {
return Collections.unmodifiableMap(annotations);
}
return null;
}

private Map<String,String> createJobLabels(ApiClient client, JsonObject resource, String name, String kind,
String namespace, String appName, String appNamespace, String actionName, String userId) {
String namespace, String appName, String appNamespace, String actionName) {
String methodName = "createJobLabels";
if (Logger.isEntryEnabled()) {
Logger.log(className, methodName, Logger.LogType.ENTRY, "Resource=" + resource.toString() + ", name="+ name + ", kind=" + kind + ", namespace="+namespace + ", appName=" + appName + ", appNamespace=" + appNamespace + ", actionName=" + actionName + ", userId="+userId);
Logger.log(className, methodName, Logger.LogType.ENTRY, "Resource=" + resource.toString() + ", name="+ name + ", kind=" + kind + ", namespace="+namespace + ", appName=" + appName + ", appNamespace=" + appNamespace + ", actionName=" + actionName);
}

final Map<String,String> labels = new HashMap<>();
labels.put(KAPPNAV_JOB_TYPE, KAPPNAV_JOB_COMMAND_TYPE);
labels.put(KAPPNAV_JOB_ACTION_NAME, actionName);
// Set the user id if it's available.
if (userId != null && !userId.isEmpty()) {
labels.put(KAPPNAV_JOB_USER_ID, userId);
}

// If appName is not set this resource is an application. Only set the application labels.
if (appName == null || appName.isEmpty()) {
labels.put(KAPPNAV_JOB_APPLICATION_NAME, name);
Expand Down Expand Up @@ -871,4 +896,61 @@ private static String urlDecode(String value) {
throw new RuntimeException(ex.getCause());
}
}

/**
* Return the username associated with the command action
* @param commandAction - JsonObject of the command action details
* @return String - username who created the command action, else empty String
*/
private String getCommandActionUserName(JsonObject commandAction) {
final String methodName = "getCommandUserName";
if (Logger.isEntryEnabled()) {
Logger.log(className, methodName, Logger.LogType.ENTRY, "job=" + commandAction);
}
String result = "";

//
// Look for the username in the annotations
//
final JsonObject metadata = commandAction.getAsJsonObject(METADATA_PROPERTY_NAME);
if (metadata != null) {
final JsonObject annotations = metadata.getAsJsonObject(ANNOTATIONS_PROPERTY_NAME);
if (annotations != null) {
final JsonElement userId = annotations.get(KAPPNAV_JOB_USER_ID);
if (userId != null) {
result = userId.getAsString();
if (Logger.isDebugEnabled()) {
Logger.log(className, methodName, Logger.LogType.DEBUG, "userId=" + userId);
}
}
}
}

//
// Legacy Command Actions:
// Look for the username in the labels, if we did not find the username
// in the annotations
//
if(result != null && result.isEmpty()) {
if (metadata != null) {
final JsonObject metadataObj = metadata.getAsJsonObject();
final JsonElement labels = metadataObj.get(LABELS_PROPERTY_NAME);
if (labels != null && labels.isJsonObject()) {
final JsonObject labelsObj = labels.getAsJsonObject();
final JsonElement legacy_userId = labelsObj.get(KAPPNAV_JOB_USER_ID);
if (legacy_userId != null) {
result = legacy_userId.getAsString();
if (Logger.isDebugEnabled()) {
Logger.log(className, methodName, Logger.LogType.DEBUG, "legacy_userId=" + legacy_userId);
}
}
}
}
}

if (Logger.isExitEnabled()) {
Logger.log(className, methodName, Logger.LogType.EXIT, "result=" + result);
}
return result;
}
}

0 comments on commit a04343c

Please sign in to comment.