private void checkSecurityGroupCapacity(Reservation reservation, SecurityGroup securityGroup) {
    LOG.debug(String.format("checking security group: %s", securityGroup));

    int numberOfInstancesInSecurityGroup = securityGroup.getInstances().size();

    if (numberOfInstancesInSecurityGroup == 0) {
      LOG.debug(String.format("No instances in security group: %s", securityGroup));
      return;
    }

    if (securityGroup.getNetmask() == null) {
      LOG.debug(String.format("Unable to get the netmask for security group: %s", securityGroup));
      return;
    }

    int availableNumberOfInstancesInSecurityGroup = getSecurityGroupCapacity(securityGroup);

    LOG.debug(
        String.format(
            "SecurityGroup: %s - Number of Instances: %d - Capacity in SecurityGroup: %d",
            securityGroup.getUrl(),
            numberOfInstancesInSecurityGroup,
            availableNumberOfInstancesInSecurityGroup));

    if (numberOfInstancesInSecurityGroup + reservation.getMinCount()
        > availableNumberOfInstancesInSecurityGroup
            - NUMBER_OF_RESERVED_ADDRESSES_IN_SECURITY_GROUP)
      throw new IllegalStateException(
          "unable to run instances as no more capacity in security group");
  }
  public void refreshVirtualNetworks() {
    LOG.debug(String.format("Refreshing virtual networks"));

    Set<URI> vlanIds =
        consumedUriResourceRegistry.getResourceIdsByScheme(
            ResourceSchemes.VIRTUAL_NETWORK.toString());

    /*
     *  Because the vlanId gets inserted into the consumedUriResourceRegistry a few continuations after a security
     *  group gets added, sometimes this fails and then the pibr never actually gets onto the network manager. So we
     *  do some reconciliation between the security group and vlan registries. For now, we aren't looking for entries
     *  in the vlan registry that aren't in the security group list...needs some thought on whether that is needed but
     *  certainly not until we see some issues pertaining to that!
     */
    List<SecurityGroup> securityGroups = consumedDhtResourceRegistry.getByType(SecurityGroup.class);
    for (SecurityGroup securityGroup : securityGroups) {
      Long vlanId = securityGroup.getVlanId();
      if (null == vlanId) continue;
      URI vlanUri = URI.create(String.format(S_D, ResourceSchemes.VIRTUAL_NETWORK, vlanId));
      if (!vlanIds.contains(vlanUri)) {
        LOG.debug(
            String.format(
                "Vlan Id %d present in the security groups in consumedDhtResourceRegistry is not present in the list of vlans in consumedUriResourceRegistry",
                securityGroup.getVlanId()));
        consumedUriResourceRegistry.registerConsumer(
            vlanUri, securityGroup.getSecurityGroupId(), new LoggingContinuation<Boolean>());
        networkCommandRunner.addManagedNetwork(vlanId, privateInterface);
      }
    }

    List<String> deviceList = deviceUtils.getDeviceList();
    for (URI uri : vlanIds) {
      long vlanId = Long.parseLong(uri.getSchemeSpecificPart());
      LOG.debug(String.format("Checking to see if vlan %d exists", vlanId));
      if (!deviceUtils.deviceExists(
          networkCommandRunner.getVlanInterface(vlanId, privateInterface), deviceList)) {
        networkCommandRunner.addManagedNetwork(vlanId, privateInterface);
      }
    }

    Collection<String> allVlanDevicesForInterface =
        deviceUtils.getAllVlanDevicesForInterface(privateInterface, deviceList);
    for (String vlan : allVlanDevicesForInterface) {
      if (vlan.contains(DOT)) {
        long vlanId = Long.parseLong(vlan.split(String.format("\\%s", DOT))[1]);
        if (!vlanIds.contains(
            URI.create(String.format(S_D, ResourceSchemes.VIRTUAL_NETWORK, vlanId))))
          addressDeleteQueue.add(
              new VlanDeleteItem(vlanId, privateInterface, networkCommandRunner));
      }
    }
  }
