foreman_kubevirt 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +156 -0
  4. data/Rakefile +44 -0
  5. data/app/assets/javascripts/foreman_kubevirt/kubevirt.js +31 -0
  6. data/app/assets/javascripts/foreman_kubevirt/nic_info.js +9 -0
  7. data/app/controllers/foreman_kubevirt/concerns/api/compute_resources_controller_extensions.rb +26 -0
  8. data/app/models/concerns/fog_extensions/kubevirt/network.rb +11 -0
  9. data/app/models/concerns/fog_extensions/kubevirt/server.rb +55 -0
  10. data/app/models/concerns/fog_extensions/kubevirt/vmnic.rb +12 -0
  11. data/app/models/concerns/fog_extensions/kubevirt/volume.rb +26 -0
  12. data/app/models/foreman_kubevirt/kubevirt.rb +370 -0
  13. data/app/views/api/v2/compute_resources/kubevirt.json.rabl +1 -0
  14. data/app/views/compute_resources/form/_kubevirt.html.erb +14 -0
  15. data/app/views/compute_resources/show/_kubevirt.html.erb +14 -0
  16. data/app/views/compute_resources_vms/form/kubevirt/_base.html.erb +27 -0
  17. data/app/views/compute_resources_vms/form/kubevirt/_network.html.erb +15 -0
  18. data/app/views/compute_resources_vms/form/kubevirt/_volume.html.erb +21 -0
  19. data/app/views/compute_resources_vms/index/_kubevirt.html.erb +29 -0
  20. data/app/views/compute_resources_vms/show/_kubevirt.html.erb +55 -0
  21. data/app/views/images/form/_kubevirt.html.erb +4 -0
  22. data/config/routes.rb +2 -0
  23. data/lib/foreman_kubevirt/engine.rb +75 -0
  24. data/lib/foreman_kubevirt/version.rb +3 -0
  25. data/lib/foreman_kubevirt.rb +4 -0
  26. data/lib/tasks/foreman_kubevirt_tasks.rake +47 -0
  27. data/locale/Makefile +60 -0
  28. data/locale/en/foreman_kubevirt.po +19 -0
  29. data/locale/foreman_kubevirt.pot +19 -0
  30. data/locale/gemspec.rb +2 -0
  31. data/test/factories/compute_resource_factories.rb +10 -0
  32. data/test/factories/host_factories.rb +49 -0
  33. data/test/factories/nic_factories.rb +31 -0
  34. data/test/models/compute_resources/kubevirt_test.rb +69 -0
  35. data/test/test_plugin_helper.rb +7 -0
  36. data/test/unit/foreman_kubevirt_test.rb +45 -0
  37. 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,11 @@
1
+ module FogExtensions
2
+ module Kubevirt
3
+ module Network
4
+ extend ActiveSupport::Concern
5
+
6
+ def id
7
+ name
8
+ end
9
+ end
10
+ end
11
+ 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,12 @@
1
+ module FogExtensions
2
+ module Kubevirt
3
+ module VmNic
4
+ extend ActiveSupport::Concern
5
+ attr_writer :id
6
+
7
+ def id
8
+ name
9
+ end
10
+ end
11
+ end
12
+ 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