/** * Some machines require a TTY for sudo. Brooklyn by default does not use a TTY * so that it can get separate STDERR and STDOUT streams. You can enable a TTY as an * option to every SSH command, or you can do it once and modify the machine so that * a TTY is not subsequently required. If this task has already been executed it * will try to detect the changes and do nothing. * <p> * This command must be run with allocatePTY set as a flag to ssh. * See {@link SshTasks#dontRequireTtyForSudo(SshMachineLocation, OnFailingTask)} which sets that up. * <p> * Having a TTY for sudo seems like another case of imaginary security which is just irritating. * Like water restrictions at airport security. */ public static String dontRequireTtyForSudo() { String sudoersFileName = "/etc/sudoers"; String tmpSuffix = Identifiers.makeRandomLowercaseId(6); // Avoid clobbering // Visudo's quiet mode (-q) is not enabled. visudo's output is used for diagnostic purposes return ifFileExistsElse0(sudoersFileName, alternatives( sudo(format("grep brooklyn-removed-require-tty %s", sudoersFileName)), chainGroup( sudo(format("cp %1$s %1$s.%2$s", sudoersFileName, tmpSuffix)), sudo(format("sed -i.brooklyn.bak 's/.*requiretty.*/#brooklyn-removed-require-tty/' %1$s.%2$s", sudoersFileName, tmpSuffix)), sudo(format("visudo -c -f %1$s.%2$s", sudoersFileName, tmpSuffix)), sudo(format("mv %1$s.%2$s %1$s", sudoersFileName, tmpSuffix))))); }
private void testSecurityEditorOnMachine(int n, final JcloudsSshMachineLocation machine) throws ExecutionException, InterruptedException { final Location location = machine.getNode().getLocation(); ComputeService computeService = machine.getParent().getComputeService(); final Optional<SecurityGroupExtension> securityApi = computeService.getSecurityGroupExtension(); final SecurityGroupEditor editor = new SecurityGroupEditor(location, securityApi.get()); List<ListenableFuture<?>> futures = Lists.newArrayList(); for (int c = 0; c < n; c++) { final String id = "sgtest-" + Identifiers.makeRandomLowercaseId(6) + "-" + String.valueOf(c); final Runnable task = new Runnable() { @Override public void run() { doOneSecurityEditorOperationCycle(id, editor, machine); } }; ListenableFuture<?> future = executor.submit(task); futures.add(future); } assertTasksDoneSuccessfully(futures); }
private String id = Identifiers.makeRandomLowercaseId(10);
@Test public void testCreateGroupAddPermissionsAndDelete() { SecurityGroupDefinition sgDef = new SecurityGroupDefinition() .allowingInternalPorts(8097, 8098) .allowingInternalPortRange(6000, 7999) .allowingPublicPort(8099); final String securityGroupName = Identifiers.makeRandomLowercaseId(15); final SecurityGroupEditor editor = makeEditor(); final SecurityGroup testGroup = createTestGroup(securityGroupName, editor); assertEquals(testGroup.getName(), "jclouds#" + securityGroupName); final SecurityGroup updated = editor.addPermissions(testGroup, sgDef.getPermissions()); final Optional<SecurityGroup> fromCloud = editor.findSecurityGroupByName(securityGroupName); assertTrue(fromCloud.isPresent()); final SecurityGroup cloudGroup = fromCloud.get(); assertPermissionsEqual(updated.getIpPermissions(), cloudGroup.getIpPermissions()); editor.removeSecurityGroup(updated); final Optional<SecurityGroup> afterRemove = editor.findSecurityGroupByName(securityGroupName); assertFalse(afterRemove.isPresent()); }
@Test public void testGroupAddIsIdempotent() { SecurityGroupDefinition sgDef = new SecurityGroupDefinition() .allowingInternalPorts(8097, 8098) .allowingInternalPortRange(6000, 7999) .allowingPublicPort(8099); final String securityGroupName = Identifiers.makeRandomLowercaseId(15); final SecurityGroupEditor editor = makeEditor(); SecurityGroup group1 = createTestGroup(securityGroupName, editor); assertEquals(group1.getName(), "jclouds#" + securityGroupName); group1 = editor.addPermissions(group1, sgDef.getPermissions()); final SecurityGroup group2 = createTestGroup(securityGroupName, editor); assertEquals(group2.getName(), group1.getName()); assertPermissionsEqual(group2.getIpPermissions(), group1.getIpPermissions()); editor.removeSecurityGroup(group2); final Optional<SecurityGroup> afterRemove = editor.findSecurityGroupByName(securityGroupName); assertFalse(afterRemove.isPresent()); }
@Test public void testPermissionsAddIsIdempotent() { SecurityGroupDefinition sgDef = new SecurityGroupDefinition() .allowingInternalPorts(8097, 8098) .allowingInternalPortRange(6000, 7999) .allowingPublicPort(8099); final String securityGroupName = Identifiers.makeRandomLowercaseId(15); final SecurityGroupEditor editor = makeEditor(); SecurityGroup group1 = createTestGroup(securityGroupName, editor); assertEquals(group1.getName(), "jclouds#" + securityGroupName); final SecurityGroup before = editor.addPermissions(group1, sgDef.getPermissions()); assertPermissionsEqual(ImmutableSet.copyOf(sgDef.getPermissions()), before.getIpPermissions()); try { final SecurityGroup after = editor.addPermissions(before, sgDef.getPermissions()); assertPermissionsEqual(before.getIpPermissions(), after.getIpPermissions()); } catch (Exception e) { // catch here so as to give us the chance to delete the group rather than leak it (this is a live test) fail("Exception repeating group permissions", e); } editor.removeSecurityGroup(group1); final Optional<SecurityGroup> afterRemove = editor.findSecurityGroupByName(securityGroupName); assertFalse(afterRemove.isPresent()); }