Example #3
0
  public synchronized List<String> generateFilterTable(
      List<SecurityGroup> securityGroups, List<String> existingChains) {

    LOG.debug(String.format("generateFilterTable(%s, %s)", securityGroups, existingChains));
    lines = new ArrayList<String>();

    // if (!existingChains.contains(PI_CHAIN))
    // addChain(PI_CHAIN);
    // addForwardAllToChain(PI_CHAIN);

    for (SecurityGroup securityGroup : securityGroups) {
      if (!validateSecurityGroup(securityGroup)) {
        LOG.debug(String.format(SKIPPING_SECURITY_GROUP_S_AS_IT_IS_NOT_POPULATED, securityGroup));
        continue;
      }

      LOG.debug(String.format("Processing Security group: %s for filter rules.", securityGroup));
      String filterChainName =
          getChainNameForSecurityGroup(FLTR_PREFIX, securityGroup.getSecurityGroupId());
      String destinationNetwork =
          String.format(S_SLASH_S, securityGroup.getNetworkAddress(), securityGroup.getSlashnet());

      if (!existingChains.contains(filterChainName))
        lines.add(ipTablesHelper.addChain(filterChainName));

      lines.add(
          ipTablesHelper.appendForwardChainToChain(PI_CHAIN, destinationNetwork, filterChainName));

      // TODO: Handle case where rule name specificed instead of network

      for (NetworkRule networkRule : securityGroup.getNetworkRules()) {
        for (String sourceNetwork : networkRule.getSourceNetworks()) {
          addFilterRule(
              filterChainName,
              sourceNetwork,
              destinationNetwork,
              networkRule.getNetworkProtocol(),
              networkRule.getPortRangeMin(),
              networkRule.getPortRangeMax());
        }
      }
    }
    logFlushRules("Generated filter iptables:\n%s", lines);
    return lines;
  }
    @Override
    public SecurityGroup update(SecurityGroup existingEntity, SecurityGroup requestedEntity) {
      if (null == existingEntity) return null;

      for (String instanceId : reservationInstanceIds) {
        existingEntity.getInstances().put(instanceId, new InstanceAddress());
      }

      return existingEntity;
    }
