teuton 2.1.1 → 2.1.2
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 +4 -4
- data/README.md +12 -21
- data/docs/Challenge-Server-Project.md +50 -0
- data/docs/changelog/servidor-de-retos.md +53 -0
- data/docs/changelog/todo.md +46 -0
- data/docs/changelog/v2.0.md +17 -0
- data/docs/changelog/v2.1.md +139 -0
- data/docs/commands/commands.md +10 -0
- data/docs/commands/create_skeleton.md +31 -0
- data/docs/commands/help.md +13 -0
- data/docs/commands/revise_test.md +46 -0
- data/docs/commands/run_test_unit.md +78 -0
- data/docs/commands/show_version.md +9 -0
- data/docs/developers/01-telnet.md +121 -0
- data/docs/developers/02-ssh.md +93 -0
- data/docs/developers/03-encoding.md +153 -0
- data/docs/developers/comparative.md +17 -0
- data/docs/dsl/_Sidebar.md +30 -0
- data/docs/dsl/definition/expect.md +56 -0
- data/docs/dsl/definition/goto.md +112 -0
- data/docs/dsl/definition/group.md +16 -0
- data/docs/dsl/definition/result.md +76 -0
- data/docs/dsl/definition/run.md +23 -0
- data/docs/dsl/definition/target.md +35 -0
- data/docs/dsl/execution/export.md +39 -0
- data/docs/dsl/execution/play.md +16 -0
- data/docs/dsl/execution/send.md +54 -0
- data/docs/dsl/execution/show.md +21 -0
- data/docs/dsl/keywords.md +53 -0
- data/docs/dsl/setting/get.md +36 -0
- data/docs/dsl/setting/set.md +18 -0
- data/docs/install/install.md +32 -0
- data/docs/install/manual_install.md +25 -0
- data/docs/install/modes_of_use.md +38 -0
- data/docs/install/scripts_install.md +76 -0
- data/docs/install/tested_od.md +25 -0
- data/docs/install/vagrant_install.md +15 -0
- data/docs/learn/example-01-target.md +117 -0
- data/docs/learn/example-02-configfile.md +168 -0
- data/docs/learn/example-03-remote-hosts.md +90 -0
- data/docs/learn/example-04-use.md +74 -0
- data/docs/learn/example-05-debug.md +104 -0
- data/docs/learn/example-11-first-test.md +96 -0
- data/docs/learn/learning.md +34 -0
- data/docs/learn/quick-demo.md +168 -0
- data/docs/learn/videos.md +13 -0
- data/lib/teuton/application.rb +1 -1
- data/lib/teuton/command/readme.rb +3 -0
- data/lib/teuton/command/test.rb +3 -0
- data/lib/teuton/command.rb +2 -2
- metadata +91 -5
- data/docs/logo.png +0 -0
@@ -0,0 +1,121 @@
|
|
1
|
+
|
2
|
+
# 01 - Conexión Telnet
|
3
|
+
|
4
|
+
> ¡Vale, lo sé! No debería estar usando Telnet ni Windows 2012.
|
5
|
+
> Pero ahora mismo es un reto personal y quiero descubrir qué está pasando.
|
6
|
+
|
7
|
+
---
|
8
|
+
|
9
|
+
# Herramientas que uso
|
10
|
+
|
11
|
+
He creado el siguiente [programa ruby](../../tests/manual/telnet.rb) para abrir
|
12
|
+
una conexión telnet a una máquina remota, ejecutar un comando y mostrar
|
13
|
+
el resutado en pantalla.
|
14
|
+
|
15
|
+
---
|
16
|
+
|
17
|
+
# Gema net/Telnet
|
18
|
+
|
19
|
+
Estoy usando la gema `net/telnet`, la cual en su [documentación](https://www.rubydoc.info/gems/net-telnet/0.2.0)
|
20
|
+
pone lo siguiente:
|
21
|
+
|
22
|
+
```
|
23
|
+
# Usage
|
24
|
+
# Log in and send a command, echoing all output to stdout
|
25
|
+
|
26
|
+
localhost = Net::Telnet::new("Host" => "localhost",
|
27
|
+
"Timeout" => 10,
|
28
|
+
"Prompt" => /[$%#>] \z/n)
|
29
|
+
localhost.login("username", "password") { |c| print c }
|
30
|
+
localhost.cmd("command") { |c| print c }
|
31
|
+
localhost.close
|
32
|
+
```
|
33
|
+
|
34
|
+
> Repositorio GitHub de la gema: https://github.com/ruby/net-telnet/
|
35
|
+
|
36
|
+
---
|
37
|
+
|
38
|
+
# Comprobaciones
|
39
|
+
|
40
|
+
## MV GNU/Linux Debian 9 con servidor telnet
|
41
|
+
* Manualmente -> OK
|
42
|
+
* Usando el programa -> OK
|
43
|
+
|
44
|
+
```
|
45
|
+
Testing : {:ip=>"192.168.1.106", :username=>"root", :password=>"profesor", :cmd=>"whoami"}
|
46
|
+
Output : ["whoami", "root", "root@vargas42d:~# "]
|
47
|
+
|
48
|
+
Testing : {:ip=>"192.168.1.106", :username=>"profesor", :password=>"profesor", :cmd=>"whoami"}
|
49
|
+
Output : ["whoami", "profesor", "profesor@vargas42d:~$ "]
|
50
|
+
```
|
51
|
+
|
52
|
+
## MV Windows 2008 server con servidor Telnet
|
53
|
+
* Manualmente -> OK
|
54
|
+
* Usando el programa -> OK
|
55
|
+
|
56
|
+
```
|
57
|
+
Testing : {:ip=>"192.168.1.115", :username=>"Administrador", :password=>"profesorFP2018", :cmd=>"whoami"}
|
58
|
+
Output : ["whoami", "vargas42s08\\administrador", "", "C:\\Users\\Administrador>"]
|
59
|
+
|
60
|
+
Testing : {:ip=>"192.168.1.115", :username=>"profesor", :password=>"sayonaraBABY2018", :cmd=>"whoami"}
|
61
|
+
Output : ["whoami", "vargas42s08\\profesor", "", "C:\\Users\\profesor>"]
|
62
|
+
```
|
63
|
+
|
64
|
+
## MV Windows 2012 server con servidor Telnet
|
65
|
+
* Manualmente -> OK
|
66
|
+
|
67
|
+
```
|
68
|
+
david@camaleon:~/proy/tools/sysadmin-game> telnet 192.168.1.114
|
69
|
+
Trying 192.168.1.114...
|
70
|
+
Connected to 192.168.1.114.
|
71
|
+
Escape character is '^]'.
|
72
|
+
Welcome to Microsoft Telnet Service
|
73
|
+
|
74
|
+
login: administrador
|
75
|
+
password:
|
76
|
+
|
77
|
+
*===============================================================
|
78
|
+
Microsoft Telnet Server.
|
79
|
+
*===============================================================
|
80
|
+
C:\Users\Administrador>whoami
|
81
|
+
vargas42s12\administrador
|
82
|
+
|
83
|
+
C:\Users\Administrador>
|
84
|
+
C:\Users\Administrador>exitConnection closed by foreign host.
|
85
|
+
david@camaleon:~/proy/tools/sysadmin-game> telnet 192.168.1.114
|
86
|
+
Trying 192.168.1.114...
|
87
|
+
Connected to 192.168.1.114.
|
88
|
+
Escape character is '^]'.
|
89
|
+
Welcome to Microsoft Telnet Service
|
90
|
+
|
91
|
+
login: profesor
|
92
|
+
password:
|
93
|
+
|
94
|
+
*===============================================================
|
95
|
+
Microsoft Telnet Server.
|
96
|
+
*===============================================================
|
97
|
+
C:\>whoami
|
98
|
+
vargas42s12\profesor
|
99
|
+
|
100
|
+
C:\>exiConnection closed by foreign host.
|
101
|
+
```
|
102
|
+
* Usando el programa -> OK
|
103
|
+
|
104
|
+
```
|
105
|
+
david@camaleon:~/proy/tools/sysadmin-game> ./tests/manual/telnet.rb
|
106
|
+
|
107
|
+
Testing : {:ip=>"192.168.1.114", :username=>"Administrador", :password=>"profesorFP2018", :cmd=>"whoami"}
|
108
|
+
Output : ["whoami", "vargas42s12\\administrador", "", "C:\\Users\\Administrador>"]
|
109
|
+
|
110
|
+
Testing : {:ip=>"192.168.1.114", :username=>"profesor", :password=>"sayonaraBABY2018", :cmd=>"whoami"}
|
111
|
+
Output : ["whoami", "vargas42s12\\profesor", "", "C:\\Users\\profesor>"]
|
112
|
+
|
113
|
+
```
|
114
|
+
---
|
115
|
+
|
116
|
+
# Problema
|
117
|
+
|
118
|
+
La aplicación falla cuando lo intento con Windows 2012 server.
|
119
|
+
|
120
|
+
Creo que la estoy usando correctamente, pero hay algo que funciona diferente
|
121
|
+
en Windows 2012 y no consigo identificar el qué.
|
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
# 02 - Conexión SSH a PowerShell
|
3
|
+
|
4
|
+
---
|
5
|
+
|
6
|
+
# Herramientas que uso
|
7
|
+
|
8
|
+
He creado el programa de ruby [ssh.rb](../../tests/manual/ssh.rb) para abrir
|
9
|
+
una conexión SSH a una máquina remota, ejecutar un comando y mostrar
|
10
|
+
el resutado en pantalla.
|
11
|
+
|
12
|
+
---
|
13
|
+
|
14
|
+
# Gema net/ssh
|
15
|
+
|
16
|
+
Estoy usando la gema `net/ssh`, la cual en su [documentación](hhttp://net-ssh.github.io/net-ssh/)
|
17
|
+
pone lo siguiente:
|
18
|
+
|
19
|
+
```
|
20
|
+
require 'net/ssh'
|
21
|
+
|
22
|
+
Net::SSH.start('host', 'user', password: "password") do |ssh|
|
23
|
+
# capture all stderr and stdout output from a remote process
|
24
|
+
output = ssh.exec!("hostname")
|
25
|
+
puts output
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
> Repositorio GitHub de la gema: https://github.com/net-ssh/net-ssh
|
30
|
+
|
31
|
+
---
|
32
|
+
|
33
|
+
# Comprobaciones
|
34
|
+
|
35
|
+
## Debian 9 con servidor SSH
|
36
|
+
|
37
|
+
Todos los comandos que se ejecutan vía SSH por esta herramienta funcionan correctamente.
|
38
|
+
|
39
|
+
## MV Windows 2012 server con servidor SSH
|
40
|
+
|
41
|
+
* Manualmente -> OK (usando ssh con sshpass)
|
42
|
+
|
43
|
+
```
|
44
|
+
david@camaleon:~/proy/tools/sysadmin-game> sshpass -p profesorFP2018 ssh administrador@192.168.1.114 'get-windowsfeature -name rds-rd-server'
|
45
|
+
|
46
|
+
Display Name Name
|
47
|
+
------------ ----
|
48
|
+
[ ] Host de sesi�n de Escritorio remoto RDS-RD-Server
|
49
|
+
|
50
|
+
```
|
51
|
+
|
52
|
+
* Manualmente -> OK (usando ssh)
|
53
|
+
|
54
|
+
```
|
55
|
+
david@camaleon:~/proy/tools/sysadmin-game> ssh administrador@192.168.1.114 'get-windowsfeature -name rds-rd-server'
|
56
|
+
administrador@192.168.1.114's password:
|
57
|
+
|
58
|
+
Display Name Name
|
59
|
+
------------ ----
|
60
|
+
[ ] Host de sesi�n de Escritorio remoto RDS-RD-Server
|
61
|
+
```
|
62
|
+
|
63
|
+
* Usando el programa -> OK (Comando whoami)
|
64
|
+
|
65
|
+
```
|
66
|
+
david@camaleon:~/proy/tools/sysadmin-game> ./tests/manual/ssh.rb
|
67
|
+
|
68
|
+
Testing : {:ip=>"192.168.1.114", :username=>"Administrador", :password=>"profesorFP2018", :cmd=>"whoami"}
|
69
|
+
Output : ["vargas42s12\\administrador\r"]
|
70
|
+
|
71
|
+
```
|
72
|
+
|
73
|
+
* Usando el programa -> ERROR!!!! (Comando get-windowsfeature) La salida está vacía.
|
74
|
+
|
75
|
+
```
|
76
|
+
david@camaleon:~/proy/tools/sysadmin-game> ./tests/manual/ssh.rb
|
77
|
+
|
78
|
+
Testing : {:ip=>"192.168.1.114", :username=>"Administrador", :password=>"profesorFP2018", :cmd=>"get-windowsfeature -name rds-rd-server"}
|
79
|
+
[ArgumentError] SSH on <Administrador@192.168.1.114> exec: get-windowsfeature -name rds-rd-server
|
80
|
+
Output : []
|
81
|
+
|
82
|
+
```
|
83
|
+
|
84
|
+
---
|
85
|
+
|
86
|
+
# Problema
|
87
|
+
|
88
|
+
La librería `net/ssh` parece que no recoge el resultado cuando se ejecuta el comando de PowerShell `get-windowsfeature -name rds-server` en Windows 2012 server.
|
89
|
+
|
90
|
+
Pero si lo hago de forma manual SI funciona.
|
91
|
+
|
92
|
+
¿Puede ser que algunos comandos de PowerShell no se comportan como lo hacen todos los comandos y generan
|
93
|
+
una salida que no puede capturar bien la librería?
|
@@ -0,0 +1,153 @@
|
|
1
|
+
|
2
|
+
# 03 - Encoding (Charset)
|
3
|
+
|
4
|
+
---
|
5
|
+
|
6
|
+
# 1. Introducción
|
7
|
+
|
8
|
+
Supongamos que tenemos la siguiente instrucción de SysadminGame:
|
9
|
+
|
10
|
+
`goto :host1, :exec => "whoami"`
|
11
|
+
|
12
|
+
Con esta instrucción se abre una conexión remota al equipo `:host1` y se ejecuta el comando `whoami`.
|
13
|
+
Luego el texto obtenido se guarda en una variable String que luego se convierte en un Array con cada
|
14
|
+
una de las líneas del texto de salida del comando. Ejemplo:
|
15
|
+
|
16
|
+
```
|
17
|
+
# Si text es el texto devuelto por el comando entonces output es un Array de Strings
|
18
|
+
output = text.split("\n")
|
19
|
+
```
|
20
|
+
|
21
|
+
La variable String de ruby trabaja con codificación 'UTF-8'. En el momento de ejecutar
|
22
|
+
`text.split("\n")` se espera que text esté codificado 'UTF-8'. En caso contrario tenemos un error.
|
23
|
+
|
24
|
+
---
|
25
|
+
|
26
|
+
# 2. Problema
|
27
|
+
|
28
|
+
Cuando ejecutamos:
|
29
|
+
|
30
|
+
`goto :win1, :exec => "get-windowsfeature -name rds-rd-server"`
|
31
|
+
|
32
|
+
siendo `:win1` un Windows 2012 server tenemos un error.
|
33
|
+
|
34
|
+
Si ejecutamos el comando manualmente obtenemos la siguiente salida:
|
35
|
+
|
36
|
+
```
|
37
|
+
david@camaleon:~/proy/tools/sysadmin-game> ssh administrador@192.168.1.114 'get-windowsfeature -name rds-rd-server'
|
38
|
+
administrador@192.168.1.114's password:
|
39
|
+
|
40
|
+
Display Name Name
|
41
|
+
------------ ----
|
42
|
+
[ ] Host de sesi�n de Escritorio remoto RDS-RD-Server
|
43
|
+
```
|
44
|
+
|
45
|
+
Como podemos comprobar, este comando genera una salida con tildes codificada en ISO-8859-1. Y ahí están el problema.
|
46
|
+
|
47
|
+
---
|
48
|
+
|
49
|
+
# 3. Solución
|
50
|
+
|
51
|
+
La solución que se propone es poner la siguiente instrucción en esos casos:
|
52
|
+
|
53
|
+
`goto :win1, :exec => "get-windowsfeature -name rds-rd-server", :encoding => "ISO-8859-1"`
|
54
|
+
|
55
|
+
Esto es, para las salidas de los comandos que requieran conversión de tipo, se debe
|
56
|
+
especificar con `:encoding` el tipo de codificación que se recibirá. Luego ésta se convierte
|
57
|
+
internamente a 'UTF-8' y a partir de ahí todo funcionará correctamente.
|
58
|
+
|
59
|
+
---
|
60
|
+
|
61
|
+
# 4. Comentarios
|
62
|
+
|
63
|
+
Entiendo que es una molestia indicar la codificación en algunos comandos/servidores especiales. Pero por ahora no se puede asumir que siempre se recibirán los caracteres con la misma codificación.
|
64
|
+
|
65
|
+
---
|
66
|
+
|
67
|
+
# 5. ¿Cómo averiguar el encoding (charset) de forma automática?
|
68
|
+
|
69
|
+
Hablando con _Albérica_, el problema anterior, ella comenta la idea de buscar la forma de encontrar el `encoding` de forma automática. Me pongo a pensar y escribo lo siguiente:
|
70
|
+
|
71
|
+
> **Leer el encoding de los ficheros y cómo cambiarlo**
|
72
|
+
>
|
73
|
+
> En ciertas ocasiones es necesario [cambiar el encoding de una archivo](http://lacapa8v2.blogspot.com/2012/07/como-saber-y-cambiar-el-charset.html#.XDvPZqHLfQo), Con el comando file y la opción mime se puede saber el charset de un archivo.
|
74
|
+
> Veamos un ejemplo:
|
75
|
+
>
|
76
|
+
> $ file --mime test.html
|
77
|
+
> test.html: text/plain; charset=iso-8859-1
|
78
|
+
>
|
79
|
+
> Para cambiar el charset, usaremos el comando iconv:
|
80
|
+
>
|
81
|
+
> $ iconv --from-code=iso-8859-1 --to-code=utf-8 test.html > test_new.html
|
82
|
+
|
83
|
+
**¿Qué pasa con la salida de los comandos de un OpenSUSE en español?**
|
84
|
+
|
85
|
+
Me aseguro que tengo el sistema operativo en español:
|
86
|
+
```
|
87
|
+
> locale
|
88
|
+
|
89
|
+
LANG=es_ES.utf8
|
90
|
+
LC_CTYPE=es_ES.utf8
|
91
|
+
LC_NUMERIC="es_ES.utf8"
|
92
|
+
LC_TIME="es_ES.utf8"
|
93
|
+
LC_COLLATE="es_ES.utf8"
|
94
|
+
LC_MONETARY="es_ES.utf8"
|
95
|
+
LC_MESSAGES="es_ES.utf8"
|
96
|
+
LC_PAPER="es_ES.utf8"
|
97
|
+
LC_NAME="es_ES.utf8"
|
98
|
+
LC_ADDRESS="es_ES.utf8"
|
99
|
+
LC_TELEPHONE="es_ES.utf8"
|
100
|
+
LC_MEASUREMENT="es_ES.utf8"
|
101
|
+
LC_IDENTIFICATION="es_ES.utf8"
|
102
|
+
LC_ALL=
|
103
|
+
```
|
104
|
+
Ahora vamos a comprobar el charset de la salida de algún comando:
|
105
|
+
```
|
106
|
+
$ pwd > /tmp/pwd.tmp
|
107
|
+
$ file --mime /tmp/pwd.tmp
|
108
|
+
pwd.tmp: text/plain; charset=us-ascii
|
109
|
+
```
|
110
|
+
|
111
|
+
> Interesante... La salida de los comandos tienen charset `us-ascii`,
|
112
|
+
a pesar de que mi sistema está en español.
|
113
|
+
>
|
114
|
+
> Me pregunto ¿funcionarán todos los comandos de la misma forma? Lo lógico es pensar que sí. En dicho caso podremos asumir que todos los comandos de GNU/Linux generan la salida con enconding us-ascii.
|
115
|
+
|
116
|
+
**¿Qué pasa con los comandos de W2012 en español?**
|
117
|
+
|
118
|
+
Averiguar el encoding que está usando por el terminal:
|
119
|
+
```
|
120
|
+
$ ssh administrador@192.168.1.114 'chcp' > chcp.tmp
|
121
|
+
administrador@192.168.1.114's password:
|
122
|
+
|
123
|
+
$ more /tmp/chcp.tmp
|
124
|
+
P�gina de c�digos activa: 850
|
125
|
+
|
126
|
+
$ file --mime /tmp/chcp.tmp
|
127
|
+
/tmp/chcp.tmp: text/plain; charset=iso-8859-1
|
128
|
+
```
|
129
|
+
|
130
|
+
O sea, que según el comando tiene charser `850` y luego el resultado del comando está en `iso-8859-1`. Pero no queda claro porque hay comandos que generan la salida en una codificación y otros en otra. Veamos:
|
131
|
+
|
132
|
+
```
|
133
|
+
$ ssh administrador@192.168.1.114 'pwd' > win.tmp
|
134
|
+
administrador@192.168.1.114's password:
|
135
|
+
|
136
|
+
$ file --mime win.tmp
|
137
|
+
win.tmp: text/plain; charset=us-ascii
|
138
|
+
|
139
|
+
$ ssh administrador@192.168.1.114 'chcp' > chcp.tmp
|
140
|
+
administrador@192.168.1.114's password:
|
141
|
+
|
142
|
+
$ ssh administrador@192.168.1.114 'get-windowsfeature -name rds-rd-server' > gwf.tmp
|
143
|
+
administrador@192.168.1.114's password:
|
144
|
+
|
145
|
+
$ file --mime /tmp/gwf.tmp
|
146
|
+
/tmp/gwf.tmp: text/plain; charset=iso-8859-1
|
147
|
+
```
|
148
|
+
|
149
|
+
> Pues la salida de los comandos de W2012 son:
|
150
|
+
> * `us-ascii` algunas veces, y otras en
|
151
|
+
> * `iso-8859-1`
|
152
|
+
>
|
153
|
+
> ¿De qué depende? ¿Qué comandos usan cada encoding?
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
# Infrastructure test comparison
|
3
|
+
|
4
|
+
|
5
|
+
| Features | Teuton | Testinfra | Goss |
|
6
|
+
| -------- | ------ | --------- | ---- |
|
7
|
+
| URL | https://github.com/teuton-software/teuton | https://testinfra.readthedocs.io/en/latest/index.html | https://github.com/aelsabbahy/goss |
|
8
|
+
| License | GPL v.3 | Apache license 2.0 | Apache license 2.0 |
|
9
|
+
| Programming language | Ruby | Python | Go |
|
10
|
+
| Platforms | Multiplatform | Multiplatform | GNU/Linux |
|
11
|
+
| Remote connections | SSH, Telnet | SSH | ? |
|
12
|
+
| Installed on | Master | Slave | |
|
13
|
+
| Test Units Lenguage definition | Teuton DSL | Python | YAML |
|
14
|
+
| Configuration input files | YAML, JSON | Python | YAML |
|
15
|
+
| Output formats | Documentation, TXT, YAML, JSON, silent | ? | rspecish, documentation, JSON, TAP, JUnit, nagios, silent |
|
16
|
+
| Builtin functions | Yes | Yes | ... |
|
17
|
+
| Function creation | Yes | ? | ? |
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
# Keywords (DSL)
|
3
|
+
|
4
|
+
- [[DSL keywords]]
|
5
|
+
|
6
|
+
Definition
|
7
|
+
|
8
|
+
- [[group]]
|
9
|
+
- [[target]]
|
10
|
+
- [[goto]]
|
11
|
+
- [[run]]
|
12
|
+
- [[result]]
|
13
|
+
- [[expect]]
|
14
|
+
- [[result]]
|
15
|
+
|
16
|
+
Execution
|
17
|
+
|
18
|
+
- [[play]]
|
19
|
+
- [[show]]
|
20
|
+
- [[export]]
|
21
|
+
- [[send]]
|
22
|
+
|
23
|
+
Settings
|
24
|
+
|
25
|
+
- [[get]]
|
26
|
+
- [[set]]
|
27
|
+
|
28
|
+
---
|
29
|
+
|
30
|
+
- [[Home]]
|
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
## Description
|
3
|
+
|
4
|
+
Compare the obtained result with the expected one. This comparation process is registered into final report.
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
target 'Exist user obiwan'
|
10
|
+
run 'cat /etc/passwd'
|
11
|
+
expect 'root'
|
12
|
+
```
|
13
|
+
|
14
|
+
Use `expect` keyword to check output (from previous execution).
|
15
|
+
|
16
|
+
## Example
|
17
|
+
|
18
|
+
Let's see some examples:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
target 'Exist user obiwan'
|
22
|
+
run 'id obiwan'
|
23
|
+
expect 'obiwan' # Expect previous command output contains obiwan text
|
24
|
+
```
|
25
|
+
|
26
|
+
## Other uses
|
27
|
+
|
28
|
+
| Command | Description |
|
29
|
+
| ---------------------------- | ----------------------------------- |
|
30
|
+
| expect 'obiwan' | Expect line/s with obiwan |
|
31
|
+
| expect ['obiwan', 'kenobi' ] | Expect line/s with obiwan and kenobi|
|
32
|
+
| expect_one 'obiwan' | Expect one line with obiwan |
|
33
|
+
| expect_one ['obiwan','kenobi'] | Expect one line with obiwan and kenobi |
|
34
|
+
| expect_none 'obiwan' | Expect no line with obiwan |
|
35
|
+
| expect_none ['obiwan', 'kenobi' ] | Expect no line with obiwan and kenobi |
|
36
|
+
|
37
|
+
* **expect /Obiwan|obi-wan/**, Expect line/s with Obiwan or obi-wan. This example uses regular expresions.
|
38
|
+
|
39
|
+
---
|
40
|
+
|
41
|
+
## Expert mode
|
42
|
+
|
43
|
+
After every execution keyword (`goto`, or `run`), we get command outputs and save it into `result` object. So we can ask to `result` to create more complex evaluations.
|
44
|
+
|
45
|
+
For example, if we have this execution
|
46
|
+
```ruby
|
47
|
+
target 'Exist user vader'
|
48
|
+
run 'cat /etc/passwd'
|
49
|
+
```
|
50
|
+
|
51
|
+
Then we check result with
|
52
|
+
```ruby
|
53
|
+
expect result.find("vader").count.eq(1)
|
54
|
+
expect result.find(/Darth|darth/).find(/Vader|vader/).count.eq(1)
|
55
|
+
expect result.not_find('#').find(/vader).count.eq(1)
|
56
|
+
```
|
@@ -0,0 +1,112 @@
|
|
1
|
+
|
2
|
+
## Description
|
3
|
+
|
4
|
+
Connect to remote host and executes command. The commadn output is saved into result object.
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
goto :host1, :exec => "id fran"
|
10
|
+
goto :host1, :execute => "id fran"
|
11
|
+
```
|
12
|
+
|
13
|
+
> ADVISE: I know that programers dislike `goto` sentence, but this is diferent. Think of it as english speaker, not as developer.
|
14
|
+
|
15
|
+
* This example connect to remote host identified by `host1`. Then we execute the command into it and save the output commadn into result object.
|
16
|
+
* `host1` is a lbal that identifies specific machine. Host information (ip, username, password, protocol) cames from config file.
|
17
|
+
|
18
|
+
## Examples
|
19
|
+
|
20
|
+
Execute `id obiwan` comand into remote host `linux1`.
|
21
|
+
```Ruby
|
22
|
+
goto :linux1, :exec => "id obiwan"
|
23
|
+
goto :linux1, :execute => "id obiwan"
|
24
|
+
goto :linux1, exec: "id obiwan"
|
25
|
+
goto :linux1, execute: "id obiwan"
|
26
|
+
```
|
27
|
+
|
28
|
+
Execute `id david` command into `localhost`.
|
29
|
+
|
30
|
+
```Ruby
|
31
|
+
goto :localhost, :exec => "id david"
|
32
|
+
goto :localhost, :execute => "id david"
|
33
|
+
run "id david"
|
34
|
+
```
|
35
|
+
|
36
|
+
## Protocol
|
37
|
+
|
38
|
+
**SSH connection**
|
39
|
+
|
40
|
+
By default, when invoking `goto :host1` sentence, Teuton try to open remote SSH session. This config files examples do the same:
|
41
|
+
|
42
|
+
Sample 1:
|
43
|
+
```
|
44
|
+
---
|
45
|
+
:config:
|
46
|
+
---
|
47
|
+
:global:
|
48
|
+
:cases:
|
49
|
+
- :tt_members: Student1
|
50
|
+
:host1_ip: 1.1.1.1
|
51
|
+
:host1_username: student
|
52
|
+
:host1_password: secret
|
53
|
+
```
|
54
|
+
|
55
|
+
Sample 2:
|
56
|
+
```
|
57
|
+
---
|
58
|
+
:config:
|
59
|
+
---
|
60
|
+
:global:
|
61
|
+
:cases:
|
62
|
+
- :tt_members: Student1
|
63
|
+
:host1_ip: 1.1.1.1
|
64
|
+
:host1_username: student
|
65
|
+
:host1_password: secret
|
66
|
+
:host1_protocol: ssh
|
67
|
+
```
|
68
|
+
|
69
|
+
**Telnet connection**
|
70
|
+
|
71
|
+
If you need to use telnet, then it's necessary specified that into config file. For example:
|
72
|
+
```
|
73
|
+
---
|
74
|
+
:global:
|
75
|
+
:cases:
|
76
|
+
- :tt_members: Student2
|
77
|
+
:host1_ip: 2.2.2.2
|
78
|
+
:host1_username: student
|
79
|
+
:host1_password: secret
|
80
|
+
:host1_protocol: telnet
|
81
|
+
```
|
82
|
+
|
83
|
+
**Localhost**
|
84
|
+
|
85
|
+
If our hostname is localhost, or the IP is 127.0.0.X, then Teuton will assume that you want to run your command on local system, and no session is opened. This examples are the same:
|
86
|
+
|
87
|
+
```
|
88
|
+
goto :localhost, :exec => "id david"
|
89
|
+
```
|
90
|
+
|
91
|
+
And
|
92
|
+
|
93
|
+
```
|
94
|
+
run "id david"
|
95
|
+
```
|
96
|
+
|
97
|
+
**SSH to localhost**
|
98
|
+
|
99
|
+
> NOTE: Only works on Teuton version >= 2.1.X
|
100
|
+
|
101
|
+
If you want to open SSH session to your localhost, then force SSH protocol into your config file, like this:
|
102
|
+
|
103
|
+
```
|
104
|
+
---
|
105
|
+
:global:
|
106
|
+
:cases:
|
107
|
+
- :tt_members: Student3
|
108
|
+
:host1_ip: 127.0.0.1
|
109
|
+
:host1_username: student
|
110
|
+
:host1_password: secret
|
111
|
+
:host1_protocol: ssh
|
112
|
+
```
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
## Description
|
3
|
+
|
4
|
+
Groups targets/goals.
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
group "group_name" do
|
10
|
+
...
|
11
|
+
end
|
12
|
+
```
|
13
|
+
|
14
|
+
* Define a group of targets or goal. These are groups of objectives to be evaluated.
|
15
|
+
* At least you must define one `group`, where you can define all your targets.
|
16
|
+
* We can use `group`, as many times as we need. Usefull to group related objectives.
|
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
## Description
|
3
|
+
|
4
|
+
`result` saves the output from previous execution.
|
5
|
+
It is usefull to build advanced `expect result...` sentences.
|
6
|
+
|
7
|
+
* After every execution (For example, `goto :host1, :exec => "whoami"`), Teuton gets output and saves it into `result` object.
|
8
|
+
* Use `result` object to read or filter that output.
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
This example get /etc/passwd file from host1, then filter lines without '#' and with '/bin/bash'.
|
13
|
+
Count lines number and expect it to be greater that 6.
|
14
|
+
|
15
|
+
```
|
16
|
+
target "Active users number configured with bash > 6"
|
17
|
+
goto :host1, :exec => "cat /etc/passwd"
|
18
|
+
expect result.grep_v('#').grep('/bin/bash').count.gt 6
|
19
|
+
```
|
20
|
+
|
21
|
+
## Examples
|
22
|
+
|
23
|
+
Boolean functions:
|
24
|
+
|
25
|
+
| Function | Description |
|
26
|
+
| ------------------- | ------------------------- |
|
27
|
+
| `result.eq(VALUE)` | Result equal to VALUE |
|
28
|
+
| `result.neq(VALUE)` | Result not equal to VALUE |
|
29
|
+
| `result.gt(VALUE)` | Result greater than VALUE |
|
30
|
+
| `result.ge(VALUE)` | Result equal or greater than VALUE |
|
31
|
+
| `result.lt(VALUE)` | Result lesser than VALUE |
|
32
|
+
| `result.le(VALUE)` | Result equal or lesser than VALUE |
|
33
|
+
|
34
|
+
Filtering functions:
|
35
|
+
|
36
|
+
| Function | VALUE type | Description |
|
37
|
+
| -------------------- | ----------- | ------------------------------------- |
|
38
|
+
| `result.find(VALUE)` | String | Filter lines that contains VALUE text |
|
39
|
+
| | RegExp | Filter lines that match VALUE regexp. For example `/?ello]`, filter lines with "Hello" or "hello" |
|
40
|
+
| | Array | Apply filter to every array element. For example `["Hi","Hello"]`, filter lines with "Hi" or "Hello". |
|
41
|
+
| `result.grep(VALUE)` | | Same as find |
|
42
|
+
| `result.not_find(VALUE)` | | Filter lines that not contains VALUE. VALUE may be String, Regular Expresion or an Array. |
|
43
|
+
| `result.grep_v(VALUE)` | | Same as not_find |
|
44
|
+
| `result.count` | | Count lines from result and save this number into result object. |
|
45
|
+
| `result.restore` | | Restore result data. After every filtering action result is modified, but this function restore data to their original state. |
|
46
|
+
|
47
|
+
Information functions:
|
48
|
+
|
49
|
+
| Function | Description |
|
50
|
+
| -------------------- | --------------------------------- |
|
51
|
+
| `result.value` | Return first output line or value |
|
52
|
+
| `result.content` | Return all output lines |
|
53
|
+
| `result.alterations` | Return transformations applied to the output |
|
54
|
+
| `result.debug` | Print the result content on screen. Usefull for debugging process |
|
55
|
+
|
56
|
+
## Expert use
|
57
|
+
|
58
|
+
It's posible contenate a sequence of several results orders. Examples:
|
59
|
+
|
60
|
+
Supose we execute this:
|
61
|
+
```
|
62
|
+
goto :host1, :exec => "cat /etc/passwd"
|
63
|
+
```
|
64
|
+
And then we could do:
|
65
|
+
* Get all lines that dosn't contain "nologin" and contain "/bin/bash"
|
66
|
+
```
|
67
|
+
result.grep_v("nologin").grep("/bin/bash")
|
68
|
+
```
|
69
|
+
* Count all lines that dosn't contain "nologin" and contain "/bin/bash"
|
70
|
+
```
|
71
|
+
result.grep_v("nologin").grep("/bin/bash").count
|
72
|
+
```
|
73
|
+
* Return true if the number when count all lines that dosn't contain "nologin" and contain "/bin/bash" is greater than 0
|
74
|
+
```
|
75
|
+
result.grep_v("nologin").grep("/bin/bash").count.gt 0
|
76
|
+
```
|