Skip to content

Commit

Permalink
Add command to tag a log group with current project and env
Browse files Browse the repository at this point in the history
  • Loading branch information
cartwrightian committed Sep 20, 2018
1 parent 7ae1b21 commit 880abb5
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 18 deletions.
4 changes: 4 additions & 0 deletions src/tw/com/AwsFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -653,4 +653,8 @@ public void removeCloudWatchLogsOlderThan(ProjectAndEnv projectAndEnv, int days)
});

}

public void tagCloudWatchLog(ProjectAndEnv projectAndEnv, String groupName) {
logRepository.tagCloudWatchLog(projectAndEnv, groupName);
}
}
1 change: 1 addition & 0 deletions src/tw/com/commandline/Actions.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,6 @@ private void createActions() {
actions.add(new AllowHostAction());
actions.add(new BlockHostAction());
actions.add(new RemoveLogsAction());
actions.add(new TagLogAction());
}
}
3 changes: 1 addition & 2 deletions src/tw/com/commandline/actions/RemoveLogsAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ public void invoke(FacadeFactory factory, ProjectAndEnv projectAndEnv, Collectio
AwsFacade aws = factory.createFacade();
try {
int days = Integer.parseInt(args[0]);
DateTime timeStamp = DateTime.now();
aws.removeCloudWatchLogsOlderThan(projectAndEnv, days);
aws.removeCloudWatchLogsOlderThan(projectAndEnv, days);
}
catch (NumberFormatException parseFailed) {
throw new CfnAssistException("Unable to parse number of weeks " + args[0]);
Expand Down
54 changes: 54 additions & 0 deletions src/tw/com/commandline/actions/TagLogAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package tw.com.commandline.actions;

import com.amazonaws.services.cloudformation.model.Parameter;
import org.apache.commons.cli.MissingArgumentException;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tw.com.AwsFacade;
import tw.com.FacadeFactory;
import tw.com.commandline.CommandLineException;
import tw.com.entity.ProjectAndEnv;
import tw.com.exceptions.CfnAssistException;

import java.util.Collection;

public class TagLogAction extends SharedAction {
private static final Logger logger = LoggerFactory.getLogger(TagLogAction.class);

@SuppressWarnings("static-access")
public TagLogAction() {
createOptionWithArgs("tagLog", "Tags the named group with current project and env", 1);
}

public void invoke(FacadeFactory factory, ProjectAndEnv projectAndEnv, Collection<Parameter> unused,
Collection<Parameter> artifacts, String... args) throws CfnAssistException, MissingArgumentException, InterruptedException {
logger.info("Invoking removeLogs for " + projectAndEnv + " and " + args[0]);
AwsFacade aws = factory.createFacade();
String groupName = args[0];
aws.tagCloudWatchLog(projectAndEnv, groupName);
}

@Override
public void validate(ProjectAndEnv projectAndEnv, Collection<Parameter> cfnParams,
Collection<Parameter> artifacts, String... argumentForAction)
throws CommandLineException {
guardForProjectAndEnv(projectAndEnv);
}

@Override
public boolean usesProject() {
return true;
}

@Override
public boolean usesComment() {
return false;
}

@Override
public boolean usesSNS() {
return true;
}

}
12 changes: 12 additions & 0 deletions src/tw/com/providers/LogClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.amazonaws.services.logs.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tw.com.AwsFacade;
import tw.com.entity.ProjectAndEnv;

import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -53,4 +55,14 @@ private List<LogGroup> getLogGroups() {
DescribeLogGroupsResult result = theClient.describeLogGroups();
return result.getLogGroups();
}

public void tagGroupFor(ProjectAndEnv projectAndEnv, String groupToTag) {
logger.info(format("Tag log group %s with %s", groupToTag, projectAndEnv));

TagLogGroupRequest request = new TagLogGroupRequest().withLogGroupName(groupToTag);
request.addTagsEntry(AwsFacade.ENVIRONMENT_TAG, projectAndEnv.getEnv());
request.addTagsEntry(AwsFacade.PROJECT_TAG, projectAndEnv.getProject());
theClient.tagLogGroup(request);

}
}
12 changes: 11 additions & 1 deletion src/tw/com/repository/LogRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,20 @@ public void removeOldStreamsFor(String groupName, Duration duration) {

streams.stream().filter(logStream -> (logStream.getLastEventTimestamp()<when))
.forEach(oldStream -> {
DateTime last = new DateTime(oldStream.getLastEventTimestamp());
logger.info(format("Deleting stream %s from group %s, last event was %s", oldStream.getLogStreamName(),
groupName, oldStream.getLastEventTimestamp()));
groupName, last));
logClient.deleteLogStream(groupName, oldStream.getLogStreamName());
});

}

