コード例 #1
0
  public PutMetricDataResponseType putMetricData(PutMetricDataType request)
      throws CloudWatchException {
    PutMetricDataResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      LOG.trace("put metric data called");
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_PUTMETRICDATA, ctx);

      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final List<MetricDatum> metricData = validateMetricData(request.getMetricData());
      final String namespace = validateNamespace(request.getNamespace(), true);
      final Boolean isUserAccountAdmin =
          Principals.isSameUser(
              Principals.systemUser(), Wrappers.unwrap(Context.class, Contexts.lookup()).getUser());
      LOG.trace("Namespace=" + namespace);
      LOG.trace("metricData=" + metricData);
      MetricType metricType = getMetricTypeFromNamespace(namespace);
      if (metricType == MetricType.System && !isUserAccountAdmin) {
        throw new InvalidParameterValueException(
            "The value AWS/ for parameter Namespace is invalid.");
      }
      MetricDataQueue.getInstance()
          .insertMetricData(ownerFullName.getAccountNumber(), namespace, metricData, metricType);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
コード例 #2
0
  public DescribeAlarmsForMetricResponseType describeAlarmsForMetric(
      DescribeAlarmsForMetricType request) throws CloudWatchException {
    DescribeAlarmsForMetricResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_DESCRIBEALARMSFORMETRIC, ctx);
      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      final Map<String, String> dimensionMap =
          TransformationFunctions.DimensionsToMap.INSTANCE.apply(
              validateDimensions(request.getDimensions()));
      final String metricName = validateMetricName(request.getMetricName(), true);
      final String namespace = validateNamespace(request.getNamespace(), true);
      final Integer period = validatePeriod(request.getPeriod(), false);
      final Statistic statistic = validateStatistic(request.getStatistic(), false);
      final Units unit = validateUnits(request.getUnit(), true);
      Collection<AlarmEntity> results =
          AlarmManager.describeAlarmsForMetric(
              accountId, dimensionMap, metricName, namespace, period, statistic, unit);
      MetricAlarms metricAlarms = new MetricAlarms();
      metricAlarms.setMember(
          Lists.newArrayList(
              Collections2.<AlarmEntity, MetricAlarm>transform(
                  results, TransformationFunctions.AlarmEntityToMetricAlarm.INSTANCE)));
      reply.getDescribeAlarmsForMetricResult().setMetricAlarms(metricAlarms);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
コード例 #3
0
  public PutMetricAlarmResponseType putMetricAlarm(PutMetricAlarmType request)
      throws CloudWatchException {
    PutMetricAlarmResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_PUTMETRICALARM, ctx);

      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      final Boolean actionsEnabled = validateActionsEnabled(request.getActionsEnabled(), true);
      final Map<String, String> dimensionMap =
          TransformationFunctions.DimensionsToMap.INSTANCE.apply(
              validateDimensions(request.getDimensions()));
      final Collection<String> alarmActions =
          validateActions(request.getAlarmActions(), dimensionMap, "AlarmActions");
      final String alarmDescription = validateAlarmDescription(request.getAlarmDescription());
      final String alarmName = validateAlarmName(request.getAlarmName(), true);
      final ComparisonOperator comparisonOperator =
          validateComparisonOperator(request.getComparisonOperator(), true);
      Integer evaluationPeriods = validateEvaluationPeriods(request.getEvaluationPeriods(), true);
      final Integer period = validatePeriod(request.getPeriod(), true);
      validatePeriodAndEvaluationPeriodsNotAcrossDays(period, evaluationPeriods);
      final Collection<String> insufficientDataActions =
          validateActions(
              request.getInsufficientDataActions(), dimensionMap, "InsufficientDataActions");
      final String metricName = validateMetricName(request.getMetricName(), true);
      final String namespace = validateNamespace(request.getNamespace(), true);
      final Collection<String> okActions =
          validateActions(request.getOkActions(), dimensionMap, "OKActions");
      final Statistic statistic = validateStatistic(request.getStatistic(), true);
      final Double threshold = validateThreshold(request.getThreshold(), true);
      final Units unit = validateUnits(request.getUnit(), true);
      if (AlarmManager.countMetricAlarms(accountId) >= 5000) {
        throw new LimitExceededException("The maximum limit of 5000 alarms would be exceeded.");
      }
      AlarmManager.putMetricAlarm(
          accountId,
          actionsEnabled,
          alarmActions,
          alarmDescription,
          alarmName,
          comparisonOperator,
          dimensionMap,
          evaluationPeriods,
          insufficientDataActions,
          metricName,
          getMetricTypeFromNamespace(namespace),
          namespace,
          okActions,
          period,
          statistic,
          threshold,
          unit);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
コード例 #4
0
 @Override
 public void incomingMessage(ChannelHandlerContext ctx, MessageEvent event) throws Exception {
   if (event.getMessage() instanceof MappingHttpRequest) {
     MappingHttpRequest httpRequest = (MappingHttpRequest) event.getMessage();
     if (httpRequest.getMessage() instanceof WalrusRequestType) {
       WalrusRequestType request = (WalrusRequestType) httpRequest.getMessage();
       BucketLogData logData = request.getLogData();
       if (logData != null) {
         long currentTime = System.currentTimeMillis();
         logData.setTotalTime(currentTime);
         logData.setTurnAroundTime(currentTime);
         logData.setUri(httpRequest.getUri());
         String referrer = httpRequest.getHeader(HttpHeaders.Names.REFERER);
         if (referrer != null) logData.setReferrer(referrer);
         String userAgent = httpRequest.getHeader(HttpHeaders.Names.USER_AGENT);
         if (userAgent != null) logData.setUserAgent(userAgent);
         logData.setTimestamp(
             String.format("[%1$td/%1$tb/%1$tY:%1$tH:%1$tM:%1$tS %1$tz]", Calendar.getInstance()));
         User user = Contexts.lookup(httpRequest.getCorrelationId()).getUser();
         if (user != null) logData.setAccessorId(user.getUserId());
         if (request.getBucket() != null) logData.setBucketName(request.getBucket());
         if (request.getKey() != null) logData.setKey(request.getKey());
         if (ctx.getChannel().getRemoteAddress() instanceof InetSocketAddress) {
           InetSocketAddress sockAddress = (InetSocketAddress) ctx.getChannel().getRemoteAddress();
           logData.setSourceAddress(sockAddress.getAddress().getHostAddress());
         }
       }
     }
   }
 }
