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.
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