diff --git a/.gitignore b/.gitignore index 24b0a35..a5739d2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,4 @@ config.json #ignore generated iptables p2p/iptable/ #ignore plugins added -plugin/deploy \ No newline at end of file +plugin/deploy/ \ No newline at end of file diff --git a/Docs/Implementation.md b/Docs/Implementation.md index 3a27aaf..619385c 100644 --- a/Docs/Implementation.md +++ b/Docs/Implementation.md @@ -15,4 +15,5 @@ the project is git.sr.ht/~akilan1999/p2p-rendering-computation. ## [Config Module](ConfigImplementation.md) ## [Server Module](ServerImplementation.md) ## [Client Module](ClientImplementation.md) -## [P2P Module](P2PImplementation.md) \ No newline at end of file +## [P2P Module](P2PImplementation.md) +## [Plugin Module](PluginImplementation.md) \ No newline at end of file diff --git a/Docs/Installation.md b/Docs/Installation.md index 3b17f13..a4a6e2d 100644 --- a/Docs/Installation.md +++ b/Docs/Installation.md @@ -88,7 +88,7 @@ GLOBAL OPTIONS:
-# Using the Cli commands +# Using basic commands ### Start as a server Do ensure you have docker installed for this @@ -96,7 +96,7 @@ Do ensure you have docker installed for this p2prc -s ``` -### View server Speciafication +### View server Specification ``` p2prc --specs= ``` @@ -133,3 +133,38 @@ p2prc --ls p2prc --ni ``` +
+ +-------------- + +
+ +# Using Plugins +This feature is still Under Development: +[Read more on the implementation](PluginImplementation.md) + +#### Dependencies +- Ansible: + - Debian/ubuntu: ```sudo apt install ansible``` + - Others: [Installation link](https://ansible-tips-and-tricks.readthedocs.io/en/latest/ansible/install/) + +#### Set ansible host_key_checking to false +- On linux + - ```sudo nano /etc/ansible/ansible.cfg```: Open the following file. If this file is not found then where + ever the file ```ansible.cfg``` is located. + - Add or uncomment ```host_key_checking = False``` + +#### Run Test Cases +- Generate Test Case Ansible file + - ```make testcases``` +- Enter inside plugin directory and run tests. + Note: That docker needs to installed and needs to run without + sudo. Refer the section install Docker. + - ```cd plugin``` + - ```go test .``` + + + + + + diff --git a/Docs/PluginImplementation.md b/Docs/PluginImplementation.md new file mode 100644 index 0000000..1dcf2a9 --- /dev/null +++ b/Docs/PluginImplementation.md @@ -0,0 +1,87 @@ +# Plugin Module Implementation +## Topics +1. [Introduciton](#introduction) +2. [Site.yml](#site-File-Template) +3. [Host](#hosts-file) +4. [Description](#description-file) + +## Introduction + +The plugin module is designed to ensure clients can execute instructions in a declarative manner across different +containers created. This means the user (i.e client) needs to write the instruction only once, and these instructions +can be executed across different nodes in a repetitive manner. + +In the scenario of this project Ansibles will be used as the way the users can create these instructions. + +- [Setup instruction](Installation.md#Using-Plugins) + +The plugin module introduces a new path to the config file known as pluginpath. This path by defaults points to +```${P2PRC}/plugin/deploy```. Any file/folder inside ```plugin/deploy``` is part of the .gitginore. Plugins are +detected by folder names inside the ```plugin/deploy```. +``` +plugin +|___ Deploy + |___ + |___ site.yml + |___ hosts + |___ description.txt + . + . + . + n: n number of plugins possible +``` + +## Site File Template +The site file is also known as the Ansible playbook and is incharge of executing +instructions in a declarative manner. The below example specifies how to make one. +``` +- hosts: all + + tasks: + - name: + + debug: + msg: +``` +Read more about ansible tasks: https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#about-playbooks + +## Hosts file +hosts file is also known as the inventory file. This file consists of all the information required to connect to other +nodes to execute Ansible instructions. In this project this file needs to be set in a certain configuration because the +go code or binary will populate this file automatically with the appropriate information required to connect to local or +remote containers. + +#### Note: Add as exactly specified below +``` +all: + vars: + ansible_python_interpreter: /usr/bin/python3 // Path to your python 3 interpreter +main: + hosts: + host1: + // Note: These values will be automatically overwritten + // by the Go functions + ansible_host: 0.0.0.0 + ansible_port: 39269 + ansible_user: master + ansible_ssh_pass: password + ansible_sudo_pass: password +``` + +## Description file +This is a simple text file used to describe what the module does. +When the client is looking at various commands via the ClI. +The description is displayed along-side the plugin name. + +Ex: When the flag ```--ViewPlugins``` or ```--vp``` is called +``` +{ + "PluginsDetected": [ + { + "FolderName": "", + "PluginDescription": "" + } + ] +} + +``` \ No newline at end of file diff --git a/Docs/README.md b/Docs/README.md index e9bfe07..26b4b20 100644 --- a/Docs/README.md +++ b/Docs/README.md @@ -12,5 +12,6 @@ 3. [Server Module](ServerImplementation.md) 4. [Config Module](ConfigImplementation.md) 5. [Cli Module](CliImplementation.md) + 6. [Plugin Module](PluginImplementation.md) 5. [Problems](Problems.md) diff --git a/Makefile b/Makefile index a87800f..4bd8a68 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,9 @@ build: configfile: ./p2prc --SetDefaultConfig +testcases: + sh plugin/generate_test_case.sh + run: go run main.go diff --git a/deploy/TestAnsible/description.txt b/deploy/TestAnsible/description.txt new file mode 100644 index 0000000..b0a0a8f --- /dev/null +++ b/deploy/TestAnsible/description.txt @@ -0,0 +1 @@ +Test if it's detected \ No newline at end of file diff --git a/deploy/TestAnsible/hosts b/deploy/TestAnsible/hosts new file mode 100644 index 0000000..07e4869 --- /dev/null +++ b/deploy/TestAnsible/hosts @@ -0,0 +1,12 @@ +--- +all: + vars: + ansible_python_interpreter: /usr/bin/python3 +main: + hosts: + host1: + ansible_host: 0.0.0.0 # Replace with your remote IP + ansible_port: 44003 # Replace with your remote SSH port + ansible_user: master # Replace wtih your username + ansible_ssh_pass: password + ansible_sudo_pass: password \ No newline at end of file diff --git a/deploy/TestAnsible/site.yml b/deploy/TestAnsible/site.yml new file mode 100644 index 0000000..3dc78ac --- /dev/null +++ b/deploy/TestAnsible/site.yml @@ -0,0 +1,8 @@ +--- + +- hosts: all + + tasks: + - name: simple-ansibleplaybook + debug: + msg: Your are running 'simple-ansibleplaybook' example \ No newline at end of file diff --git a/go.mod b/go.mod index aa36d60..19b3e8b 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.15 require ( github.com/Microsoft/hcsshim v0.8.15 // indirect github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect + github.com/apenella/go-ansible v1.1.0 github.com/containerd/continuity v0.0.0-20210315143101-93e15499afd5 // indirect github.com/docker/docker v20.10.0-beta1.0.20201113105859-b6bfff2a628f+incompatible github.com/docker/go-connections v0.4.0 @@ -19,7 +20,6 @@ require ( github.com/morikuni/aec v1.0.0 // indirect github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/shirou/gopsutil v3.20.12+incompatible - github.com/showwin/speedtest-go v1.1.1 github.com/spf13/viper v1.4.0 github.com/urfave/cli/v2 v2.3.0 gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 // indirect diff --git a/go.sum b/go.sum index 70b1bcb..d7e8059 100644 --- a/go.sum +++ b/go.sum @@ -64,8 +64,13 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/apenella/go-ansible v1.1.0 h1:wWqaZBvoDxPjvtwXc2fXbDj546uBj/Kv2PL7PW82EfY= +github.com/apenella/go-ansible v1.1.0/go.mod h1:tHqFBSwWXF9k2hkLQWfq6oxMQZHslySQqttkA2siyqE= +github.com/apenella/go-common-utils v0.1.1 h1:dJA2tY22z6mYB5a+EogfiS7NxZsR/Ld3TWnZcS3JPa0= +github.com/apenella/go-common-utils v0.1.1/go.mod h1:E7RUbl9B1vdLkTIapoTE2W6pIgW7dTSJOxL3pf4gV6g= +github.com/apenella/go-common-utils/error v0.0.0-20200917063805-34b0ed3c4ce1 h1:lw/fwF65AaJVxyUTJShtBiZfaiafKde3QkR4im1glzQ= +github.com/apenella/go-common-utils/error v0.0.0-20200917063805-34b0ed3c4ce1/go.mod h1:Hj3S/BcSHKfv9VDMcrY7lsm9hGnb7cd70alSkl/Sv+4= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= @@ -164,6 +169,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= @@ -208,6 +214,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= @@ -366,12 +373,12 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lithammer/shortuuid v3.0.0+incompatible h1:NcD0xWW/MZYXEHa6ITy6kaXN5nwm/V115vj2YXfhS0w= @@ -383,6 +390,7 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -417,6 +425,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -502,8 +512,6 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/shirou/gopsutil v3.20.12+incompatible h1:6VEGkOXP/eP4o2Ilk8cSsX0PhOEfX6leqAnD+urrp9M= github.com/shirou/gopsutil v3.20.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/showwin/speedtest-go v1.1.1 h1:anVwVssgk9MsN/ev8hXBcfMHAfu7o+6fUPvOYTQYkq8= -github.com/showwin/speedtest-go v1.1.1/go.mod h1:Evr4so/j097J4zgdEyYvaBhzyKMgrTNUOwFQcXqUUzc= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -875,8 +883,9 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= diff --git a/plugin/TestAnsible/description.txt b/plugin/TestAnsible/description.txt new file mode 100644 index 0000000..b0a0a8f --- /dev/null +++ b/plugin/TestAnsible/description.txt @@ -0,0 +1 @@ +Test if it's detected \ No newline at end of file diff --git a/plugin/TestAnsible/hosts b/plugin/TestAnsible/hosts new file mode 100644 index 0000000..07e4869 --- /dev/null +++ b/plugin/TestAnsible/hosts @@ -0,0 +1,12 @@ +--- +all: + vars: + ansible_python_interpreter: /usr/bin/python3 +main: + hosts: + host1: + ansible_host: 0.0.0.0 # Replace with your remote IP + ansible_port: 44003 # Replace with your remote SSH port + ansible_user: master # Replace wtih your username + ansible_ssh_pass: password + ansible_sudo_pass: password \ No newline at end of file diff --git a/plugin/TestAnsible/site.yml b/plugin/TestAnsible/site.yml new file mode 100644 index 0000000..3dc78ac --- /dev/null +++ b/plugin/TestAnsible/site.yml @@ -0,0 +1,8 @@ +--- + +- hosts: all + + tasks: + - name: simple-ansibleplaybook + debug: + msg: Your are running 'simple-ansibleplaybook' example \ No newline at end of file diff --git a/plugin/generate_test_case.sh b/plugin/generate_test_case.sh new file mode 100644 index 0000000..cecca14 --- /dev/null +++ b/plugin/generate_test_case.sh @@ -0,0 +1 @@ +cp -r plugin/TestAnsible/ plugin/deploy/ diff --git a/plugin/plugin.go b/plugin/plugin.go index 74d3f5a..b59ea69 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -1,8 +1,18 @@ package plugin import ( + "context" + "errors" + "fmt" "git.sr.ht/~akilan1999/p2p-rendering-computation/config" + "gopkg.in/yaml.v2" "io/ioutil" + "strconv" + + "github.com/apenella/go-ansible/pkg/execute" + "github.com/apenella/go-ansible/pkg/options" + "github.com/apenella/go-ansible/pkg/playbook" + "github.com/apenella/go-ansible/pkg/stdoutcallback/results" ) // Plugins Array of all plugins detected @@ -14,6 +24,35 @@ type Plugins struct { type Plugin struct { FolderName string PluginDescription string + Execute []*ExecuteIP +} + +// ExecuteIP IP Address to execute Ansible instruction +type ExecuteIP struct { + IPAddress string + SSHPortNo string + Success bool +} + +// Host Struct for ansible host +// Generated from https://zhwt.github.io/yaml-to-go/ +type Host struct { + All struct { + Vars struct { + AnsiblePythonInterpreter string `yaml:"ansible_python_interpreter"` + } `yaml:"vars"` + } `yaml:"all"` + Main struct { + Hosts struct { + Host1 struct { + AnsibleHost string `yaml:"ansible_host"` + AnsiblePort int `yaml:"ansible_port"` + AnsibleUser string `yaml:"ansible_user"` + AnsibleSSHPass string `yaml:"ansible_ssh_pass"` + AnsibleSudoPass string `yaml:"ansible_sudo_pass"` + } `yaml:"host1"` + } `yaml:"hosts"` + } `yaml:"main"` } // DetectPlugins Detects all the plugins available @@ -51,4 +90,143 @@ func DetectPlugins()(*Plugins,error){ } return plugins,nil -} \ No newline at end of file +} + +// RunPlugin Executes plugins based on the plugin name provided +func RunPlugin(pluginName string ,IPAddresses []*ExecuteIP) (*Plugin,error) { + plugins, err := DetectPlugins() + if err != nil { + return nil,err + } + + // Variable to store struct information about the plugin + var plugindetected *Plugin + for _,plugin := range plugins.PluginsDetected { + if plugin.FolderName == pluginName { + plugindetected = plugin + plugindetected.Execute = IPAddresses + break + } + } + + if plugindetected == nil { + return nil, errors.New("Plugin not detected") + } + + // Executing the plugin + err = plugindetected.ExecutePlugin() + if err != nil { + return nil,err + } + + return plugindetected,nil +} + +// ExecutePlugin Function to execute plugins that are called +func (p *Plugin) ExecutePlugin() error { + // Get Execute plugin path from config file + config, err:= config.ConfigInit() + if err != nil { + return err + } + + // Run ip address to execute ansible inside + for _,execute := range p.Execute { + // Modify ansible hosts before executing + err = execute.ModifyHost(p,config.PluginPath) + if err != nil { + return err + } + + err = execute.RunAnsible(p,config.PluginPath) + if err != nil { + return err + } + // If ran successfully then change success flag to true + execute.Success = true + } + return nil +} + +// RunAnsible Executes based on credentials on the struct +func (e *ExecuteIP)RunAnsible(p *Plugin,path string) error { + ansiblePlaybookConnectionOptions := &options.AnsibleConnectionOptions{ + User: "master", + } + + ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{ + Inventory: path + "/" + p.FolderName + "/hosts", + ExtraVars: map[string]interface{}{"host_key_checking":"false"}, + } + + ansiblePlaybookPrivilegeEscalationOptions := &options.AnsiblePrivilegeEscalationOptions{ + Become: true, + } + + playbook := &playbook.AnsiblePlaybookCmd{ + Playbooks: []string{path + "/" + p.FolderName + "/site.yml"}, + ConnectionOptions: ansiblePlaybookConnectionOptions, + PrivilegeEscalationOptions: ansiblePlaybookPrivilegeEscalationOptions, + Options: ansiblePlaybookOptions, + Exec: execute.NewDefaultExecute( + execute.WithTransformers( + results.Prepend("success"), + ), + ), + } + + err := playbook.Run(context.TODO()) + if err != nil { + return err + } + + return nil +} + +// ModifyHost adds IP address , port no to the config file +func (e *ExecuteIP)ModifyHost(p *Plugin, path string) error { + host,err := ReadHost(path + "/" + p.FolderName + "/hosts") + if err != nil { + return err + } + // Setting ansible host + host.Main.Hosts.Host1.AnsibleHost = e.IPAddress + // Setting SSH port no + host.Main.Hosts.Host1.AnsiblePort, err = strconv.Atoi(e.SSHPortNo) + if err != nil { + return err + } + // Setting SSH user name + host.Main.Hosts.Host1.AnsibleUser = "master" + // Setting SSH password + host.Main.Hosts.Host1.AnsibleSSHPass = "password" + // Setting SSH sudo password + host.Main.Hosts.Host1.AnsibleSudoPass = "password" + + // write modified information to the hosts yaml file + data,err := yaml.Marshal(host) + if err != nil { + return err + } + err = ioutil.WriteFile(path + "/" + p.FolderName + "/hosts",data,0777) + if err != nil { + return err + } + return nil +} + +// ReadHost Reads host file and adds +func ReadHost(filename string) (*Host, error) { + buf, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + + c := &Host{} + err = yaml.Unmarshal(buf, c) + if err != nil { + return nil, fmt.Errorf("in file %q: %v", filename, err) + } + + return c, nil +} diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go index 6820dab..c69fd38 100644 --- a/plugin/plugin_test.go +++ b/plugin/plugin_test.go @@ -1,6 +1,12 @@ package plugin -import "testing" +import ( + "fmt" + "git.sr.ht/~akilan1999/p2p-rendering-computation/config" + "git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" + "strconv" + "testing" +) // Test if the dummy plugin added is detected func TestDetectPlugins(t *testing.T) { @@ -8,4 +14,79 @@ func TestDetectPlugins(t *testing.T) { if err != nil { t.Fail() } +} + +// Test ensures that the ansible are executed inside local containers +func TestRunPlugin(t *testing.T) { + var testips []*ExecuteIP + var testip1,testip2 ExecuteIP + + // Create docker container and get SSH port + container1 ,err := docker.BuildRunContainer(0,"false","") + if err != nil { + fmt.Println(err) + t.Fail() + } + + //Test IP 1 configuration + testip1.IPAddress = "0.0.0.0" + testip1.SSHPortNo = strconv.Itoa(container1.SSHPort) + + // Create docker container and get SSH port + container2 ,err := docker.BuildRunContainer(0,"false","") + if err != nil { + fmt.Println(err) + t.Fail() + } + //Test IP 2 configuration + testip2.IPAddress = "0.0.0.0" + testip2.SSHPortNo = strconv.Itoa(container2.SSHPort) + + testips = append(testips, &testip1) + testips = append(testips, &testip2) + + _,err = RunPlugin("TestAnsible",testips) + if err != nil { + fmt.Println(err) + t.Fail() + } + + // Removing container1 after Ansible is executed + err = docker.StopAndRemoveContainer(container1.ID) + if err != nil { + fmt.Println(err) + t.Fail() + } + + err = docker.StopAndRemoveContainer(container2.ID) + if err != nil { + fmt.Println(err) + t.Fail() + } +} + +// Test to ensure that the ansible host file is modified to +// the appropriate IP +func TestExecuteIP_ModifyHost(t *testing.T) { + var plugin Plugin + var testip ExecuteIP + + // Get plugin path from config file + Config, err := config.ConfigInit() + if err != nil { + fmt.Println(err) + t.Fail() + } + //Set plugin name + plugin.FolderName = "TestAnsible" + + //Test IP 1 configuration + testip.IPAddress = "0.0.0.0" + testip.SSHPortNo = "41289" + + err = testip.ModifyHost(&plugin,Config.PluginPath) + if err != nil { + fmt.Println(err) + t.Fail() + } } \ No newline at end of file