Skip to content

Instantly share code, notes, and snippets.

@gregsheremeta
Created July 9, 2018 14:08
Show Gist options
  • Save gregsheremeta/761527f4211b3e327d76f2227ee929be to your computer and use it in GitHub Desktop.
Save gregsheremeta/761527f4211b3e327d76f2227ee929be to your computer and use it in GitHub Desktop.
AnsibleServlet
/*
Copyright (c) 2018 Red Hat, Inc.
Licensed 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 org.ovirt.engine.core.services;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.inject.Inject;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.ovirt.engine.core.common.utils.Pair;
import org.ovirt.engine.core.common.utils.ansible.AnsibleCommandBuilder;
import org.ovirt.engine.core.common.utils.ansible.AnsibleExecutor;
import org.ovirt.engine.core.common.utils.ansible.AnsibleReturnCode;
import org.ovirt.engine.core.common.utils.ansible.AnsibleReturnValue;
import org.ovirt.engine.core.utils.EngineLocalConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AnsibleServlet extends HttpServlet {
private static final long serialVersionUID = -8894175367839134323L;
private static final Logger log = LoggerFactory.getLogger(AnsibleServlet.class);
private static final String BEARER = "Bearer";
private static final String HEADER_AUTHORIZATION = "Authorization";
@Inject
private AnsibleExecutor ansibleExecutor;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
// TODO: check permissions
Path variablesFile = null;
try {
EngineLocalConfig config = EngineLocalConfig.getInstance();
variablesFile = createVariablesFile(request);
AnsibleCommandBuilder command = new AnsibleCommandBuilder()
.variables(
new Pair<>("engine_url", String.format("https://%s:%s/ovirt-engine/api", config.getHost(), config.getHttpsPort())),
new Pair<>("engine_token", getTokenFromHeader(request)),
new Pair<>("engine_insecure", "true")
// TODO: use CA file
)
.variableFilePath(variablesFile.toString())
.playbook(request.getParameter("playbook") + ".yml");
AnsibleReturnValue ansibleReturnValue = ansibleExecutor.runCommand(command);
if (ansibleReturnValue.getAnsibleReturnCode() != AnsibleReturnCode.OK) {
log.error("Error while executing command.");
response.setStatus(HttpURLConnection.HTTP_INTERNAL_ERROR);
}
} catch (IOException | InterruptedException e) {
log.error("Error while executing command.", e);
response.setStatus(HttpURLConnection.HTTP_INTERNAL_ERROR);
} finally {
if (variablesFile != null) {
try {
Files.delete(variablesFile);
} catch (IOException ex) {
log.debug("Failed to delete temporary file '{}': {}", variablesFile, ex.getMessage());
}
}
}
}
private Path createVariablesFile(HttpServletRequest request) throws IOException {
BufferedReader body = request.getReader();
StringBuilder buffer = new StringBuilder();
int r;
while ((r = body.read()) != -1) {
buffer.append((char) r);
}
Path variablesFile = Files.createTempFile("ansible-variables", "");
Files.write(variablesFile, buffer.toString().getBytes());
return variablesFile;
}
private String getTokenFromHeader(HttpServletRequest request) {
String token = null;
String headerValue = request.getHeader(HEADER_AUTHORIZATION);
if (headerValue != null && headerValue.startsWith(BEARER)) {
token = headerValue.substring(BEARER.length()).trim();
}
return token;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment