blob: 639456412891f361497e4b91ee181d408f3232e1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.epam.dlab.backendapi.service.impl;
import com.epam.dlab.auth.SystemUserInfoService;
import com.epam.dlab.backendapi.ProvisioningServiceApplicationConfiguration;
import com.epam.dlab.backendapi.core.Directories;
import com.epam.dlab.backendapi.core.commands.DockerAction;
import com.epam.dlab.backendapi.core.commands.DockerCommands;
import com.epam.dlab.backendapi.core.commands.RunDockerCommand;
import com.epam.dlab.backendapi.core.response.handlers.ReuploadKeyCallbackHandler;
import com.epam.dlab.dto.reuploadkey.ReuploadKeyCallbackDTO;
import com.epam.dlab.dto.reuploadkey.ReuploadKeyDTO;
import com.epam.dlab.exceptions.DlabException;
import com.epam.dlab.model.ResourceData;
import com.epam.dlab.rest.contracts.ApiCallbacks;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import static java.lang.String.format;
import static java.nio.file.Files.readAllBytes;
import static java.nio.file.Paths.get;
@Slf4j
@Singleton
public class KeyService extends DockerService implements DockerCommands {
private static final String REUPLOAD_KEY_ACTION = "reupload_key";
private final SystemUserInfoService systemUserInfoService;
private final ProvisioningServiceApplicationConfiguration conf;
@Inject
public KeyService(SystemUserInfoService systemUserInfoService, ProvisioningServiceApplicationConfiguration conf) {
this.systemUserInfoService = systemUserInfoService;
this.conf = conf;
}
public void reuploadKeyAction(String userName, ReuploadKeyDTO dto, DockerAction action) {
log.debug("{} for edge user {}", action, dto.getEdgeUserName());
long count = dto.getResources()
.stream()
.map(resourceData -> buildCallbackDTO(resourceData, getUuid(), dto))
.peek(callbackDto -> startCallbackListener(userName, callbackDto))
.peek(callbackDto ->
runDockerCmd(userName, callbackDto.getId(), buildRunDockerCommand(callbackDto, action),
buildDockerCommandDTO(callbackDto)))
.count();
log.debug("Executed {} Docker commands", count);
}
public String getAdminKey() {
try {
return new String(readAllBytes(get(format("%s/%s.pem", conf.getKeyDirectory(), conf.getAdminKey()))));
} catch (IOException e) {
log.error("Can not read admin key: {}", e.getMessage());
throw new DlabException("Can not read admin key: " + e.getMessage(), e);
}
}
private String getUuid() {
return DockerCommands.generateUUID();
}
private void runDockerCmd(String userName, String uuid, RunDockerCommand runDockerCommand,
ReuploadKeyCallbackDTO callbackDto) {
try {
final String command = commandBuilder.buildCommand(runDockerCommand, callbackDto);
log.trace("Docker command: {}", command);
commandExecutor.executeAsync(userName, uuid, command);
} catch (Exception e) {
log.error("Exception occured during reuploading key: {} for command {}", e.getLocalizedMessage(),
runDockerCommand.toCMD());
}
}
private void startCallbackListener(String userName, ReuploadKeyCallbackDTO dto) {
folderListenerExecutor.start(configuration.getKeyLoaderDirectory(),
configuration.getKeyLoaderPollTimeout(),
new ReuploadKeyCallbackHandler(selfService, systemUserInfoService, ApiCallbacks.REUPLOAD_KEY_URI,
userName, dto));
}
@Override
public String getResourceType() {
return Directories.EDGE_LOG_DIRECTORY;
}
private RunDockerCommand buildRunDockerCommand(ReuploadKeyCallbackDTO callbackDto, DockerAction action) {
return new RunDockerCommand()
.withInteractive()
.withName(getContainerName(callbackDto))
.withVolumeForRootKeys(configuration.getKeyDirectory())
.withVolumeForResponse(configuration.getKeyLoaderDirectory())
.withVolumeForLog(configuration.getDockerLogDirectory(), getResourceType())
.withResource(callbackDto.getResource().getResourceType().toString())
.withRequestId(callbackDto.getId())
.withConfKeyName(configuration.getAdminKey())
.withImage(configuration.getEdgeImage())
.withAction(action);
}
private ReuploadKeyCallbackDTO buildCallbackDTO(ResourceData resource, String uuid, ReuploadKeyDTO dto) {
return new ReuploadKeyCallbackDTO()
.withId(uuid)
.withEdgeUserName(dto.getEdgeUserName())
.withServiceBaseName(dto.getServiceBaseName())
.withConfOsFamily(dto.getConfOsFamily())
.withResourceId(resource.getResourceId())
.withResource(resource);
}
private ReuploadKeyCallbackDTO buildDockerCommandDTO(ReuploadKeyCallbackDTO dto) {
return new ReuploadKeyCallbackDTO()
.withEdgeUserName(dto.getEdgeUserName())
.withServiceBaseName(dto.getServiceBaseName())
.withConfOsFamily(dto.getConfOsFamily())
.withResourceId(dto.getResourceId());
}
private String getContainerName(ReuploadKeyCallbackDTO callbackDto) {
return nameContainer(callbackDto.getEdgeUserName(), REUPLOAD_KEY_ACTION,
callbackDto.getResource().getResourceType().toString(),
callbackDto.getResource().getResourceId());
}
}