Example #5
0
  public synchronized List<String> generateNatTable(
      List<SecurityGroup> securityGroups, List<String> existingChains) {

    LOG.debug(String.format("generateNatTable(%s, %s)", securityGroups, existingChains));
    lines = new ArrayList<String>();

    if (!existingChains.contains(PI_PREROUTING)) {
      lines.add(ipTablesHelper.addChain(PI_PREROUTING));
      lines.add(ipTablesHelper.appendForwardChainToChain(PREROUTING, PI_PREROUTING));
    }
    if (!existingChains.contains(PI_OUTPUT)) {
      lines.add(ipTablesHelper.addChain(PI_OUTPUT));
      lines.add(ipTablesHelper.appendForwardChainToChain(OUTPUT, PI_OUTPUT));
    }

    for (SecurityGroup securityGroup : securityGroups) {
      if (!validateSecurityGroup(securityGroup)) {
        LOG.debug(String.format(SKIPPING_SECURITY_GROUP_S_AS_IT_IS_NOT_POPULATED, securityGroup));
        continue;
      }
      LOG.debug(String.format("Processing Security group: %s for nat rules.", securityGroup));
      String postChainName =
          getChainNameForSecurityGroup(POST_PREFIX, securityGroup.getSecurityGroupId());
      String destinationNetwork =
          String.format(S_SLASH_S, securityGroup.getNetworkAddress(), securityGroup.getSlashnet());

      if (!existingChains.contains(postChainName))
        lines.add(ipTablesHelper.addChain(postChainName));

      lines.add(
          ipTablesHelper.insertChainForwardToChain(POSTROUTING, destinationNetwork, postChainName));

      // TODO: Handle case where rule name specified instead of network

      for (Entry<String, InstanceAddress> addressEntry : securityGroup.getInstances().entrySet()) {
        LOG.debug(String.format("Processing addressEntry: %s for nat rules.", addressEntry));
        InstanceAddress address = addressEntry.getValue();
        if (null == address) {
          LOG.warn(
              String.format("null entry in instance table for instance %s", addressEntry.getKey()));
          continue;
        }
        if (address.getPublicIpAddress() != null && address.getPrivateIpAddress() != null) {
          addNatRule(postChainName, address.getPublicIpAddress(), address.getPrivateIpAddress());
        } else {
          LOG.debug(
              String.format(
                  "Skipping NAT rule within group %s as one or both addresses are null (%s / %s)",
                  securityGroup.getSecurityGroupId(),
                  address.getPublicIpAddress(),
                  address.getPrivateIpAddress()));
        }
      }
    }
    logFlushRules("Generated nat iptables:\n%s", lines);

    return lines;
  }
  @Override
  public void handleResult(Instance result) {
    LOG.debug(String.format("handleResult(PiEntity - %s)", result));
    if (result != null) {
      if (result.getNodeId() != null) {
        LOG.debug(
            String.format(
                "Sending termination message for inst %s to node %s",
                result.getInstanceId(), result.getNodeId()));
        PId instanceRecordId = piIdBuilder.getNodeIdFromNodeId(result.getNodeId());
        MessageContext instanceMessageContext = messageContextFactory.newMessageContext();
        instanceMessageContext.routePiMessageToApplication(
            instanceRecordId,
            EntityMethod.DELETE,
            result,
            InstanceManagerApplication.APPLICATION_NAME);
      } else {
        LOG.debug(
            String.format(
                "Null node id detected, not sending termination message for %s to instance manager",
                result.getInstanceId()));
      }

      int instanceGlobalAvzCode =
          piIdBuilder.getGlobalAvailabilityZoneCodeFromEc2Id(result.getInstanceId());
      PId securityGroupId =
          piIdBuilder
              .getPId(SecurityGroup.getUrl(result.getUserId(), result.getSecurityGroupName()))
              .forGlobalAvailablityZoneCode(instanceGlobalAvzCode);
      LOG.debug(
          String.format(
              "Sending termination message for inst %s to network app node %s for sec group %s:%s",
              result.getInstanceId(),
              result.getUserId(),
              securityGroupId.toStringFull(),
              result.getSecurityGroupName()));
      MessageContext securityGroupMessageContext = messageContextFactory.newMessageContext();
      securityGroupMessageContext.routePiMessageToApplication(
          securityGroupId, EntityMethod.DELETE, result, NetworkManagerApplication.APPLICATION_NAME);
      InstanceStateTransition transition = instanceStatusMap.get(result.getInstanceId());
      if (transition != null) {
        transition.setNextState(result.getState());
      }
    } else {
      LOG.warn("Expected a non-null instance record");
    }
  }
  @Before
  public void setup() {
    when(piIdBuilder.getPIdForEc2AvailabilityZone(uri)).thenReturn(instancePId);
    when(piIdBuilder.getGlobalAvailabilityZoneCodeFromEc2Id(instanceId)).thenReturn(globalAvzCode);
    when(piIdBuilder.getPId(SecurityGroup.getUrl(userId, securityGroupName)))
        .thenReturn(securityGroupPId);
    when(piIdBuilder.getPiQueuePId(PiQueue.INSTANCE_NETWORK_MANAGER_TEARDOWN))
        .thenReturn(instanceNetworkManagerTeardownQueueId);
    when(securityGroupPId.forGlobalAvailablityZoneCode(globalAvzCode)).thenReturn(securityGroupPId);

    when(instanceNetworkManagerTeardownQueueId.forLocalScope(
            PiQueue.TERMINATE_INSTANCE.getNodeScope()))
        .thenReturn(instanceNetworkManagerTeardownQueueId);
    when(messageContextFactory.newMessageContext()).thenReturn(messageContext);
    when(dhtClientFactory.createReader()).thenReturn(dhtReader);

    when(resultInstance.getInstanceId()).thenReturn(instanceId);
    when(resultInstance.getNodeId()).thenReturn(instanceNodeId);
    when(resultInstance.getUserId()).thenReturn(userId);
    when(resultInstance.getSecurityGroupName()).thenReturn(securityGroupName);
  }