コード例 #5
0
 public static void handle(String service, MuleMessage responseMessage, BaseMessage request) {
   BaseMessage reply = null;
   if (responseMessage.getExceptionPayload() == null) {
     reply = (BaseMessage) responseMessage.getPayload();
   } else {
     Throwable t = responseMessage.getExceptionPayload().getException();
     t = (t.getCause() == null) ? t : t.getCause();
     reply = new EucalyptusErrorMessageType(service, request, t.getMessage());
   }
   String corrId = reply.getCorrelationId();
   EventRecord.here(
           EuareReplyQueue.class,
           EventType.MSG_REPLY,
           reply.getCorrelationId(),
           reply.getClass().getSimpleName())
       .debug();
   try {
     Context context = Contexts.lookup(corrId);
     Channel channel = context.getChannel();
     Channels.write(channel, reply);
     Contexts.clear(context);
   } catch (NoSuchContextException e) {
     LOG.trace(e, e);
   }
 }
コード例 #6
0
 public static ModifyPropertyValueResponseType modifyProperty(ModifyPropertyValueType request)
     throws EucalyptusCloudException {
   ModifyPropertyValueResponseType reply = request.getReply();
   if (INTERNAL_OP.equals(request.getName())) {
     if (!Contexts.lookup().hasAdministrativePrivileges()) {
       throw new EucalyptusCloudException("You are not authorized to interact with this service.");
     }
     LOG.debug("Performing euca operation: \n" + request.getValue());
     try {
       reply.setName(INTERNAL_OP);
       reply.setValue("" + Groovyness.eval(request.getValue()));
       reply.setOldValue("executed successfully.");
     } catch (Exception ex) {
       LOG.error(ex, ex);
       reply.setName(INTERNAL_OP);
       reply.setOldValue("euca operation failed because of: " + ex.getMessage());
       reply.setValue(Exceptions.string(ex));
     }
   } else {
     try {
       ConfigurableProperty entry = PropertyDirectory.getPropertyEntry(request.getName());
       String oldValue = "********";
       if (!entry.getWidgetType().equals(ConfigurableFieldType.KEYVALUEHIDDEN)) {
         oldValue = entry.getValue();
       }
       reply.setOldValue(oldValue);
       Boolean reset = request.getReset();
       if (reset != null) {
         if (Boolean.TRUE.equals(reset)) {
           entry.setValue(entry.getDefaultValue());
         }
       } else {
         // if property is ReadOnly it should not be set by user
         if (!entry.getReadOnly()) {
           try {
             String inValue = request.getValue();
             entry.setValue((inValue == null) ? "" : inValue);
           } catch (Exception e) {
             entry.setValue(oldValue);
             Exceptions.findAndRethrow(e, EucalyptusCloudException.class);
             throw e;
           }
         }
       }
       reply.setValue(entry.getValue());
       reply.setName(request.getName());
     } catch (IllegalAccessException e) {
       throw new EucalyptusCloudException("Failed to set property: " + e.getMessage());
     } catch (EucalyptusCloudException e) {
       throw e;
     } catch (Throwable e) {
       throw new EucalyptusCloudException(e);
     }
   }
   return reply;
 }
コード例 #7
0
ファイル: VolumeManager.java プロジェクト: sosilent/euca
  public CreateVolumeResponseType CreateVolume(final CreateVolumeType request)
      throws EucalyptusCloudException, AuthException {
    Context ctx = Contexts.lookup();
    Long volSize = request.getSize() != null ? Long.parseLong(request.getSize()) : null;
    final String snapId = request.getSnapshotId();
    String partition = request.getAvailabilityZone();

    if ((request.getSnapshotId() == null && request.getSize() == null)) {
      throw new EucalyptusCloudException("One of size or snapshotId is required as a parameter.");
    }

    if (snapId != null) {
      try {
        Transactions.find(Snapshot.named(null, snapId));
      } catch (ExecutionException ex) {
        throw new EucalyptusCloudException(
            "Failed to create volume because the referenced snapshot id is invalid: " + snapId);
      }
    }
    final Integer newSize = new Integer(request.getSize() != null ? request.getSize() : "-1");
    Exception lastEx = null;
    for (int i = 0; i < VOL_CREATE_RETRIES; i++) {
      try {
        final ServiceConfiguration sc =
            Topology.lookup(Storage.class, Partitions.lookupByName(partition));
        final UserFullName owner = ctx.getUserFullName();
        Function<Long, Volume> allocator =
            new Function<Long, Volume>() {

              @Override
              public Volume apply(Long size) {
                try {
                  return Volumes.createStorageVolume(
                      sc, owner, snapId, Ints.checkedCast(size), request);
                } catch (ExecutionException ex) {
                  throw Exceptions.toUndeclared(ex);
                }
              }
            };
        Volume newVol = RestrictedTypes.allocateMeasurableResource(newSize.longValue(), allocator);
        CreateVolumeResponseType reply = request.getReply();
        reply.setVolume(newVol.morph(new edu.ucsb.eucalyptus.msgs.Volume()));
        return reply;
      } catch (RuntimeException ex) {
        LOG.error(ex, ex);
        if (!(ex.getCause() instanceof ExecutionException)) {
          throw ex;
        } else {
          lastEx = ex;
        }
      }
    }
    throw new EucalyptusCloudException(
        "Failed to create volume after " + VOL_CREATE_RETRIES + " because of: " + lastEx, lastEx);
  }