public void tagCloudWatchLog(ProjectAndEnv projectAndEnv, String groupToTag) {
List<String> currnet = logGroupsFor(projectAndEnv);
if (currnet.contains(groupToTag)) {
logger.warn(format("Group %s is already tagged for %s", groupToTag, projectAndEnv));
return;
}
logClient.tagGroupFor(projectAndEnv, groupToTag);
}
}
8 changes: 8 additions & 0 deletions test/tw/com/CLIArgBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -339,4 +339,12 @@ public static String[] tidyCloudWatch(Integer weeks) {
"-removeLogs", weeks.toString()
};
}

public static String[] tagCloudWatchLog(String logGroupName) {
return new String[]{
"-env", EnvironmentSetupForTests.ENV,
"-project", EnvironmentSetupForTests.PROJECT,
"-tagLog", logGroupName
};
}
}
19 changes: 19 additions & 0 deletions test/tw/com/integration/TestLogClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import com.amazonaws.services.logs.AWSLogs;
import com.amazonaws.services.logs.model.*;
import org.junit.*;
import tw.com.AwsFacade;
import tw.com.EnvironmentSetupForTests;
import tw.com.entity.ProjectAndEnv;
import tw.com.providers.LogClient;

import java.util.HashMap;
Expand Down Expand Up @@ -71,4 +73,21 @@ public void shouldGetAndDeleteLogStream() {
List<String> names = actual.getLogStreams().stream().map(stream -> stream.getLogStreamName()).collect(Collectors.toList());
assertFalse(names.contains(streamName));
}

