foreman_kubevirt 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +619 -0
- data/README.md +156 -0
- data/Rakefile +44 -0
- data/app/assets/javascripts/foreman_kubevirt/kubevirt.js +31 -0
- data/app/assets/javascripts/foreman_kubevirt/nic_info.js +9 -0
- data/app/controllers/foreman_kubevirt/concerns/api/compute_resources_controller_extensions.rb +26 -0
- data/app/models/concerns/fog_extensions/kubevirt/network.rb +11 -0
- data/app/models/concerns/fog_extensions/kubevirt/server.rb +55 -0
- data/app/models/concerns/fog_extensions/kubevirt/vmnic.rb +12 -0
- data/app/models/concerns/fog_extensions/kubevirt/volume.rb +26 -0
- data/app/models/foreman_kubevirt/kubevirt.rb +370 -0
- data/app/views/api/v2/compute_resources/kubevirt.json.rabl +1 -0
- data/app/views/compute_resources/form/_kubevirt.html.erb +14 -0
- data/app/views/compute_resources/show/_kubevirt.html.erb +14 -0
- data/app/views/compute_resources_vms/form/kubevirt/_base.html.erb +27 -0
- data/app/views/compute_resources_vms/form/kubevirt/_network.html.erb +15 -0
- data/app/views/compute_resources_vms/form/kubevirt/_volume.html.erb +21 -0
- data/app/views/compute_resources_vms/index/_kubevirt.html.erb +29 -0
- data/app/views/compute_resources_vms/show/_kubevirt.html.erb +55 -0
- data/app/views/images/form/_kubevirt.html.erb +4 -0
- data/config/routes.rb +2 -0
- data/lib/foreman_kubevirt/engine.rb +75 -0
- data/lib/foreman_kubevirt/version.rb +3 -0
- data/lib/foreman_kubevirt.rb +4 -0
- data/lib/tasks/foreman_kubevirt_tasks.rake +47 -0
- data/locale/Makefile +60 -0
- data/locale/en/foreman_kubevirt.po +19 -0
- data/locale/foreman_kubevirt.pot +19 -0
- data/locale/gemspec.rb +2 -0
- data/test/factories/compute_resource_factories.rb +10 -0
- data/test/factories/host_factories.rb +49 -0
- data/test/factories/nic_factories.rb +31 -0
- data/test/models/compute_resources/kubevirt_test.rb +69 -0
- data/test/test_plugin_helper.rb +7 -0
- data/test/unit/foreman_kubevirt_test.rb +45 -0
- metadata +127 -0
data/README.md
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
|
2
|
+
# Foreman Kubevirt Plugin
|
3
|
+
|
4
|
+
The ```foreman_kubevirt ``` plugin enables managing of [KubeVirt](https://kubevirt.io) as a Compute Resource in Foreman.
|
5
|
+
|
6
|
+
* Website: [TheForeman.org](http://theforeman.org)
|
7
|
+
* Wiki: [Foreman wiki](http://projects.theforeman.org/projects/foreman/wiki/About)
|
8
|
+
* Community and support: #theforeman for general support, #theforeman-dev for development chat in [Freenode](irc.freenode.net)
|
9
|
+
* Mailing lists:
|
10
|
+
* [foreman-users](https://groups.google.com/forum/?fromgroups#!forum/foreman-users)
|
11
|
+
* [foreman-dev](https://groups.google.com/forum/?fromgroups#!forum/foreman-dev)
|
12
|
+
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Please see the Foreman manual for appropriate instructions:
|
17
|
+
|
18
|
+
* [Foreman: How to Install a Plugin](https://theforeman.org/plugins/#2.Installation)
|
19
|
+
|
20
|
+
|
21
|
+
### Building the plugin from source
|
22
|
+
# git clone https://github.com/masayag/foreman_kubevirt.git
|
23
|
+
# cd foreman_kubevirt
|
24
|
+
# gem build foreman_kubevirt.gemspec # the output will be gem named foreman_kubevirt-x.y.z.gem, where x.y.z should be replaced with the actual version
|
25
|
+
|
26
|
+
### Installing the plugin
|
27
|
+
|
28
|
+
#### Installing on Red Hat, CentOS, Fedora, Scientific Linux (rpm)
|
29
|
+
# sudo -i
|
30
|
+
# scl enable tfm bash
|
31
|
+
# yum -y install gcc-c++ redhat-rpm-config gcc rubygems rh-ruby25-ruby-devel-2.5 # or a matching version according to the installed ruby
|
32
|
+
# gem install foreman_kubevirt-x.y.z.gem # replace x.y.z with the actual version
|
33
|
+
|
34
|
+
### Bundle (gem)
|
35
|
+
|
36
|
+
Add the following to bundler.d/Gemfile.local.rb in your Foreman installation directory (/usr/share/foreman by default)
|
37
|
+
|
38
|
+
$ gem 'foreman_kubevirt'
|
39
|
+
|
40
|
+
Or simply:
|
41
|
+
|
42
|
+
$ echo "gem 'foreman_kubevirt'" > /usr/share/foreman/bundler.d/Gemfile.local.rb
|
43
|
+
|
44
|
+
Then run `bundle install` from the same directory
|
45
|
+
|
46
|
+
#### Developing the plugin
|
47
|
+
Add the following to bundler.d/Gemfile.local.rb in your Foreman development directory
|
48
|
+
|
49
|
+
$ gem 'foreman_kubevirt', :path => 'path to foreman_kubevirt directory'
|
50
|
+
|
51
|
+
Then run `bundle install` from the same directory
|
52
|
+
|
53
|
+
-------------------
|
54
|
+
To verify that the installation was successful, go to Foreman, top bar **Administer > About** and check *foreman_kubevirt* shows up in the **System Status** menu under the **Plugins** tab.
|
55
|
+
|
56
|
+
## Compatibility
|
57
|
+
|
58
|
+
| Foreman Version | Plugin Version |
|
59
|
+
| --------------- | --------------:|
|
60
|
+
| >= 1.21.x | ~> 0.1.x |
|
61
|
+
|
62
|
+
## Usage
|
63
|
+
Go to **Infrastructure > Compute Resources** and click on **New Compute Resource**.
|
64
|
+
Choose the **KubeVirt provider**, and fill in all the fields.
|
65
|
+
|
66
|
+
Here is a short description of some of the fields:
|
67
|
+
* *Namespace* - the virtual cluster on kubernetes to which the user has permissions as cluster-admin.
|
68
|
+
* *Token* - a bearer token authentication for HTTP(s) calls.
|
69
|
+
* *X509 Certification Authorities* - enables client certificate authentication for API server calls.
|
70
|
+
|
71
|
+
### How to get values of *Token* and *X509 CA* ?
|
72
|
+
|
73
|
+
#### Kubernetes
|
74
|
+
##### *Token*:
|
75
|
+
|
76
|
+
Either list the secrets and pick the one that contains the relevant token, or select a service account:
|
77
|
+
|
78
|
+
List of secrets that contain the tokens and set secret name instead of *YOUR_SECRET*:
|
79
|
+
```
|
80
|
+
# kubectl get secrets
|
81
|
+
# kubectl get secrets YOUR_SECRET -o jsonpath='{.data.token}' | base64 -d | xargs
|
82
|
+
```
|
83
|
+
|
84
|
+
Or obtain token for a service account named 'foreman-account':
|
85
|
+
```
|
86
|
+
# KUBE_SECRET=`kubectl get sa foreman-account -o jsonpath='{.secrets[0].name}'`
|
87
|
+
# kubectl get secrets $KUBE_SECRET -o jsonpath='{.data.token}' | base64 -d | xargs
|
88
|
+
```
|
89
|
+
|
90
|
+
##### *X509 CA*:
|
91
|
+
|
92
|
+
Taken from kubernetes admin config file:
|
93
|
+
```
|
94
|
+
# cat /etc/kubernetes/admin.conf | grep certificate-authority-data: | cut -d: -f2 | tr -d " " | base64 -d
|
95
|
+
```
|
96
|
+
|
97
|
+
Or by retrieving from the secret, via the service account (in this example assuming its name is *foreman-account*):
|
98
|
+
```
|
99
|
+
# KUBE_SECRET=`kubectl get sa foreman-account -o jsonpath='{.secrets[0].name}'`
|
100
|
+
# kubectl get secret $KUBE_SECRET -o jsonpath='{.data.ca\.crt}' | base64 -d
|
101
|
+
```
|
102
|
+
|
103
|
+
#### OpenShift
|
104
|
+
##### *Token*:
|
105
|
+
|
106
|
+
Create a privileged account named *my-account*:
|
107
|
+
```
|
108
|
+
# oc create -f https://raw.githubusercontent.com/ManageIQ/manageiq-providers-kubevirt/master/manifests/account-openshift.yml
|
109
|
+
```
|
110
|
+
Use *oc* tool for reading the token of the *my-account* service account under *default* namespace:
|
111
|
+
`# oc sa get-token my-account -n default`
|
112
|
+
|
113
|
+
##### *X509 CA*:
|
114
|
+
|
115
|
+
Taken from OpenShift admin config file:
|
116
|
+
```
|
117
|
+
# cat /etc/origin/master/openshift-master.kubeconfig | grep certificate-authority-data: | cut -d: -f2 | tr -d " " | base64 -d
|
118
|
+
```
|
119
|
+
|
120
|
+
Or by retrieving from the secret of service account *my-account* under the *default* namespace:
|
121
|
+
```
|
122
|
+
# KUBE_SECRET=`oc get sa my-account -n default -o jsonpath='{.secrets[0].name}'`
|
123
|
+
# kubectl get secret $KUBE_SECRET -n default -o jsonpath='{.data.ca\.crt}' | base64 -d
|
124
|
+
```
|
125
|
+
|
126
|
+
## Tests
|
127
|
+
|
128
|
+
Tests should be invoked from the *foreman* directory by:
|
129
|
+
```
|
130
|
+
# bundle exec rake test:foreman_kubevirt
|
131
|
+
```
|
132
|
+
|
133
|
+
## TODO
|
134
|
+
|
135
|
+
* Implement VM Console
|
136
|
+
|
137
|
+
## Contributing
|
138
|
+
|
139
|
+
Fork and send a Pull Request. Thanks!
|
140
|
+
|
141
|
+
## Copyright
|
142
|
+
|
143
|
+
Copyright (c) 2018 Red Hat, Inc.
|
144
|
+
|
145
|
+
This program is free software: you can redistribute it and/or modify
|
146
|
+
it under the terms of the GNU General Public License as published by
|
147
|
+
the Free Software Foundation, either version 3 of the License, or
|
148
|
+
(at your option) any later version.
|
149
|
+
|
150
|
+
This program is distributed in the hope that it will be useful,
|
151
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
152
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
153
|
+
GNU General Public License for more details.
|
154
|
+
|
155
|
+
You should have received a copy of the GNU General Public License
|
156
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
data/Rakefile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'ForemanKubevirt'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
20
|
+
end
|
21
|
+
|
22
|
+
APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
|
23
|
+
|
24
|
+
Bundler::GemHelper.install_tasks
|
25
|
+
|
26
|
+
require 'rake/testtask'
|
27
|
+
|
28
|
+
Rake::TestTask.new(:test) do |t|
|
29
|
+
t.libs << 'lib'
|
30
|
+
t.libs << 'test'
|
31
|
+
t.pattern = 'test/**/*_test.rb'
|
32
|
+
t.verbose = false
|
33
|
+
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
require 'rubocop/rake_task'
|
37
|
+
RuboCop::RakeTask.new
|
38
|
+
rescue StandardError => _
|
39
|
+
puts 'Rubocop not loaded.'
|
40
|
+
end
|
41
|
+
|
42
|
+
task :default do
|
43
|
+
Rake::Task['rubocop'].execute
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
bootableRadio = function (item) {
|
2
|
+
const disabled = $('[id$=_bootable_true]:disabled:checked:visible');
|
3
|
+
|
4
|
+
$('[id$=_bootable_true]').prop('checked', false);
|
5
|
+
if (disabled.length > 0) {
|
6
|
+
disabled.prop('checked', true);
|
7
|
+
} else {
|
8
|
+
$(item).prop('checked', true);
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
cniProviderSelected = function (item) {
|
13
|
+
const selected = $(item).val().toLowerCase();
|
14
|
+
podSelected = selected == "pod";
|
15
|
+
changeNetworkElementVisibility(!podSelected);
|
16
|
+
}
|
17
|
+
|
18
|
+
function changeNetworkElementVisibility(toggle) {
|
19
|
+
if (toggle) {
|
20
|
+
$('.kubevirt-network').parents('.form-group').css('display', '');
|
21
|
+
} else {
|
22
|
+
$('.kubevirt-network').parents('.form-group').css('display', 'none');
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
function changeNetworkElementVisibilityOnLoad() {
|
27
|
+
selected = $('select.kubevirt-cni-provider').val().toLowerCase();
|
28
|
+
changeNetworkElementVisibility(selected != "pod");
|
29
|
+
}
|
30
|
+
|
31
|
+
$(document).ready(changeNetworkElementVisibilityOnLoad);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
providerSpecificNICInfo = function(form) {
|
2
|
+
cni_provider = form.find('select.kubevirt-cni-provider :selected').text();
|
3
|
+
if (cni_provider === 'pod') {
|
4
|
+
network = '';
|
5
|
+
} else {
|
6
|
+
network = form.find('select.kubevirt-network').val();
|
7
|
+
}
|
8
|
+
return network + ' @ ' + cni_provider;
|
9
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ForemanKubevirt
|
2
|
+
module Concerns
|
3
|
+
module Api
|
4
|
+
module ComputeResourcesControllerExtensions
|
5
|
+
module ApiPieExtensions
|
6
|
+
extend ::Apipie::DSL::Concern
|
7
|
+
update_api(:create, :update) do
|
8
|
+
param :compute_resource, Hash do
|
9
|
+
param :token, String, :desc => N_("Token for KubeVirt only")
|
10
|
+
param :hostname, String, :desc => N_("Host name for KubeVirt only")
|
11
|
+
param :namespace, String, :desc => N_("Namespace for KubeVirt only")
|
12
|
+
param :ca_crt, String, :desc => N_("CA crt for KubeVirt only")
|
13
|
+
param :api_port, String, :desc => N_("API port for KubeVirt only")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
|
21
|
+
included do
|
22
|
+
include ApiPieExtensions
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module FogExtensions
|
2
|
+
module Kubevirt
|
3
|
+
module Server
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
include ActionView::Helpers::NumberHelper
|
7
|
+
|
8
|
+
attr_accessor :image_id
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
name
|
12
|
+
end
|
13
|
+
|
14
|
+
def state
|
15
|
+
status
|
16
|
+
end
|
17
|
+
|
18
|
+
def interfaces_attributes=(attrs)
|
19
|
+
end
|
20
|
+
|
21
|
+
def volumes_attributes=(attrs)
|
22
|
+
end
|
23
|
+
|
24
|
+
def uuid
|
25
|
+
name
|
26
|
+
end
|
27
|
+
|
28
|
+
def mac
|
29
|
+
interfaces.map(&:mac_address).compact.min
|
30
|
+
end
|
31
|
+
|
32
|
+
# TODO: Update once new API for reporting IP_ADRESSSES is set
|
33
|
+
def ip_addresses
|
34
|
+
[interfaces&.first&.ip_address]
|
35
|
+
end
|
36
|
+
|
37
|
+
def poweroff
|
38
|
+
stop
|
39
|
+
end
|
40
|
+
|
41
|
+
def reset
|
42
|
+
stop
|
43
|
+
start
|
44
|
+
end
|
45
|
+
|
46
|
+
def vm_description
|
47
|
+
_("%{cpu_cores} Cores and %{memory} memory") % { :cpu_cores => cpu_cores, :memory => number_to_human_size(memory.to_i) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def select_nic(fog_nics, _nic)
|
51
|
+
fog_nics.select { |iface| !iface.mac.nil? }[0]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module FogExtensions
|
2
|
+
module Kubevirt
|
3
|
+
module Volume
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
attr_writer :storage_class
|
7
|
+
attr_writer :capacity
|
8
|
+
|
9
|
+
def capacity
|
10
|
+
pvc.requests[:storage] unless pvc.nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
def storage_class
|
14
|
+
pvc&.storage_class
|
15
|
+
end
|
16
|
+
|
17
|
+
def bootable
|
18
|
+
boot_order == 1
|
19
|
+
end
|
20
|
+
|
21
|
+
def id
|
22
|
+
name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|