コード例 #8
0
    private Allocation(
        final String reservationId,
        final String instanceId,
        final String instanceUuid,
        final byte[] userData,
        final Date expiration,
        final Partition partition,
        final SshKeyPair sshKeyPair,
        final BootableSet bootSet,
        final VmType vmType,
        final Set<NetworkGroup> networkGroups,
        final boolean isUsePrivateAddressing,
        final boolean monitoring,
        final String clientToken,
        final String iamInstanceProfileArn,
        final String iamInstanceProfileId,
        final String iamRoleArn) {
      this.context = Contexts.lookup();
      this.minCount = 1;
      this.maxCount = 1;
      this.usePrivateAddressing = isUsePrivateAddressing;
      this.ownerFullName = context.getUserFullName();
      this.reservationId = reservationId;
      this.reservationIndex = UniqueIds.nextIndex(VmInstance.class, (long) this.maxCount);
      this.instanceIds = Maps.newHashMap();
      this.instanceIds.put(0, instanceId);
      this.instanceUuids = Maps.newHashMap();
      this.instanceUuids.put(0, instanceUuid);
      this.userData = userData;
      this.partition = partition;
      this.sshKeyPair = (sshKeyPair != null ? sshKeyPair : KeyPairs.noKey());
      this.bootSet = bootSet;
      this.expiration = expiration;
      this.vmType = vmType;
      this.monitoring = monitoring;
      this.clientToken = clientToken;
      this.iamInstanceProfileArn = iamInstanceProfileArn;
      this.iamInstanceProfileId = iamInstanceProfileId;
      this.iamRoleArn = iamRoleArn;
      this.credential = null;

      this.networkGroups =
          new HashMap<String, NetworkGroup>() {
            {
              for (NetworkGroup g : networkGroups) {
                if (Allocation.this.primaryNetwork == null) {
                  Allocation.this.primaryNetwork = g;
                }
                put(g.getDisplayName(), g);
              }
            }
          };
      this.request = inferRequest();
    }
コード例 #9
0
ファイル: Handlers.java プロジェクト: remtcs/eucalyptus
 @Override
 public void handleUpstream(final ChannelHandlerContext ctx, final ChannelEvent e)
     throws Exception {
   final MappingHttpMessage request = MappingHttpMessage.extractMessage(e);
   final BaseMessage msg = BaseMessage.extractMessage(e);
   if ((request != null) && (msg != null)) {
     final User user = Contexts.lookup(request.getCorrelationId()).getUser();
     if (user.isSystemAdmin() || ServiceOperations.isUserOperation(msg)) {
       ctx.sendUpstream(e);
     } else {
       Contexts.clear(Contexts.lookup(msg.getCorrelationId()));
       ctx.getChannel()
           .write(
               new MappingHttpResponse(
                   request.getProtocolVersion(), HttpResponseStatus.FORBIDDEN));
     }
   } else {
     ctx.sendUpstream(e);
   }
 }
コード例 #10
0
  private static void checkAuthorized() throws ReportingException {
    final Context ctx = Contexts.lookup();
    final User requestUser = ctx.getUser();
    final AuthContextSupplier requestUserSupplier = ctx.getAuthContext();

    if (!requestUser.isSystemUser()
        || !Permissions.isAuthorized(
            VENDOR_REPORTING, "", "", null, getIamActionByMessageType(), requestUserSupplier)) {
      throw new ReportingException(
          HttpResponseStatus.UNAUTHORIZED, ReportingException.NOT_AUTHORIZED, "Not authorized");
    }
  }
コード例 #11
0
 @Override
 public DescribeServicesResponseType apply(final DescribeServicesType input) {
   try {
     if (!Contexts.lookup().getUser().isSystemAdmin()) {
       return user(input);
     } else {
       return EmpyreanService.describeService(input);
     }
   } catch (final Exception ex) {
     throw Exceptions.toUndeclared(ex);
   }
 }
コード例 #12
0
  private static void handleException(final Exception e) throws CloudWatchException {
    final CloudWatchException cause = Exceptions.findCause(e, CloudWatchException.class);
    if (cause != null) {
      throw cause;
    }

    final InternalFailureException exception =
        new InternalFailureException(String.valueOf(e.getMessage()));
    if (Contexts.lookup().hasAdministrativePrivileges()) {
      exception.initCause(e);
    }
    throw exception;
  }
コード例 #13
0
  public GetMetricStatisticsResponseType getMetricStatistics(GetMetricStatisticsType request)
      throws CloudWatchException {
    GetMetricStatisticsResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();
    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_GETMETRICSTATISTICS, ctx);

      // TODO: parse statistics separately()?
      final OwnerFullName ownerFullName = ctx.getUserFullName();
      Statistics statistics = validateStatistics(request.getStatistics());
      final String namespace = validateNamespace(request.getNamespace(), true);
      final String metricName = validateMetricName(request.getMetricName(), true);
      final Date startTime =
          MetricManager.stripSeconds(validateStartTime(request.getStartTime(), true));
      final Date endTime = MetricManager.stripSeconds(validateEndTime(request.getEndTime(), true));
      final Integer period = validatePeriod(request.getPeriod(), true);
      validateDateOrder(startTime, endTime, "StartTime", "EndTime", true, true);
      validateNotTooManyDataPoints(startTime, endTime, period, 1440L);

      // TODO: null units here does not mean Units.NONE but basically a
      // wildcard.
      // Consider this case.
      final Units units = validateUnits(request.getUnit(), false);
      final Map<String, String> dimensionMap =
          TransformationFunctions.DimensionsToMap.INSTANCE.apply(
              validateDimensions(request.getDimensions()));
      Collection<MetricStatistics> metrics;
      metrics =
          MetricManager.getMetricStatistics(
              ownerFullName.getAccountNumber(),
              metricName,
              namespace,
              dimensionMap,
              getMetricTypeFromNamespace(namespace),
              units,
              startTime,
              endTime,
              period);
      reply.getGetMetricStatisticsResult().setLabel(metricName);
      ArrayList<Datapoint> datapoints = convertMetricStatisticsToDataoints(statistics, metrics);
      if (datapoints.size() > 0) {
        Datapoints datapointsReply = new Datapoints();
        datapointsReply.setMember(datapoints);
        reply.getGetMetricStatisticsResult().setDatapoints(datapointsReply);
      }
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
コード例 #14
0
  public ListMetricsResponseType listMetrics(ListMetricsType request) throws CloudWatchException {
    ListMetricsResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_LISTMETRICS, ctx);

      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String namespace = validateNamespace(request.getNamespace(), false);
      final String metricName = validateMetricName(request.getMetricName(), false);
      final Map<String, String> dimensionMap =
          TransformationFunctions.DimensionFiltersToMap.INSTANCE.apply(
              validateDimensionFilters(request.getDimensions()));

      // take all stats updated after two weeks ago
      final Date after = new Date(System.currentTimeMillis() - 2 * 7 * 24 * 60 * 60 * 1000L);
      final Date before = null; // no bound on time before stats are updated
      // (though maybe 'now')
      final Integer maxRecords = 500; // per the API docs
      final String nextToken = request.getNextToken();
      final List<ListMetric> results =
          ListMetricManager.listMetrics(
              ownerFullName.getAccountNumber(),
              metricName,
              namespace,
              dimensionMap,
              after,
              before,
              maxRecords,
              nextToken);

      final Metrics metrics = new Metrics();
      metrics.setMember(
          Lists.newArrayList(
              Collections2.<ListMetric, Metric>transform(
                  results, TransformationFunctions.ListMetricToMetric.INSTANCE)));
      final ListMetricsResult listMetricsResult = new ListMetricsResult();
      listMetricsResult.setMetrics(metrics);
      if (maxRecords != null && results.size() == maxRecords) {
        listMetricsResult.setNextToken(results.get(results.size() - 1).getNaturalId());
      }
      reply.setListMetricsResult(listMetricsResult);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
