Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Initial import of code from ansible/ansible.
Browse files Browse the repository at this point in the history
  • Loading branch information
mattclay committed Apr 16, 2018
1 parent e1b5569 commit 2a5bcdc
Show file tree
Hide file tree
Showing 3 changed files with 377 additions and 0 deletions.
39 changes: 39 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
FROM fedora:26

RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*; \
rm -f /etc/systemd/system/*.wants/*; \
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*; \
rm -f /lib/systemd/system/anaconda.target.wants/*;

RUN dnf clean all && \
dnf -y --setopt=install_weak_deps=false install \
git \
glibc \
gcc \
golang-bin \
python-devel \
python-pip \
python-setuptools \
redhat-rpm-config \
yum \
&& \
dnf clean all

VOLUME /sys/fs/cgroup /run /tmp
ENV container=docker
RUN mkdir -p /opt/gocode
RUN chmod -R 777 /opt/gocode
ENV GOPATH=/opt/gocode
RUN go get -u github.com/vmware/govmomi/vcsim
RUN go get github.com/vmware/govmomi/govc
RUN pip install psutil
RUN pip install flask
ADD flask_control.py /root/flask_control.py


EXPOSE 5000 8989 443 80 8080
CMD ["/root/flask_control.py"]
335 changes: 335 additions & 0 deletions flask_control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,335 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# (c) 2017 James Tanner (@jctanner) <[email protected]>
# Abhijeet Kasurde (@akasurde) <[email protected]>
#
# Written by James Tanner <[email protected]>
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.

import os
import psutil
import socket
import subprocess

from flask import Flask
from flask import jsonify
from flask import request


app = Flask(__name__)
GOPATH = os.path.expanduser('/opt/gocode')
VCSIMPATH = os.path.join(GOPATH, 'bin', 'vcsim')
GOVCPATH = os.path.join(GOPATH, 'bin', 'govc')
GOVCURL = None


@app.route('/')
def m_index():
return 'vcsim controller'


@app.route('/log')
def get_log():
"""Read and return the vcsim log"""
fdata = ''
if os.path.isfile('vcsim.log'):
with open('vcsim.log', 'rb') as f:
fdata = f.read()
return fdata


@app.route('/kill/<int:number>')
def kill_one(number):
"""Kill any arbitrary process id"""

success = False
e = None

try:
p = psutil.Process(number)
p.terminate()
success = True
except Exception as e:
pass

return jsonify({'success': success, 'e': str(e)})


@app.route('/killall')
def kill_all():
"""Kill ALL of the running vcsim pids"""

results = []

for x in psutil.pids():
p = psutil.Process(x)
if VCSIMPATH in p.cmdline():
success = False
e = None
try:
p.terminate()
success = True
except Exception as e:
pass
results.append(
{'pid': x, 'cmdline': p.cmdline(),
'success': success, 'e': str(e)}
)

return jsonify(results)


@app.route('/spawn')
def spawn_vcsim():
"""Launch vcsim in a background process and return the pid+govcm_url"""

global GOVCURL

username = request.args.get('username') or 'user'
password = request.args.get('password') or 'pass'
hostname = request.args.get('hostname') or \
socket.gethostbyname(socket.gethostname())
port = request.args.get('port') or '443'
port = int(port)

# FIXME - enable tracing
if request.args.get('trace'):
trace = True
else:
trace = False

# vcsim cli options and their default values
cli_opts = [
['app', 0],
['cluster', 0],
['dc', 1],
['ds', 1],
['folder', 1],
['host', 3],
['pg', 1],
['pod', 1],
['pool', 1],
['vm', 2]
]

# useful for client govc commands
govc_url = 'https://%s:%s@%s:%s' % (username, password, hostname, port)
GOVCURL = govc_url

# need these to run the service
env = {
'GOPATH': GOPATH,
'GOVC_URL': govc_url,
'GOVC_INSECURE': '1'
}

# build the command
cmd = [
VCSIMPATH,
'-httptest.serve',
'%s:%s' % (hostname, port),
]

# trace soap requests+responses
if trace:
cmd.append('-trace')

# esx only allows certain arguments
if request.args.get('esx'):
cmd.append('-esx')
for x in [('vm', 1), ('ds', 1)]:
name = x[0]
default = x[1]
if request.args.get(name):
default = request.args.get(name)
cmd.append('-%s=%s' % (name, default))
else:
# use all other options as requested for vcenter
for x in cli_opts:
name = x[0]
default = x[1]
if request.args.get(name):
default = request.args.get(name)
cmd.append('-%s=%s' % (name, default))
cmd = ' '.join(cmd)
cmd += ' > vcsim.log 2>&1'

# run it with environment settings
p = subprocess.Popen(
cmd,
env=env,
shell=True
)

# return the relevant data
pid = p.pid
rdata = {
'cmd': cmd,
'pid': pid,
'host': hostname,
'port': port,
'username': username,
'password': password,
'GOVC_URL': govc_url
}

return jsonify(rdata)


@app.route('/govc_find')
def govc_find():
"""Run govc find and optionally filter results"""
ofilter = request.args.get('filter') or None
stdout_lines = _get_all_objs(ofilter=ofilter)
return jsonify(stdout_lines)


@app.route('/govc_vm_info')
def get_govc_vm_info():
"""Run govc vm info """
vm_name = request.args.get('vm_name') or None
vm_output = {}
if vm_name:
all_vms = [vm_name]
else:
# Get all VMs
all_vms = _get_all_objs(ofilter='VM')

for vm_name in all_vms:
vm_info = _get_vm_info(vm_name=vm_name)
name = vm_info.get('Name', vm_name)
vm_output[name] = vm_info

return jsonify(vm_output)


@app.route('/govc_host_info')
def get_govc_host_info():
""" Run govc host.info """
host_name = request.args.get("host_name") or None
host_output = {}
if host_name:
all_hosts = [host_name]
else:
all_hosts = _get_all_objs(ofilter='H')
for host_system in all_hosts:
host_info = _get_host_info(host_name=host_system)
name = host_info.get('Name', host_system)
host_output[name] = host_info

return jsonify(host_output)


def _get_host_info(host_name=None):
"""
Get all information of host from vcsim
:param vm_name: Name of host
:return: Dictionary containing information about VM,
where KEY represent attributes and VALUE represent attribute's value
"""
cmd = '%s host.info -host=%s 2>&1' % (GOVCPATH, host_name)

host_info = {}
if host_name is None:
return host_info
host_info = parse_govc_info(cmd)

return host_info


def _get_vm_info(vm_name=None):
"""
Get all information of VM from vcsim
:param vm_name: Name of VM
:return: Dictionary containing information about VM,
where KEY represent attributes and VALUE represent attribute's value
"""
cmd = '%s vm.info %s 2>&1' % (GOVCPATH, vm_name)

vm_info = {}
if vm_name is None:
return vm_info
vm_info = parse_govc_info(cmd)

return vm_info


def parse_govc_info(cmd):
"""
Helper function to parse output of govc info commands
:param cmd: command variable to run and parse output for
:return: Dictionary containing information about object
"""
so, se = run_cmd(cmd)
stdout_lines = so.splitlines()
info = {}
for line in stdout_lines:
if ":" in line:
key, value = line.split(":", 1)
key = key.lstrip()
info[key] = value.strip()

return info


def _get_all_objs(ofilter=None):
"""
Get all VM Objects from vcsim
:param ofilter: Specify which object to get
:return: list of Object specified by ofilter
"""
cmd = '%s find ' % GOVCPATH
filter_mapping = dict(VA='a', CCR='c', DC='d', F='f', DVP='g', H='h',
VM='m', N='n', ON='o', RP='p', CR='r', D='s', DVS='w')
if ofilter:
type_filter = filter_mapping.get(ofilter, '')
if type_filter != '':
cmd += '-type %s ' % type_filter

cmd += "2>&1"
so, se = run_cmd(cmd)
stdout_lines = so.splitlines()
return stdout_lines


def run_cmd(cmd):
"""
Helper Function to run commands
:param cmd: Command string to execute
:return: StdOut and StdErr in string format
"""
global GOVCURL

env = {
'GOPATH': GOPATH,
'GOVC_URL': GOVCURL,
'GOVC_INSECURE': '1'
}

p = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
shell=True
)

(so, se) = p.communicate()
return so, se


if __name__ == "__main__":
app.run(debug=False, host='0.0.0.0')
3 changes: 3 additions & 0 deletions make.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker build --no-cache -t ansible:vcenter-simulator .

0 comments on commit 2a5bcdc

Please sign in to comment.