Skip to content
Browse files

env specific servers, ec2 security groups started, better elb model

  • Loading branch information...
1 parent 294732e commit 85d65edb1829f4b98f4bd2ecd5a3cb93a9cc9425 @brianm brianm committed Dec 7, 2011
View
1 .gitignore
@@ -1,3 +1,4 @@
+src/test/java/com/ning/atlas/TestAWSLocal.java
atlas.log
.atlasrc
.DS_Store
View
2 pom.xml
@@ -24,7 +24,7 @@
<dependency>
<groupId>org.skife.terminal</groupId>
<artifactId>java-progress-bar</artifactId>
- <version>0.0.2</version>
+ <version>0.0.3</version>
</dependency>
<dependency>
View
28 src/main/java/com/ning/atlas/Environment.java
@@ -1,5 +1,6 @@
package com.ning.atlas;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -12,17 +13,19 @@
import com.ning.atlas.spi.space.Space;
import org.apache.commons.lang3.builder.ToStringBuilder;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class Environment
{
- private final List<String> listeners = Lists.newArrayList();
+ private final List<String> listeners = Lists.newArrayList();
private final Map<String, Base> bases = Maps.newConcurrentMap();
private final Map<String, String> properties = Maps.newConcurrentMap();
- private final PluginSystem plugins;
+ private final PluginSystem plugins;
+ private final Collection<Template> environmentDefinedElements;
public Environment()
{
@@ -31,7 +34,8 @@ public Environment()
Collections.<String, Map<String, String>>emptyMap(),
Collections.<String, Map<String, String>>emptyMap(),
Collections.<String, Base>emptyMap(),
- Collections.<String, String>emptyMap());
+ Collections.<String, String>emptyMap(),
+ Collections.<Template>emptyList());
}
public Environment(PluginSystem plugins,
@@ -41,7 +45,20 @@ public Environment(PluginSystem plugins,
Map<String, Base> bases,
Map<String, String> properties)
{
+ this(plugins, provisioners, installers, listeners, bases, properties, Collections.<Template>emptyList());
+ }
+
+ public Environment(PluginSystem plugins,
+ Map<String, Map<String, String>> provisioners,
+ Map<String, Map<String, String>> installers,
+ Map<String, Map<String, String>> listeners,
+ Map<String, Base> bases,
+ Map<String, String> properties,
+ Collection<Template> environmentDefinedElements)
+ {
this.plugins = plugins;
+ this.environmentDefinedElements = ImmutableList.copyOf(environmentDefinedElements);
+
for (Map.Entry<String, Map<String, String>> entry : provisioners.entrySet()) {
plugins.registerProvisionerConfig(entry.getKey(), entry.getValue());
}
@@ -121,4 +138,9 @@ public PluginSystem getPluginSystem()
{
return this.plugins;
}
+
+ public Collection<Template> getEnvironmentDefinedElements()
+ {
+ return environmentDefinedElements;
+ }
}
View
8 src/main/java/com/ning/atlas/SystemMap.java
@@ -13,19 +13,17 @@
public class SystemMap
{
private final List<Element> roots;
- private final Environment env;
public SystemMap() {
- this(Collections.<Element>emptyList(), new Environment());
+ this(Collections.<Element>emptyList());
}
public SystemMap(Element... elements) {
- this(asList(elements), new Environment());
+ this(asList(elements));
}
- public SystemMap(List<Element> roots, Environment env)
+ public SystemMap(List<Element> roots)
{
- this.env = env;
this.roots = ImmutableList.copyOf(roots);
}
View
21 src/main/java/com/ning/atlas/Template.java
@@ -9,15 +9,16 @@
import org.apache.commons.lang3.builder.ToStringBuilder;
import javax.annotation.Nullable;
+import java.util.Collection;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
public abstract class Template implements Tree
{
private final List<String> cardinality;
- private final String type;
- private final My my;
+ private final String type;
+ private final My my;
public Template(String type, My my, List<?> cardinality)
{
@@ -61,8 +62,20 @@ public My getMy()
return my;
}
- public final SystemMap normalize(Environment env) {
- return new SystemMap(_normalize(Identity.root(), env), env);
+ public final SystemMap normalize(Environment env)
+ {
+ List<Element> roots = Lists.newArrayList();
+
+ List<Element> sys_roots = _normalize(Identity.root(), env);
+ roots.addAll(sys_roots);
+
+ Collection<Template> env_defined = env.getEnvironmentDefinedElements();
+ for (Template template : env_defined) {
+ List<Element> el = template._normalize(Identity.root(), env);
+ roots.addAll(el);
+ }
+
+ return new SystemMap(roots);
}
protected abstract List<Element> _normalize(Identity parent, Environment env);
View
7 src/main/java/com/ning/atlas/aws/EC2Provisioner.java
@@ -96,13 +96,18 @@ public String perform(final Host node, final Uri<? extends Component> uri, Deplo
}
req.setKeyName(keypairId.get());
+
+ final String security_group = Maybe.elideNull(uri.getParams().get("security_group")).otherwise("default");
+ req.setSecurityGroups(asList(security_group));
+
RunInstancesResult rs = ec2.runInstances(req);
final Instance i = rs.getReservation().getInstances().get(0);
- logger.debug("obtained ec2 instance {}", i.getInstanceId());
+ logger.debug("obtained ec2 instance %s", i.getInstanceId());
while (true) {
+
DescribeInstancesRequest dreq = new DescribeInstancesRequest();
dreq.setInstanceIds(Lists.newArrayList(i.getInstanceId()));
DescribeInstancesResult res = null;
View
164 src/main/java/com/ning/atlas/aws/EC2SecurityGroupProvisioner.java
@@ -0,0 +1,164 @@
+package com.ning.atlas.aws;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.services.ec2.AmazonEC2Client;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult;
+import com.amazonaws.services.ec2.model.IpPermission;
+import com.amazonaws.services.ec2.model.RevokeSecurityGroupIngressRequest;
+import com.amazonaws.services.ec2.model.SecurityGroup;
+import com.amazonaws.services.ec2.model.UserIdGroupPair;
+import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClient;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+import com.ning.atlas.ConcurrentComponent;
+import com.ning.atlas.Host;
+import com.ning.atlas.spi.Component;
+import com.ning.atlas.spi.Deployment;
+import com.ning.atlas.spi.Identity;
+import com.ning.atlas.spi.Uri;
+import com.ning.atlas.spi.protocols.AWS;
+import com.ning.atlas.spi.space.Missing;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.util.Arrays.asList;
+
+public class EC2SecurityGroupProvisioner extends ConcurrentComponent
+{
+ @Override
+ public String perform(Host host, Uri<? extends Component> uri, Deployment d) throws Exception
+ {
+ final String group_name = uri.getFragment();
+
+ AWSCredentials creds = d.getSpace().get(AWS.ID, AWS.Credentials.class, Missing.RequireAll)
+ .otherwise(new IllegalStateException("No AWS Credentials available"))
+ .toAWSCredentials();
+
+ AmazonEC2Client ec2 = new AmazonEC2Client(creds);
+ AmazonIdentityManagementClient iam = new AmazonIdentityManagementClient(creds);
+ String user_id = iam.getUser().getUser().getUserId();
+
+ Set<String> raw_rules = Sets.newHashSet();
+ for (Map.Entry<String, Collection<String>> entry : uri.getFullParams().entrySet()) {
+ raw_rules.addAll(entry.getValue());
+ }
+
+ List<Rule> rules = Lists.newArrayList();
+ for (String raw_thing : raw_rules) {
+ rules.add(Rule.parse(user_id, raw_thing));
+ }
+
+ DescribeSecurityGroupsRequest dsgreq = new DescribeSecurityGroupsRequest();
+ dsgreq.setGroupNames(asList(group_name));
+ DescribeSecurityGroupsResult dsgres = ec2.describeSecurityGroups(dsgreq);
+
+ SecurityGroup group = dsgres.getSecurityGroups().get(0);
+
+
+ // find permissions to remove
+
+ for (IpPermission permission : group.getIpPermissions()) {
+ // ensure all the allowances are there
+
+ }
+
+
+ return "okay";
+ }
+
+ @Override
+ public String unwind(Identity hostId, Uri<? extends Component> uri, Deployment d) throws Exception
+ {
+ throw new UnsupportedOperationException("Not Yet Implemented!");
+ }
+
+ @Override
+ public Future<String> describe(Host server, Uri<? extends Component> uri, Deployment deployment)
+ {
+ return Futures.immediateFuture("no!");
+ }
+
+ abstract static class Rule
+ {
+ private static final Pattern CIDR_RULE = Pattern.compile("\\s*(\\w+)\\s+(\\d+)\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+/\\d+)\\s*");
+ private static final Pattern GROUP_RULE = Pattern.compile("\\s*(\\w+)\\s+(\\d+)\\s+(\\w+)\\s*");
+
+ static Rule parse(String userId, String descriptor)
+ {
+ Matcher cidr = CIDR_RULE.matcher(descriptor);
+ Matcher group = GROUP_RULE.matcher(descriptor);
+ if (cidr.matches()) {
+ return new CIDRRule(cidr.group(1), cidr.group(2), cidr.group(3));
+ }
+ else if (group.matches()) {
+ return new GroupRule(userId, group.group(1), group.group(2), group.group(3));
+ }
+ throw new IllegalStateException(descriptor + " does not appear to be a CIDR or group rule");
+ }
+
+ public abstract IpPermission toIpPermission();
+
+ private static class CIDRRule extends Rule
+ {
+
+ private final String ipRange;
+ private final int port;
+ private final String proto;
+
+ CIDRRule(String proto, String port, String ipRange) {
+ this.ipRange = ipRange;
+ this.port = Integer.parseInt(port);
+ this.proto = proto;
+ }
+
+ @Override
+ public IpPermission toIpPermission()
+ {
+ IpPermission perm = new IpPermission();
+ perm.setFromPort(port);
+ perm.setToPort(port);
+ perm.setIpProtocol(proto);
+ perm.setIpRanges(asList(ipRange));
+ return perm;
+ }
+ }
+
+ private static class GroupRule extends Rule
+ {
+ private final String userId;
+ private final int port;
+ private final String proto;
+ private final String group;
+
+ public GroupRule(String userId, String proto, String port, String group)
+ {
+ this.userId = userId;
+ this.proto = proto;
+ this.group = group;
+ this.port = Integer.parseInt(port);
+ }
+
+ @Override
+ public IpPermission toIpPermission()
+ {
+ IpPermission perm = new IpPermission();
+ perm.setIpProtocol(proto);
+ perm.setToPort(port);
+ perm.setFromPort(port);
+ UserIdGroupPair pair = new UserIdGroupPair();
+ pair.setGroupName(group);
+ pair.setUserId(userId);
+ perm.setUserIdGroupPairs(asList(pair));
+ return perm;
+ }
+ }
+ }
+}
View
118 src/main/java/com/ning/atlas/aws/ELBAddInstaller.java
@@ -5,13 +5,17 @@
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Reservation;
import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient;
+import com.amazonaws.services.elasticloadbalancing.model.DeregisterInstancesFromLoadBalancerRequest;
import com.amazonaws.services.elasticloadbalancing.model.DescribeLoadBalancersRequest;
+import com.amazonaws.services.elasticloadbalancing.model.DescribeLoadBalancersResult;
import com.amazonaws.services.elasticloadbalancing.model.DisableAvailabilityZonesForLoadBalancerRequest;
import com.amazonaws.services.elasticloadbalancing.model.EnableAvailabilityZonesForLoadBalancerRequest;
import com.amazonaws.services.elasticloadbalancing.model.Instance;
+import com.amazonaws.services.elasticloadbalancing.model.LoadBalancerDescription;
import com.amazonaws.services.elasticloadbalancing.model.RegisterInstancesWithLoadBalancerRequest;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures;
import com.ning.atlas.ConcurrentComponent;
import com.ning.atlas.Host;
@@ -21,15 +25,21 @@
import com.ning.atlas.spi.Uri;
import com.ning.atlas.spi.protocols.AWS;
+import javax.annotation.Nullable;
+import javax.sql.rowset.serial.SerialStruct;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.Future;
import static java.util.Arrays.asList;
public class ELBAddInstaller extends ConcurrentComponent
{
- @Override
+
+ private final Set<String> elbnames = new ConcurrentSkipListSet<String>();
+
+ @Override
public Future<String> describe(Host server,
Uri<? extends Component> uri,
Deployment deployment)
@@ -41,56 +51,94 @@
public String perform(Host host, Uri<? extends Component> uri, Deployment d) throws Exception
{
String elb_name = uri.getFragment();
- String member_query = uri.getParams().get("member_query");
+ elbnames.add(elb_name);
AWS.Credentials creds = d.getSpace().get(AWS.ID, AWS.Credentials.class).getValue();
AmazonElasticLoadBalancingClient elb = new AmazonElasticLoadBalancingClient(creds.toAWSCredentials());
- Set<String> instance_ids = d.getSpace().query(member_query + ":ec2-instance-id");
- AmazonEC2Client client = new AmazonEC2Client(creds.toAWSCredentials());
- DescribeInstancesRequest dir = new DescribeInstancesRequest();
- dir.setInstanceIds(instance_ids);
- DescribeInstancesResult dires = client.describeInstances(dir);
+ String instance_id = d.getSpace().get(host.getId(), "ec2-instance-id")
+ .otherwise(new IllegalStateException(host.getId() + " lacks an ec2-instance-id"));
+ Instance instance = new Instance(instance_id);
+ RegisterInstancesWithLoadBalancerRequest rq = new RegisterInstancesWithLoadBalancerRequest(elb_name,
+ asList(instance));
+ elb.registerInstancesWithLoadBalancer(rq);
- List<String> old_avail_zones = elb.describeLoadBalancers(new DescribeLoadBalancersRequest(asList(elb_name)))
- .getLoadBalancerDescriptions()
- .get(0)
- .getAvailabilityZones();
-
- List<String> new_avail_zones = Lists.newArrayList();
- for (Reservation reservation : dires.getReservations()) {
- for (com.amazonaws.services.ec2.model.Instance instance : reservation.getInstances()) {
- new_avail_zones.add(instance.getPlacement().getAvailabilityZone());
- }
- }
+ return "okay";
+ }
- List<Instance> instances = Lists.transform(Lists.newArrayList(instance_ids), new Function<String, Instance>()
- {
- @Override
- public Instance apply(String input)
- {
- return new Instance(input);
- }
- });
+ @Override
+ public String unwind(Identity hostId, Uri<? extends Component> uri, Deployment d) throws Exception
+ {
+ String elb_name = uri.getFragment();
+ elbnames.add(elb_name);
- RegisterInstancesWithLoadBalancerRequest rq = new RegisterInstancesWithLoadBalancerRequest(elb_name, instances);
- elb.registerInstancesWithLoadBalancer(rq);
+ AWS.Credentials creds = d.getSpace().get(AWS.ID, AWS.Credentials.class).getValue();
+ AmazonElasticLoadBalancingClient elb = new AmazonElasticLoadBalancingClient(creds.toAWSCredentials());
- elb.enableAvailabilityZonesForLoadBalancer(new EnableAvailabilityZonesForLoadBalancerRequest(elb_name, new_avail_zones));
+ String instance_id = d.getSpace().get(hostId, "ec2-instance-id")
+ .otherwise(new IllegalStateException(hostId + " lacks an ec2-instance-id"));
- List<String> zones_to_remove = Lists.newArrayList(old_avail_zones);
- zones_to_remove.removeAll(new_avail_zones);
+ DeregisterInstancesFromLoadBalancerRequest req = new DeregisterInstancesFromLoadBalancerRequest();
+ req.setInstances(asList(new Instance(instance_id)));
- elb.disableAvailabilityZonesForLoadBalancer(new DisableAvailabilityZonesForLoadBalancerRequest(elb_name, zones_to_remove));
+ elb.deregisterInstancesFromLoadBalancer(req);
+ // TODO figure out how to do this better
return "okay";
}
@Override
- public String unwind(Identity hostId, Uri<? extends Component> uri, Deployment d) throws Exception
+ protected void finishLocal2(Deployment d)
{
- // TODO figure out how to do this better
- return "okay";
+ /**
+ * Clean up avail zones the b works against based on where instances are placed.
+ */
+
+ AWS.Credentials creds = d.getSpace().get(AWS.ID, AWS.Credentials.class).getValue();
+ AmazonElasticLoadBalancingClient elb = new AmazonElasticLoadBalancingClient(creds.toAWSCredentials());
+ AmazonEC2Client ec2 = new AmazonEC2Client(creds.toAWSCredentials());
+
+ DescribeLoadBalancersResult rs = elb.describeLoadBalancers(new DescribeLoadBalancersRequest(Lists.newArrayList(elbnames)));
+
+ for (LoadBalancerDescription description : rs.getLoadBalancerDescriptions()) {
+ List<String> instance_ids = Lists.transform(description.getInstances(), new Function<Instance, String>()
+ {
+ @Override
+ public String apply(Instance input)
+ {
+ return input.getInstanceId();
+ }
+ });
+
+ Set<String> new_zone_set = Sets.newHashSet();
+ DescribeInstancesRequest des_instances_req = new DescribeInstancesRequest();
+ des_instances_req.setInstanceIds(instance_ids);
+ for (Reservation reservation : ec2.describeInstances(des_instances_req).getReservations()) {
+ for (com.amazonaws.services.ec2.model.Instance instance : reservation.getInstances()) {
+ new_zone_set.add(instance.getPlacement().getAvailabilityZone());
+ }
+ }
+
+ Set<String> old_zone_set = Sets.newHashSet(description.getAvailabilityZones());
+
+ Set<String> to_remove = Sets.difference(old_zone_set, new_zone_set);
+ Set<String> to_add = Sets.difference(new_zone_set, old_zone_set);
+
+ if (!to_add.isEmpty()) {
+ EnableAvailabilityZonesForLoadBalancerRequest eazreq = new EnableAvailabilityZonesForLoadBalancerRequest();
+ eazreq.setAvailabilityZones(to_add);
+ eazreq.setLoadBalancerName(description.getLoadBalancerName());
+ elb.enableAvailabilityZonesForLoadBalancer(eazreq);
+ }
+
+ if (!to_remove.isEmpty()) {
+ DisableAvailabilityZonesForLoadBalancerRequest disreq = new DisableAvailabilityZonesForLoadBalancerRequest();
+ disreq.setAvailabilityZones(to_remove);
+ disreq.setLoadBalancerName(description.getLoadBalancerName());
+ elb.disableAvailabilityZonesForLoadBalancer(disreq);
+ }
+
+ }
}
}
View
17 src/main/java/com/ning/atlas/aws/ELBProvisioner.java
@@ -1,24 +1,18 @@
package com.ning.atlas.aws;
-import com.amazonaws.AmazonClientException;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.AvailabilityZone;
import com.amazonaws.services.ec2.model.DescribeAvailabilityZonesResult;
import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient;
-import com.amazonaws.services.elasticloadbalancing.model.CreateLoadBalancerListenersRequest;
import com.amazonaws.services.elasticloadbalancing.model.CreateLoadBalancerRequest;
import com.amazonaws.services.elasticloadbalancing.model.CreateLoadBalancerResult;
import com.amazonaws.services.elasticloadbalancing.model.DeleteLoadBalancerRequest;
import com.amazonaws.services.elasticloadbalancing.model.DescribeLoadBalancersRequest;
import com.amazonaws.services.elasticloadbalancing.model.DescribeLoadBalancersResult;
-import com.amazonaws.services.elasticloadbalancing.model.Instance;
import com.amazonaws.services.elasticloadbalancing.model.Listener;
-import com.amazonaws.services.elasticloadbalancing.model.LoadBalancerDescription;
-import com.amazonaws.services.elasticloadbalancing.model.RegisterInstancesWithLoadBalancerRequest;
-import com.amazonaws.services.elasticloadbalancing.model.RegisterInstancesWithLoadBalancerResult;
+import com.amazonaws.services.elasticloadbalancing.model.LoadBalancerNotFoundException;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures;
import com.ning.atlas.ConcurrentComponent;
import com.ning.atlas.Host;
@@ -27,13 +21,8 @@
import com.ning.atlas.spi.Identity;
import com.ning.atlas.spi.Uri;
import com.ning.atlas.spi.protocols.AWS;
-import com.ning.atlas.spi.space.Missing;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.util.List;
-import java.util.Set;
import java.util.concurrent.Future;
import static java.util.Arrays.asList;
@@ -79,8 +68,10 @@ private String ensureLbExists(AmazonElasticLoadBalancingClient aws,
DescribeLoadBalancersResult rs = aws.describeLoadBalancers(req);
return rs.getLoadBalancerDescriptions().get(0).getDNSName();
}
- catch (AmazonClientException e) {
+ catch (LoadBalancerNotFoundException e) {
// not found!
+ // we don't know what zones our instances are in yet, so add lb to all of them
+ // we will rejigger this when we assign instances to the LB
DescribeAvailabilityZonesResult avail_zones = ec2.describeAvailabilityZones();
List<String> avail_zones_s = Lists.transform(avail_zones.getAvailabilityZones(),
View
30 src/main/java/com/ning/atlas/spi/protocols/EC2SecurityGroup.java
@@ -0,0 +1,30 @@
+package com.ning.atlas.spi.protocols;
+
+import com.ning.atlas.spi.space.Space;
+
+import java.util.concurrent.TimeUnit;
+
+public class EC2SecurityGroup
+{
+ public static void publishAvailability(String name, Space space) {
+ space.store(AWS.ID.createChild("ec2-security-group", "availability"), name, name);
+ }
+
+ public static void waitForAvailabilityOf(String name, Space space, long time, TimeUnit unit) {
+ long give_up_at = unit.toMillis(time) + System.currentTimeMillis();
+ while (give_up_at > System.currentTimeMillis()) {
+ if (space.get(AWS.ID.createChild("ec2-security-group", "availablity"), name).isKnown()) {
+ return;
+ }
+ else {
+ try {
+ Thread.sleep(100);
+ }
+ catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new IllegalStateException("interrupted", e);
+ }
+ }
+ }
+ }
+}
View
37 src/main/ruby/atlas/parser.rb
@@ -64,6 +64,7 @@ class EnvironmentParser
def initialize block
@block = block
@properties, @provisioners, @installers, @bases, @listeners = {}, {}, {}, {}, {}
+ @children = []
end
def __parse
@@ -73,7 +74,8 @@ def __parse
@installers,
@listeners,
@bases,
- @properties
+ @properties,
+ @children
end
def base name, args={}
@@ -107,10 +109,37 @@ def installer name, args = {}
@installers[name] = Atlas.stringify(args)
end
- def system *args
- #no-op
+ def system name="system", args={}, &block
+ st = if args[:external] then
+ Atlas.parse_system(args[:external], name)
+ else
+ SystemParser.new(name, args, block).__parse
+ end
+ @children << st
end
+ def server name, args={}
+ installers = Atlas.parse_install_list(args[:install])
+
+ # cardinality can be nil, a number, or an array
+ cardinality = case it = args[:cardinality]
+ when Array
+ it
+ when Integer
+ it.downto(1).map { |i| i - 1 }.reverse
+ else
+ ["0"]
+ end
+
+ @children << com.ning.atlas.ServerTemplate.new(name,
+ com.ning.atlas.spi.Uri.value_of(args[:base].to_s),
+ cardinality,
+ installers,
+ args.inject({}) { |a, (k, v)| a[k.to_s] = v; a })
+ end
+
+ alias :service :server
+
def listener name, args= {}
@listeners[name] = Atlas.stringify(args)
end
@@ -235,6 +264,8 @@ def server name, args={}
installers,
args.inject({}) { |a, (k, v)| a[k.to_s] = v; a })
end
+
+ alias :service :server
end
end
View
11 src/test/java/com/ning/atlas/TestJRubyTemplateParser.java
@@ -229,4 +229,15 @@ public void testTemplatization() throws Exception
}
+ @Test
+ public void testEnvironmentDefinedElements() throws Exception
+ {
+ JRubyTemplateParser p = new JRubyTemplateParser();
+ Environment e = p.parseEnvironment(new File("src/test/ruby/test_jruby_template_parser_env_servers-env.rb"));
+ Template t = p.parseSystem(new File("src/test/ruby/test_jruby_template_parser_env_servers-sys.rb"));
+
+ SystemMap map = t.normalize(e);
+ assertThat(map.findLeaves().size(), equalTo(2));
+ }
+
}
View
6 src/test/java/com/ning/atlas/TestScratchInstaller.java
@@ -29,7 +29,7 @@ public void testAtInValue() throws Exception
Collections.<Uri<Installer>>emptyList(),
new My());
Environment environment = new Environment();
- SystemMap map = new SystemMap(Arrays.<Element>asList(host), environment);
+ SystemMap map = new SystemMap(Arrays.<Element>asList(host));
Space space = InMemorySpace.newInstance();
Deployment d = new ActualDeployment(map, environment, space);
@@ -49,7 +49,7 @@ public void testAtInKey() throws Exception
Collections.<Uri<Installer>>emptyList(),
Collections.<Uri<Installer>>emptyList(),
new My());
- SystemMap map = new SystemMap(Arrays.<Element>asList(host), new Environment());
+ SystemMap map = new SystemMap(Arrays.<Element>asList(host));
Environment environment = new Environment();
Space space = InMemorySpace.newInstance();
Deployment d = new ActualDeployment(map, environment, space);
@@ -68,7 +68,7 @@ public void testMultipleThings() throws Exception
Collections.<Uri<Installer>>emptyList(),
Collections.<Uri<Installer>>emptyList(),
new My());
- SystemMap map = new SystemMap(Arrays.<Element>asList(host), new Environment());
+ SystemMap map = new SystemMap(Arrays.<Element>asList(host));
Environment environment = new Environment();
Space space = InMemorySpace.newInstance();
Deployment d = new ActualDeployment(map, environment, space);
View
38 src/test/java/com/ning/atlas/aws/TestEC2SecurityGroupProvisioner.java
@@ -0,0 +1,38 @@
+package com.ning.atlas.aws;
+
+import com.amazonaws.services.ec2.model.IpPermission;
+import org.junit.Test;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+public class TestEC2SecurityGroupProvisioner
+{
+ @Test
+ public void testCidrRule() throws Exception
+ {
+ String raw_rule = "tcp 22 0.0.0.0/0";
+ EC2SecurityGroupProvisioner.Rule rule = EC2SecurityGroupProvisioner.Rule.parse("1", raw_rule);
+ IpPermission perm = rule.toIpPermission();
+ assertThat(perm.getFromPort(), equalTo(22));
+ assertThat(perm.getToPort(), equalTo(22));
+ assertThat(perm.getIpProtocol(), equalTo("tcp"));
+ assertThat(perm.getIpRanges(), equalTo(asList("0.0.0.0/0")));
+ }
+
+ @Test
+ public void testSecurityGroupRule() throws Exception
+ {
+ String raw_rule = "tcp 22 default";
+ EC2SecurityGroupProvisioner.Rule rule = EC2SecurityGroupProvisioner.Rule.parse("1", raw_rule);
+ IpPermission perm = rule.toIpPermission();
+ assertThat(perm.getFromPort(), equalTo(22));
+ assertThat(perm.getToPort(), equalTo(22));
+ assertThat(perm.getIpProtocol(), equalTo("tcp"));
+ assertThat(perm.getUserIdGroupPairs().size(), equalTo(1));
+ assertThat(perm.getUserIdGroupPairs().get(0).getGroupName(), equalTo("default"));
+ assertThat(perm.getUserIdGroupPairs().get(0).getUserId(), equalTo("1"));
+ }
+}
View
2 src/test/java/com/ning/atlas/spi/TestUri.java
@@ -103,7 +103,7 @@ public void testCanonicalization() throws Exception
ImmutableMap.<String, Collection<String>>of("a", Arrays.asList("hello", "world"),
"b", Arrays.asList("hello world")));
- assertThat(uri.toString(), equalTo("hello:world?a=hello&a=world&b=hello+world"));
+ assertThat(uri.toString(), equalTo("hello:world?a=hello&a=world&b=hello world"));
}
@Test
View
8 src/test/ruby/test_jruby_template_parser_env_servers-env.rb
@@ -0,0 +1,8 @@
+
+
+environment "unit-test" do
+
+ server "ops-thing", base: "mythical"
+
+ base "mythical", provisioner: "noop"
+end
View
6 src/test/ruby/test_jruby_template_parser_env_servers-sys.rb
@@ -0,0 +1,6 @@
+
+
+system "magical" do
+
+ server "eng-thing", base: "mythical"
+end

0 comments on commit 85d65ed

Please sign in to comment.
Something went wrong with that request. Please try again.