コード例 #15
0
  public DisableAlarmActionsResponseType disableAlarmActions(DisableAlarmActionsType request)
      throws EucalyptusCloudException {
    DisableAlarmActionsResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_DISABLEALARMACTIONS, ctx);
      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      Collection<String> alarmNames = validateAlarmNames(request.getAlarmNames(), true);
      AlarmManager.disableAlarmActions(accountId, alarmNames);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
コード例 #16
0
  public DescribeAlarmsResponseType describeAlarms(DescribeAlarmsType request)
      throws CloudWatchException {
    DescribeAlarmsResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_DESCRIBEALARMS, ctx);

      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      final String actionPrefix = validateActionPrefix(request.getActionPrefix(), false);
      final String alarmNamePrefix = validateAlarmNamePrefix(request.getAlarmNamePrefix(), false);
      final Collection<String> alarmNames = validateAlarmNames(request.getAlarmNames(), false);
      validateNotBothAlarmNamesAndAlarmNamePrefix(alarmNames, alarmNamePrefix);
      final Integer maxRecords = validateMaxRecords(request.getMaxRecords());
      final String nextToken = request.getNextToken();
      final StateValue stateValue = validateStateValue(request.getStateValue(), false);
      List<AlarmEntity> results =
          AlarmManager.describeAlarms(
              accountId,
              actionPrefix,
              alarmNamePrefix,
              alarmNames,
              maxRecords,
              stateValue,
              nextToken);
      if (maxRecords != null && results.size() == maxRecords) {
        reply
            .getDescribeAlarmsResult()
            .setNextToken(results.get(results.size() - 1).getNaturalId());
      }
      MetricAlarms metricAlarms = new MetricAlarms();
      metricAlarms.setMember(
          Lists.newArrayList(
              Collections2.<AlarmEntity, MetricAlarm>transform(
                  results, TransformationFunctions.AlarmEntityToMetricAlarm.INSTANCE)));
      reply.getDescribeAlarmsResult().setMetricAlarms(metricAlarms);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
コード例 #17
0
 public void handle(BaseMessage responseMessage) {
   EventRecord.here(
           EuareReplyQueue.class,
           EventType.MSG_REPLY,
           responseMessage.getCorrelationId(),
           responseMessage.getClass().getSimpleName())
       .debug();
   LOG.debug("HERE: " + responseMessage);
   String corrId = responseMessage.getCorrelationId();
   try {
     Context context = Contexts.lookup(corrId);
     Channel channel = context.getChannel();
     Channels.write(channel, responseMessage);
     Contexts.clear(context);
   } catch (NoSuchContextException e) {
     LOG.warn("Received a reply for absent client:  No channel to write response message.", e);
     LOG.debug(responseMessage);
   }
 }