Example #8
0
  private boolean validateSecurityGroup(SecurityGroup securityGroup) {
    if (null == securityGroup.getNetmask() || null == securityGroup.getVlanId()) return false;

    return true;
  }
  public ReservationInstances runInstances(final Reservation reservation) {
    LOG.debug(String.format("runInstances(%s)", reservation));

    String securityGroupUrl =
        SecurityGroup.getUrl(reservation.getUserId(), reservation.getSecurityGroupName());
    PId securityGroupId = getPiIdBuilder().getPId(securityGroupUrl).forLocalRegion();
    SecurityGroup securityGroup =
        (SecurityGroup) getDhtClientFactory().createBlockingReader().get(securityGroupId);

    validateReservation(reservation, securityGroup);

    reservation.setReservationId(getIdFactory().createNewReservationId());

    AvailabilityZone availabilityZone;
    if (StringUtils.isNotEmpty(reservation.getAvailabilityZone())) {
      try {
        availabilityZone = getAvailabilityZoneByName(reservation.getAvailabilityZone());
      } catch (AvailabilityZoneNotFoundException e) {
        throw new IllegalArgumentException(
            String.format("Unknown availability zone: %s", reservation.getAvailabilityZone()));
      }
    } else {
      availabilityZone = getLocalAvailabilityZone();
      reservation.setAvailabilityZone(availabilityZone.getAvailabilityZoneName());
    }

    // setup return object
    ReservationInstances reservationInstances = new ReservationInstances();
    reservationInstances.setReservation(reservation);

    for (int i = 0; i < reservation.getMaxCount(); i++) {
      String instanceId =
          getIdFactory().createNewInstanceId(availabilityZone.getGlobalAvailabilityZoneCode());
      // create instance
      Instance instance = new Instance(reservation);
      instance.setInstanceType(reservation.getInstanceType());
      instance.setUserId(reservation.getUserId());
      instance.setInstanceId(instanceId);
      instance.setState(InstanceState.PENDING);
      instance.setLaunchTime(System.currentTimeMillis());
      instance.setAvailabilityZoneCode(availabilityZone.getAvailabilityZoneCodeWithinRegion());
      instance.setRegionCode(availabilityZone.getRegionCode());
      LOG.info(String.format("Requesting new %s", instance));
      reservationInstances.getInstances().add(instance);

      // create instance in dht
      PId instanceDhtId =
          getPiIdBuilder().getPIdForEc2AvailabilityZone(Instance.getUrl(instanceId));
      BlockingDhtWriter blockingDhtWriter = getDhtClientFactory().createBlockingWriter();
      AddNewInstanceResolver addNewInstanceResolver = new AddNewInstanceResolver();
      blockingDhtWriter.update(instanceDhtId, instance, addNewInstanceResolver);

      reservation.addInstanceId(instance.getInstanceId());
    }

    getUserService()
        .addInstancesToUser(
            reservation.getUserId(), reservation.getInstanceIds(), reservation.getInstanceType());

    // write security group to DHT
    getDhtClientFactory()
        .createBlockingWriter()
        .update(
            securityGroupId,
            null,
            new AddInstanceToSecurityGroupResolver(reservation.getInstanceIds()));

    // add to task processing queue
    PId runInstanceQueueId =
        getPiIdBuilder()
            .getPId(PiQueue.RUN_INSTANCE.getUrl())
            .forGlobalAvailablityZoneCode(availabilityZone.getGlobalAvailabilityZoneCode());
    for (String instanceId : reservation.getInstanceIds()) {
      getTaskProcessingQueueHelper()
          .addUrlToQueue(runInstanceQueueId, Instance.getUrl(instanceId), instanceTaskQueueRetries);
    }

    // anycast message
    PubSubMessageContext pubSubMessageContext =
        getApiApplicationManager()
            .newPubSubMessageContextFromGlobalAvzCode(
                PiTopics.RUN_INSTANCE, availabilityZone.getGlobalAvailabilityZoneCode());
    pubSubMessageContext.randomAnycast(EntityMethod.CREATE, reservation);

    return reservationInstances;
  }
 private int getSecurityGroupCapacity(SecurityGroup securityGroup) {
   String netmask = securityGroup.getNetmask();
   int addrsInSlashnet = IpAddressUtils.addrsInSlashnet(IpAddressUtils.netmaskToSlashnet(netmask));
   return addrsInSlashnet;
 }