@Test
public void shouldTagAGroupWithProjectAndEnv() {
ProjectAndEnv projectAndEnv = EnvironmentSetupForTests.getMainProjectAndEnv();

logClient.tagGroupFor(projectAndEnv, TEST_LOG_GROUP);

ListTagsLogGroupResult actual = awsLogs.listTagsLogGroup(new ListTagsLogGroupRequest().withLogGroupName(TEST_LOG_GROUP));

Map<String, String> result = actual.getTags();
assertTrue(result.containsKey(AwsFacade.PROJECT_TAG));
assertTrue(result.containsKey(AwsFacade.ENVIRONMENT_TAG));

assertEquals(projectAndEnv.getProject(), result.get(AwsFacade.PROJECT_TAG));
assertEquals(projectAndEnv.getEnv(), result.get(AwsFacade.ENVIRONMENT_TAG));

}
}
14 changes: 12 additions & 2 deletions test/tw/com/unit/TestAwsFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,8 @@ public void shouldSetAndResetDeltaIndex() throws CannotFindVpcException {

@Test
public void shouldDeleteLogsOverNWeeksOld() {
DateTime timeStamp = DateTime.now();

List<String> groups = Arrays.asList("groupA","groupB");
List<String> groups = Arrays.asList("groupA","groupB");
EasyMock.expect(logRepository.logGroupsFor(projectAndEnv)).andReturn(groups);
logRepository.removeOldStreamsFor("groupA", Duration.ofDays(42));
EasyMock.expectLastCall();
Expand All @@ -147,6 +146,17 @@ public void shouldDeleteLogsOverNWeeksOld() {
aws.removeCloudWatchLogsOlderThan(projectAndEnv, 42);
verifyAll();
}

@Test
public void shouldTagCloudWatchLogWithEnvAndProject() {

logRepository.tagCloudWatchLog(projectAndEnv, "groupToTag");
EasyMock.expectLastCall();

replayAll();
aws.tagCloudWatchLog(projectAndEnv, "groupToTag");
verifyAll();
}

@Test
public void shouldThrowForUnknownProjectAndEnvCombinationOnDeltaSet() throws CannotFindVpcException {
Expand Down
10 changes: 10 additions & 0 deletions test/tw/com/unit/TestCommandLineActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,16 @@ public void shouldTidyOldCloudwatchLogs() throws InterruptedException, MissingAr
validate(CLIArgBuilder.tidyCloudWatch(days));
}

@Test
public void shouldTagCloudwatchLog() throws InterruptedException, MissingArgumentException, CfnAssistException {
setFactoryExpectations();

facade.tagCloudWatchLog(projectAndEnv, "logGroupName");
EasyMock.expectLastCall();

validate(CLIArgBuilder.tagCloudWatchLog("logGroupName"));
}

@Test
public void testShouldBlockHostOnELB() throws MissingArgumentException, CfnAssistException, InterruptedException, UnknownHostException {
setFactoryExpectations();
Expand Down
54 changes: 41 additions & 13 deletions test/tw/com/unit/TestLogRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,7 @@ public void beforeEachTestRuns() {
@Test
public void shouldFilterGroupsByTags() {
Map<String, Map<String, String>> groups = new HashMap<>();
Map<String, String> groupATags = new HashMap<>();
Map<String, String> groupBTags = new HashMap<>();
Map<String, String> groupCTags = new HashMap<>();

groupATags.put("X", "value");
groupBTags.put(AwsFacade.ENVIRONMENT_TAG, projectAndEnv.getEnv());
groupBTags.put(AwsFacade.PROJECT_TAG, projectAndEnv.getProject());
groupCTags.put(AwsFacade.ENVIRONMENT_TAG, "wrongEnv");
groupCTags.put(AwsFacade.PROJECT_TAG, "wrongProject");

groups.put("groupA", groupATags);
groups.put("groupB", groupBTags);
groups.put("groupC", groupCTags);
createExistingGroups(groups);
EasyMock.expect(logClient.getGroupsWithTags()).andReturn(groups);

replayAll();
Expand Down Expand Up @@ -83,7 +71,47 @@ public void shouldRemoveOldStreamsForGroupList() {
verifyAll();
}

@Test
public void shouldTagGroupWithEnvAndProject() {
Map<String, Map<String, String>> groups = new HashMap<>();
createExistingGroups(groups);
EasyMock.expect(logClient.getGroupsWithTags()).andReturn(groups);
logClient.tagGroupFor(projectAndEnv, "groupA");
EasyMock.expectLastCall();

replayAll();
logRepository.tagCloudWatchLog(projectAndEnv, "groupA");
verifyAll();
}

@Test
public void shouldNotTagIfAlreadyDoneAndMatches() {
Map<String, Map<String, String>> groups = new HashMap<>();
createExistingGroups(groups);
EasyMock.expect(logClient.getGroupsWithTags()).andReturn(groups);

replayAll();
logRepository.tagCloudWatchLog(projectAndEnv, "groupB");
verifyAll();
}

private LogStream createStream(long offset, String streamName) {
return new LogStream().withLogStreamName(streamName).withLastEventTimestamp(offset);
}

private void createExistingGroups(Map<String, Map<String, String>> groups) {
Map<String, String> groupATags = new HashMap<>();
Map<String, String> groupBTags = new HashMap<>();
Map<String, String> groupCTags = new HashMap<>();

groupATags.put("X", "value");
groupBTags.put(AwsFacade.ENVIRONMENT_TAG, projectAndEnv.getEnv());
groupBTags.put(AwsFacade.PROJECT_TAG, projectAndEnv.getProject());
groupCTags.put(AwsFacade.ENVIRONMENT_TAG, "wrongEnv");
groupCTags.put(AwsFacade.PROJECT_TAG, "wrongProject");

groups.put("groupA", groupATags);
groups.put("groupB", groupBTags);
groups.put("groupC", groupCTags);
}
}

0 comments on commit 880abb5

Please sign in to comment.