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; }
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; }
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; }
@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()); } } } } }
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); } }
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; }
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); }
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(); }
@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); } }
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"); } }
@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); } }
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; }
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; }
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; }
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; }
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; }
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); } }
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; }
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; }
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; }
@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); }
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; } }
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; }
/** * 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; } }
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; }
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; }