コード例 #18
0
  public SetAlarmStateResponseType setAlarmState(SetAlarmStateType request)
      throws CloudWatchException {
    SetAlarmStateResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();
    try {

      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_SETALARMSTATE, ctx);
      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      final String alarmName = validateAlarmName(request.getAlarmName(), true);
      final String stateReason = validateStateReason(request.getStateReason(), true);
      final String stateReasonData = validateStateReasonData(request.getStateReasonData(), false);
      final StateValue stateValue = validateStateValue(request.getStateValue(), true);
      AlarmManager.setAlarmState(accountId, alarmName, stateReason, stateReasonData, stateValue);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
コード例 #19
0
  public DescribeAlarmHistoryResponseType describeAlarmHistory(DescribeAlarmHistoryType request)
      throws CloudWatchException {
    DescribeAlarmHistoryResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_DESCRIBEALARMHISTORY, ctx);

      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      final String alarmName = validateAlarmName(request.getAlarmName(), false);
      final Date endDate = validateEndDate(request.getEndDate(), false);
      final Date startDate = validateStartDate(request.getStartDate(), false);
      validateDateOrder(startDate, endDate, "StartDate", "EndDate", false, false);
      final HistoryItemType historyItemType =
          validateHistoryItemType(request.getHistoryItemType(), false);
      final Integer maxRecords = validateMaxRecords(request.getMaxRecords());
      final String nextToken = request.getNextToken();
      List<AlarmHistory> results =
          AlarmManager.describeAlarmHistory(
              accountId, alarmName, endDate, historyItemType, maxRecords, startDate, nextToken);
      if (maxRecords != null && results.size() == maxRecords) {
        reply
            .getDescribeAlarmHistoryResult()
            .setNextToken(results.get(results.size() - 1).getNaturalId());
      }
      AlarmHistoryItems alarmHistoryItems = new AlarmHistoryItems();
      alarmHistoryItems.setMember(
          Lists.newArrayList(
              Collections2.<AlarmHistory, AlarmHistoryItem>transform(
                  results, TransformationFunctions.AlarmHistoryToAlarmHistoryItem.INSTANCE)));
      reply.getDescribeAlarmHistoryResult().setAlarmHistoryItems(alarmHistoryItems);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
コード例 #20
0
    private Allocation(final RunInstancesType request) {
      this.context = Contexts.lookup();
      this.instanceIds = Maps.newHashMap();
      this.instanceUuids = Maps.newHashMap();
      this.request = request;
      this.minCount = request.getMinCount();
      this.maxCount = request.getMaxCount();
      this.usePrivateAddressing = "private".equals(request.getAddressingType());
      this.disableApiTermination =
          Optional.fromNullable(request.getDisableTerminate()).or(Boolean.FALSE);
      this.monitoring = request.getMonitoring() == null ? Boolean.FALSE : request.getMonitoring();
      this.clientToken = Strings.emptyToNull(request.getClientToken());

      this.ownerFullName = this.context.getUserFullName();
      if ((this.request.getInstanceType() == null) || "".equals(this.request.getInstanceType())) {
        this.request.setInstanceType(VmTypes.defaultTypeName());
      }

      this.reservationIndex = UniqueIds.nextIndex(VmInstance.class, (long) request.getMaxCount());
      this.reservationId = IdentityIdFormats.generate(getAuthenticatedArn(), "r");
      this.request.setMonitoring(this.monitoring);
      // GRZE:FIXME: moved all this encode/decode junk into util.UserDatas
      if (this.request.getUserData() != null) {
        try {
          this.userData = Base64.decode(this.request.getUserData());
          this.request.setUserData(new String(Base64.encode(this.userData)));
        } catch (Exception e) {
        }
      } else {
        try {
          this.request.setUserData(new String(Base64.encode(new byte[0])));
        } catch (Exception ex) {
          LOG.error(ex, ex);
        }
      }
      this.credential = null;
    }
コード例 #21
0
ファイル: Handlers.java プロジェクト: remtcs/eucalyptus
    @Override
    public void handleUpstream(
        final ChannelHandlerContext channelHandlerContext, final ChannelEvent channelEvent)
        throws Exception {
      if (channelEvent instanceof MessageEvent && componentIdClass != null) {
        final BaseMessage message = BaseMessage.extractMessage(channelEvent);
        final ComponentMessage componentMessage =
            message == null
                ? null
                : Ats.inClassHierarchy(message.getClass()).get(ComponentMessage.class);
        if (message != null
            && (componentMessage == null || !componentIdClass.equals(componentMessage.value()))) {
          LOG.warn(
              String.format(
                  "Message %s does not match pipeline component %s",
                  message.getClass(), componentIdClass.getSimpleName()));

          final MappingHttpMessage mappingHttpMessage =
              MappingHttpMessage.extractMessage(channelEvent);
          final BaseMessage baseMessage = BaseMessage.extractMessage(channelEvent);
          if (baseMessage != null) {
            Contexts.clear(Contexts.lookup(baseMessage.getCorrelationId()));
          }
          channelHandlerContext
              .getChannel()
              .write(
                  new MappingHttpResponse(
                      mappingHttpMessage == null
                          ? HttpVersion.HTTP_1_1
                          : mappingHttpMessage.getProtocolVersion(),
                      HttpResponseStatus.BAD_REQUEST));
          return;
        }
      }
      channelHandlerContext.sendUpstream(channelEvent);
    }
コード例 #22
0
ファイル: VolumeManager.java プロジェクト: sosilent/euca
 public DeleteVolumeResponseType DeleteVolume(final DeleteVolumeType request)
     throws EucalyptusCloudException {
   DeleteVolumeResponseType reply = (DeleteVolumeResponseType) request.getReply();
   final Context ctx = Contexts.lookup();
   reply.set_return(false);
   final Function<String, Volume> deleteVolume =
       new Function<String, Volume>() {
         @Override
         public Volume apply(final String input) {
           try {
             Volume vol =
                 Entities.uniqueResult(
                     Volume.named(ctx.getUserFullName().asAccountFullName(), input));
             if (!RestrictedTypes.filterPrivileged().apply(vol)) {
               throw Exceptions.toUndeclared(
                   "Not authorized to delete volume by " + ctx.getUser().getName());
             }
             try {
               VmVolumeAttachment attachment = VmInstances.lookupVolumeAttachment(input);
               throw new IllegalStateException("Volume is currently attached: " + attachment);
             } catch (NoSuchElementException ex) {
               /** no such volume attached, move along... * */
             }
             if (State.FAIL.equals(vol.getState()) || State.ANNIHILATED.equals(vol.getState())) {
               Entities.delete(vol);
               Volumes.fireDeleteEvent(vol);
               return vol;
             } else if (State.ANNIHILATING.equals(vol.getState())) {
               return vol;
             } else {
               try {
                 ServiceConfiguration sc =
                     Topology.lookup(Storage.class, Partitions.lookupByName(vol.getPartition()));
                 DeleteStorageVolumeResponseType scReply =
                     AsyncRequests.sendSync(sc, new DeleteStorageVolumeType(vol.getDisplayName()));
                 if (scReply.get_return()) {
                   vol.setState(State.ANNIHILATING);
                   return vol;
                 } else {
                   throw Exceptions.toUndeclared(
                       "Storage Controller returned false:  Contact the administrator to report the problem.");
                 }
               } catch (Exception ex) {
                 throw Exceptions.toUndeclared(
                     "Storage Controller request failed:  Contact the administrator to report the problem.",
                     ex);
               }
             }
           } catch (NoSuchElementException ex) {
             throw ex;
           } catch (TransactionException ex) {
             throw Exceptions.toUndeclared(
                 "Deleting volume failed:  Contact the administrator to report the problem.", ex);
           }
         }
       };
   try {
     Entities.asTransaction(Volume.class, deleteVolume).apply(request.getVolumeId());
     reply.set_return(true);
     return reply;
   } catch (NoSuchElementException ex) {
     return reply;
   } catch (RuntimeException ex) {
     throw ex;
   }
 }
コード例 #23
0
ファイル: VolumeManager.java プロジェクト: sosilent/euca
  public DescribeVolumesResponseType DescribeVolumes(DescribeVolumesType request) throws Exception {
    final DescribeVolumesResponseType reply = (DescribeVolumesResponseType) request.getReply();
    final Context ctx = Contexts.lookup();
    final boolean showAll = request.getVolumeSet().remove("verbose");
    final AccountFullName ownerFullName =
        (ctx.hasAdministrativePrivileges() && showAll)
            ? null
            : ctx.getUserFullName().asAccountFullName();
    final Set<String> volumeIds = Sets.newHashSet();
    if (!request.getVolumeSet().isEmpty()) {
      volumeIds.addAll(request.getVolumeSet());
    }
    final Function<Set<String>, Set<String>> lookupVolumeIds =
        new Function<Set<String>, Set<String>>() {
          public Set<String> apply(final Set<String> input) {
            Set<String> res = Sets.newHashSet();
            if (input.isEmpty()) {
              for (Volume foundVol :
                  Collections2.filter(
                      Entities.query(Volume.named(ownerFullName, null)),
                      RestrictedTypes.filterPrivileged())) {
                res.add(foundVol.getDisplayName());
              }
            } else {
              for (String s : input) {
                try {
                  Volume foundVol = Entities.uniqueResult(Volume.named(ownerFullName, s));
                  if (RestrictedTypes.filterPrivileged().apply(foundVol)) {
                    res.add(foundVol.getDisplayName());
                  }
                } catch (NoSuchElementException ex) {
                } catch (TransactionException ex) {
                  throw Exceptions.toUndeclared(ex);
                }
              }
            }
            return res;
          }
        };
    Set<String> allowedVolumeIds =
        Entities.asTransaction(Volume.class, lookupVolumeIds).apply(volumeIds);
    final Function<String, Volume> lookupVolume =
        new Function<String, Volume>() {

          @Override
          public Volume apply(String input) {
            try {
              Volume foundVol = Entities.uniqueResult(Volume.named(ownerFullName, input));
              if (State.ANNIHILATED.equals(foundVol.getState())) {
                Entities.delete(foundVol);
                Volumes.fireDeleteEvent(foundVol);
                reply.getVolumeSet().add(foundVol.morph(new edu.ucsb.eucalyptus.msgs.Volume()));
                return foundVol;
              } else if (RestrictedTypes.filterPrivileged().apply(foundVol)) {
                AttachedVolume attachedVolume = null;
                try {
                  VmVolumeAttachment attachment = VmInstances.lookupVolumeAttachment(input);
                  attachedVolume =
                      VmVolumeAttachment.asAttachedVolume(attachment.getVmInstance())
                          .apply(attachment);
                } catch (NoSuchElementException ex) {
                  if (State.BUSY.equals(foundVol.getState())) {
                    foundVol.setState(State.EXTANT);
                  }
                }
                edu.ucsb.eucalyptus.msgs.Volume msgTypeVolume =
                    foundVol.morph(new edu.ucsb.eucalyptus.msgs.Volume());
                if (attachedVolume != null) {
                  msgTypeVolume.setStatus("in-use");
                  msgTypeVolume.getAttachmentSet().add(attachedVolume);
                }
                reply.getVolumeSet().add(msgTypeVolume);
                return foundVol;
              }
            } catch (NoSuchElementException ex) {
              throw ex;
            } catch (TransactionException ex) {
              throw Exceptions.toUndeclared(ex);
            }
            throw new NoSuchElementException("Failed to lookup volume: " + input);
          }
        };
    for (String volId : allowedVolumeIds) {
      try {
        Volume vol = Entities.asTransaction(Volume.class, lookupVolume).apply(volId);
      } catch (Exception ex) {
        Logs.extreme().debug(ex, ex);
      }
    }
    return reply;
  }
コード例 #24
0
  /**
   * Evaluates the authorization for the operation requested, evaluates IAM, ACL, and bucket policy
   * (bucket policy not yet supported).
   *
   * @param request
   * @param bucketResourceEntity
   * @param objectResourceEntity
   * @param resourceAllocationSize the size for the quota check(s) if applicable
   * @return
   */
  public <T extends ObjectStorageRequestType> boolean operationAllowed(
      @Nonnull T request,
      @Nullable final S3AccessControlledEntity bucketResourceEntity,
      @Nullable final S3AccessControlledEntity objectResourceEntity,
      long resourceAllocationSize)
      throws IllegalArgumentException {
    /*
     * Process the operation's authz requirements based on the request type annotations
     */
    Ats requestAuthzProperties = Ats.from(request);
    ObjectStorageProperties.Permission[] requiredBucketACLPermissions = null;
    ObjectStorageProperties.Permission[] requiredObjectACLPermissions = null;
    Boolean allowOwnerOnly = null;
    RequiresACLPermission requiredACLs = requestAuthzProperties.get(RequiresACLPermission.class);
    if (requiredACLs != null) {
      requiredBucketACLPermissions = requiredACLs.bucket();
      requiredObjectACLPermissions = requiredACLs.object();
      allowOwnerOnly = requiredACLs.ownerOnly();
    } else {
      // No ACL annotation is ok, maybe a admin only op
    }

    String[] requiredActions = null;
    RequiresPermission perms = requestAuthzProperties.get(RequiresPermission.class);
    if (perms != null) {
      requiredActions = perms.value();
    }

    Boolean allowAdmin = (requestAuthzProperties.get(AdminOverrideAllowed.class) != null);
    Boolean allowOnlyAdmin =
        (requestAuthzProperties.get(AdminOverrideAllowed.class) != null)
            && requestAuthzProperties.get(AdminOverrideAllowed.class).adminOnly();

    // Must have at least one of: admin-only, owner-only, ACL, or IAM.
    if (requiredBucketACLPermissions == null
        && requiredObjectACLPermissions == null
        && requiredActions == null
        && !allowAdmin) {
      // Insufficient permission set on the message type.
      LOG.error(
          "Insufficient permission annotations on type: "
              + request.getClass().getName()
              + " cannot evaluate authorization");
      return false;
    }

    String resourceType = null;
    if (requestAuthzProperties.get(ResourceType.class) != null) {
      resourceType = requestAuthzProperties.get(ResourceType.class).value();
    }

    // Use these variables to isolate where all the AuthExceptions can happen on account/user
    // lookups
    User requestUser = null;
    String securityToken = null;
    Account requestAccount = null;
    AuthContextSupplier authContext = null;
    try {
      // Use context if available as it saves a DB lookup
      try {
        Context ctx = Contexts.lookup(request.getCorrelationId());
        requestUser = ctx.getUser();
        securityToken = ctx.getSecurityToken();
        requestAccount = requestUser.getAccount();
        authContext = ctx.getAuthContext();
      } catch (NoSuchContextException e) {
        requestUser = null;
        securityToken = null;
        requestAccount = null;
        authContext = null;
      }

      // This is not an expected path, but if no context found use the request credentials itself
      if (requestUser == null && !Strings.isNullOrEmpty(request.getEffectiveUserId())) {
        requestUser = Accounts.lookupUserById(request.getEffectiveUserId());
        requestAccount = requestUser.getAccount();
      }

      if (requestUser == null) {
        if (!Strings.isNullOrEmpty(request.getAccessKeyID())) {
          if (securityToken != null) {
            requestUser = SecurityTokenManager.lookupUser(request.getAccessKeyID(), securityToken);
          } else {
            requestUser = Accounts.lookupUserByAccessKeyId(request.getAccessKeyID());
          }
          requestAccount = requestUser.getAccount();
        } else {
          // Set to anonymous user since all else failed
          requestUser = Principals.nobodyUser();
          requestAccount = requestUser.getAccount();
        }
      }
    } catch (AuthException e) {
      LOG.error(
          "Failed to get user for request, cannot verify authorization: " + e.getMessage(), e);
      return false;
    }

    if (allowAdmin && requestUser.isSystemAdmin()) {
      // Admin override
      return true;
    }

    if (authContext == null) {
      authContext =
          Permissions.createAuthContextSupplier(
              requestUser, Collections.<String, String>emptyMap());
    }

    Account resourceOwnerAccount = null;
    if (resourceType == null) {
      LOG.error("No resource type found in request class annotations, cannot process.");
      return false;
    } else {
      try {
        // Ensure we have the proper resource entities present and get owner info
        if (PolicySpec.S3_RESOURCE_BUCKET.equals(resourceType)) {
          // Get the bucket owner.
          if (bucketResourceEntity == null) {
            LOG.error(
                "Could not check access for operation due to no bucket resource entity found");
            return false;
          } else {
            resourceOwnerAccount =
                Accounts.lookupAccountByCanonicalId(bucketResourceEntity.getOwnerCanonicalId());
          }
        } else if (PolicySpec.S3_RESOURCE_OBJECT.equals(resourceType)) {
          if (objectResourceEntity == null) {
            LOG.error(
                "Could not check access for operation due to no object resource entity found");
            return false;
          } else {
            resourceOwnerAccount =
                Accounts.lookupAccountByCanonicalId(objectResourceEntity.getOwnerCanonicalId());
          }
        }
      } catch (AuthException e) {
        LOG.error("Exception caught looking up resource owner. Disallowing operation.", e);
        return false;
      }
    }

    // Get the resourceId based on IAM resource type
    String resourceId = null;
    if (resourceId == null) {
      if (PolicySpec.S3_RESOURCE_BUCKET.equals(resourceType)) {
        resourceId = request.getBucket();
      } else if (PolicySpec.S3_RESOURCE_OBJECT.equals(resourceType)) {
        resourceId = request.getFullResource();
      }
    }

    if (allowAdmin
        && requestUser.isSystemUser()
        && iamPermissionsAllow(
            authContext, requiredActions, resourceType, resourceId, resourceAllocationSize)) {
      // Admin override
      return true;
    }

    if (requiredBucketACLPermissions == null && requiredObjectACLPermissions == null) {
      throw new IllegalArgumentException(
          "No requires-permission actions found in request class annotations, cannot process.");
    }

    /* ACL Checks: Is the user's account allowed? */
    Boolean aclAllow = false;
    if (requiredBucketACLPermissions != null && requiredBucketACLPermissions.length > 0) {
      // Check bucket ACLs

      if (bucketResourceEntity == null) {
        // There are bucket ACL requirements but no bucket entity to check. fail.
        // Don't bother with other checks, this is an invalid state
        LOG.error("Null bucket resource, cannot evaluate bucket ACL");
        return false;
      }

      // Evaluate the bucket ACL, any matching grant gives permission
      for (ObjectStorageProperties.Permission permission : requiredBucketACLPermissions) {
        aclAllow =
            aclAllow || bucketResourceEntity.can(permission, requestAccount.getCanonicalId());
      }
    }

    // Check object ACLs, if any
    if (requiredObjectACLPermissions != null && requiredObjectACLPermissions.length > 0) {
      if (objectResourceEntity == null) {
        // There are object ACL requirements but no object entity to check. fail.
        // Don't bother with other checks, this is an invalid state
        LOG.error("Null bucket resource, cannot evaluate bucket ACL");
        return false;
      }
      for (ObjectStorageProperties.Permission permission : requiredObjectACLPermissions) {
        aclAllow =
            aclAllow || objectResourceEntity.can(permission, requestAccount.getCanonicalId());
      }
    }

    /* Resource owner only? if so, override any previous acl decisions
     * It is not expected that owneronly is set as well as other ACL permissions,
     * Regular owner permissions (READ, WRITE, READ_ACP, WRITE_ACP) are handled by the regular acl checks.
     * OwnerOnly should be only used for operations not covered by the other Permissions (e.g. logging, or versioning)
     */
    aclAllow =
        (allowOwnerOnly
            ? resourceOwnerAccount.getAccountNumber().equals(requestAccount.getAccountNumber())
            : aclAllow);
    if (aclAllow && isUserAnonymous(requestUser)) {
      // Skip the IAM checks for anonymous access since they will always fail and aren't valid for
      // anonymous users.
      return true;
    } else {
      Boolean iamAllow =
          iamPermissionsAllow(
              authContext, requiredActions, resourceType, resourceId, resourceAllocationSize);
      // Must have both acl and iam allow (account & user)
      return aclAllow && iamAllow;
    }
  }
コード例 #25
0
ファイル: VolumeManager.java プロジェクト: sosilent/euca
  public AttachVolumeResponseType AttachVolume(AttachVolumeType request)
      throws EucalyptusCloudException {
    AttachVolumeResponseType reply = (AttachVolumeResponseType) request.getReply();
    final String deviceName = request.getDevice();
    final String volumeId = request.getVolumeId();
    final Context ctx = Contexts.lookup();

    if (request.getDevice() == null
        || request.getDevice().endsWith("sda")
        || request.getDevice().endsWith("sdb")) {
      throw new EucalyptusCloudException("Invalid device name specified: " + request.getDevice());
    }
    VmInstance vm = null;
    try {
      vm = RestrictedTypes.doPrivileged(request.getInstanceId(), VmInstance.class);
    } catch (NoSuchElementException ex) {
      LOG.debug(ex, ex);
      throw new EucalyptusCloudException("Instance does not exist: " + request.getInstanceId(), ex);
    } catch (Exception ex) {
      LOG.debug(ex, ex);
      throw new EucalyptusCloudException(ex.getMessage(), ex);
    }
    AccountFullName ownerFullName = ctx.getUserFullName().asAccountFullName();
    Volume volume = Volumes.lookup(ownerFullName, volumeId);
    if (!RestrictedTypes.filterPrivileged().apply(volume)) {
      throw new EucalyptusCloudException(
          "Not authorized to attach volume "
              + request.getVolumeId()
              + " by "
              + ctx.getUser().getName());
    }
    try {
      vm.lookupVolumeAttachmentByDevice(deviceName);
      throw new EucalyptusCloudException(
          "Already have a device attached to: " + request.getDevice());
    } catch (NoSuchElementException ex1) {
      /** no attachment * */
    }
    try {
      VmInstances.lookupVolumeAttachment(volumeId);
      throw new EucalyptusCloudException("Volume already attached: " + request.getVolumeId());
    } catch (NoSuchElementException ex1) {
      /** no attachment * */
    }

    Partition volPartition = Partitions.lookupByName(volume.getPartition());
    ServiceConfiguration sc = Topology.lookup(Storage.class, volPartition);
    ServiceConfiguration scVm = Topology.lookup(Storage.class, vm.lookupPartition());
    if (!sc.equals(scVm)) {
      throw new EucalyptusCloudException(
          "Can only attach volumes in the same zone: " + request.getVolumeId());
    }
    ServiceConfiguration ccConfig = Topology.lookup(ClusterController.class, vm.lookupPartition());
    AttachStorageVolumeResponseType scAttachResponse;
    try {
      AttachStorageVolumeType req =
          new AttachStorageVolumeType(Nodes.lookupIqn(vm), volume.getDisplayName());
      scAttachResponse = AsyncRequests.sendSync(sc, req);
    } catch (Exception e) {
      LOG.debug(e, e);
      throw new EucalyptusCloudException(e.getMessage(), e);
    }
    request.setRemoteDevice(scAttachResponse.getRemoteDeviceString());

    AttachedVolume attachVol =
        new AttachedVolume(
            volume.getDisplayName(),
            vm.getInstanceId(),
            request.getDevice(),
            request.getRemoteDevice());
    vm.addTransientVolume(deviceName, scAttachResponse.getRemoteDeviceString(), volume);
    AsyncRequests.newRequest(new VolumeAttachCallback(request)).dispatch(ccConfig);

    EventRecord.here(VolumeManager.class, EventClass.VOLUME, EventType.VOLUME_ATTACH)
        .withDetails(
            volume.getOwner().toString(), volume.getDisplayName(), "instance", vm.getInstanceId())
        .withDetails("partition", vm.getPartition().toString())
        .info();
    reply.setAttachedVolume(attachVol);
    return reply;
  }
コード例 #26
0
ファイル: VolumeManager.java プロジェクト: sosilent/euca
  public DetachVolumeResponseType detach(DetachVolumeType request) throws EucalyptusCloudException {
    DetachVolumeResponseType reply = (DetachVolumeResponseType) request.getReply();
    Context ctx = Contexts.lookup();

    Volume vol;
    try {
      vol = Volumes.lookup(ctx.getUserFullName().asAccountFullName(), request.getVolumeId());
    } catch (Exception ex1) {
      throw new EucalyptusCloudException("Volume does not exist: " + request.getVolumeId());
    }
    if (!RestrictedTypes.filterPrivileged().apply(vol)) {
      throw new EucalyptusCloudException(
          "Not authorized to detach volume "
              + request.getVolumeId()
              + " by "
              + ctx.getUser().getName());
    }

    VmInstance vm = null;
    AttachedVolume volume = null;
    try {
      VmVolumeAttachment vmVolAttach = VmInstances.lookupVolumeAttachment(request.getVolumeId());
      volume = VmVolumeAttachment.asAttachedVolume(vmVolAttach.getVmInstance()).apply(vmVolAttach);
      vm = vmVolAttach.getVmInstance();
    } catch (NoSuchElementException ex) {
      /** no such attachment * */
    }
    if (volume == null) {
      throw new EucalyptusCloudException("Volume is not attached: " + request.getVolumeId());
    }
    if (!RestrictedTypes.filterPrivileged().apply(vm)) {
      throw new EucalyptusCloudException(
          "Not authorized to detach volume from instance "
              + request.getInstanceId()
              + " by "
              + ctx.getUser().getName());
    }
    if (!vm.getInstanceId().equals(request.getInstanceId())
        && request.getInstanceId() != null
        && !request.getInstanceId().equals("")) {
      throw new EucalyptusCloudException(
          "Volume is not attached to instance: " + request.getInstanceId());
    }
    if (request.getDevice() != null
        && !request.getDevice().equals("")
        && !volume.getDevice().equals(request.getDevice())) {
      throw new EucalyptusCloudException(
          "Volume is not attached to device: " + request.getDevice());
    }

    Cluster cluster = null;
    ServiceConfiguration ccConfig = null;
    try {
      ccConfig = Topology.lookup(ClusterController.class, vm.lookupPartition());
      cluster = Clusters.lookup(ccConfig);
    } catch (NoSuchElementException e) {
      LOG.debug(e, e);
      throw new EucalyptusCloudException(
          "Cluster does not exist in partition: " + vm.getPartition());
    }
    ServiceConfiguration scVm;
    try {
      scVm = Topology.lookup(Storage.class, vm.lookupPartition());
    } catch (Exception ex) {
      LOG.error(ex, ex);
      throw new EucalyptusCloudException(
          "Failed to lookup SC for partition: " + vm.getPartition(), ex);
    }
    request.setVolumeId(volume.getVolumeId());
    request.setRemoteDevice(volume.getRemoteDevice());
    request.setDevice(volume.getDevice().replaceAll("unknown,requested:", ""));
    request.setInstanceId(vm.getInstanceId());
    VolumeDetachCallback ncDetach = new VolumeDetachCallback(request);
    try {
      AsyncRequests.sendSync(scVm, new DetachStorageVolumeType(volume.getVolumeId()));
    } catch (Exception e) {
      LOG.debug(e);
      Logs.extreme().debug(e, e);
      // GRZE: attach is idempotent, failure here is ok.      throw new EucalyptusCloudException(
      // e.getMessage( ) );
    }
    AsyncRequests.newRequest(ncDetach).dispatch(cluster.getConfiguration());
    EventRecord.here(VolumeManager.class, EventClass.VOLUME, EventType.VOLUME_DETACH)
        .withDetails(vm.getOwner().toString(), volume.getVolumeId(), "instance", vm.getInstanceId())
        .withDetails("cluster", ccConfig.getFullName().toString())
        .info();
    volume.setStatus("detaching");
    reply.setDetachedVolume(volume);
    return reply;
  }