miércoles, 5 de diciembre de 2018

Guía de scripting en PowerShell


¿Que es PowerShell?
Creo que no es necesaria una explicación, pero si has estado viviendo en un bunker toda tu vida, paso a resumirlo a modo de introducción. PowerShell es una consola de comandos para automatizar tareas y que apareció para desbancar a sus predecesoras, con mucha mas funcionalidad y sencillez.

Ventajas

  • PowerShell viene de forma predeterminada desde Windows Vista, por lo tanto no es necesario la instalación de software de terceros para la ejecución de scripts como pasa con otros lenguajes.
  • La programación es mucho mas sencilla que con la antigua consola, ya que puede recordar a otros lenguajes.
  • Puede instalarse en Linux
Desventajas

  • Los scripts solo servirán para sistemas windows.
  • Los scripts realizados para versiones mas modernas de PS es muy probable que no funcionen correctamente en versiones mas antiguas de PS.

¿PowerShell usa comandos de Linux?
No. Esta consola trae una serie de ALIAS para que puedas usar las abreviaturas de los comandos de Linux. Para ver los alias, usa en la consola:
Get-Alias

Restricción
PS trae una restricción predeterminada para el bloqueo de ejecuciones delicadas, para ver, quitar y poner esta restricción:
Ver: Get-ExecutionPolicy
Modificar: Set-ExecutionPolicy [Unrestricted | AllSigned | RemoteSigned | Restricted]

¿Como se crean script en PowerShell?
Cuando vamos a crear un script con nuestro editor de texto favorito, lo vamos a guardar con la extensión ".ps1". Hay otras extensiones como los módulos de script (.psm1), pero no nos meteremos con eso. Una vez preparado todo vamos empezar con lo básico:
Get-Command Con este puedes listar todos los comandos y funciones que estan establecidos en el terminal.

Para empezar, veamos unos pocos cambios entre CMD y PowerShell:

CMDPowerShellEjemplo
echo %variable%Write-Host $variableWrite-Host $pais
%variableSistema%$env:variableSistema$env:userprofile
set /p variable="Contenido?: "$variable=read-host "Contenido?"$pais=read-host "Donde naciste?"
%Date:~0,2%-%Date:~3,2%-%Date:~6,4%(get-date).tostring('dd-MM-yyyy')05/12/2018

Muchos de los comandos de CMD siguen funcionando, pero lo interesante es que aprendas a adaptar todo a Powershell, porque con esta consola puedes hacer todo lo de CMD y más. Cosa que no puede decirse a la inversa.

Una cosa que aprenderás a medida vayas aprendiendo a usarlo, es que la forma de extraer información es muy similar a una query de SQL. Seleccionando lo que quieres obtener (get-xxx o select), filtrando la información (Where o -Filter) y ordenando (Sort-Object).

En cuanto a los condicionales, no se usan los simbolos "= > <", en este caso hay una nomenclatura diferente:
-eqIgual
-neNo es igual
-ltMenor que
-leMenor o igual que
-gtMayor que
-geMayor o igual que

De resto y para ir terminando, es muy parecido a cualquier otro lenguaje. Bucles, condificonales, etc. Podéis ver ejemplos de utilidades que he programado en: https://github.com/Kevinsillo/powershell-utilities

Esto a sido todo, cualquier duda la dejáis en los comentarios y tratare de resolverla.

Fuentes:
https://4sysops.com/archives/powershell-comparison-operators-eq-lt-gt-contains-like-match/ https://es.wikipedia.org/wiki/Windows_PowerShell

miércoles, 31 de octubre de 2018

Docker-Compose: Mi primera receta

Resultado de imagen de docker compose down one container

Hoy vamos a hablar del orquestador de Docker y aprender a crear nuestro primer ficher de docker-compose. Si aun no conoces Docker, en esta publicación lo explico y doy unas sencillas pautas para comenzar con él.

Un poco de teoría
Docker-Compose es una herramienta que se instala aparte de Docker y que nos permite realizar "recetas" para levantar varios contenedores con la posibilidad de que estén conectados entre sí de una forma bastante sencilla, entre otras cosas que veremos. Simplemente bastará con crear un archivo llamado docker-compose.yml (en los casos mas sencillos).

Instalando docker-compose
Esto es bastante sencillo, solo tendremos que hacer uso de los siguientes comandos:
sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
Por aquí les dejo la pagina de la documentacion con los pasos de instalación por si encontrais problemas: https://docs.docker.com/compose/install/#install-compose

Primera configuración
Como antes comentamos, solo tenemos que crear un fichero llamado docker-compose.yml donde queramos, escribir las ordenes para levantar los contenedores y finalmente ejecutarlo. Voy a poner un ejemplo de configuración en el que podamos ver mas o menos gran parte de las posibilidades:

version: '3'
services:
    nagios:
        image: jasonrivers/nagios:latest
        hostname: nagios
        container_name: nagios
        volumes:
          - "./path-to-nagios/etc/:/opt/nagios/etc/"
          - "./path-to-nagios/var:/opt/nagios/var/"
          - "./path-to-custom-plugins:/opt/Custom-Nagios-Plugins"
          - "./path-to-nagiosgraph-var:/opt/nagiosgraph/var"
          - "./path-to-nagiosgraph-etc:/opt/nagiosgraph/etc"
        ports:
          - "8080:80"
        networks:
          frontend:
            ipv4_address: 172.20.0.5
    nginx:
        image: nginx
        hostname: web
        container_name: web
        links:
          - mysql
        volumes:
          - ./web1:/usr/share/nginx/html
          - ./default.conf:/etc/nginx/conf.d/default.conf
        networks:
          frontend:
            ipv4_address: 172.20.0.6
    mysql:
        image: mysql
        hostname: database
        container_name: database
        networks:
          frontend:
            ipv4_address: 172.20.0.7
networks:
    frontend:
        ipam:
          config:
            - subnet: 172.20.0.0/24
Vamos a comenzar por las dos primeras instrucciones casi religiosas, la versión que usaremos y la cabecera de los servicios. A partir de ahí vienen los contenedores: Nagios, Nginx y MSQL. Dentro de cada servicio tenemos:
image: Nombre de la imagen local u online (Dockerhub)
hostname: Nombre de la "maquina"
container_name: Nombre del contenedor
links: Conectar contenedores
ports: Redirección de puertos "anfitrión:contenedor"
volumes: Carpetas compartidas con el contenedor en formato "anfitrión:contenedor"
networks: Configuración de red como dirección IP
 Al final del todo, fuera de los servicios, tenemos una configuración general sobre la red. Ya que si no la nombramos nos dará problemas con los contenedores. Obviamente la configuración de ese fichero podría complicarte muchísimo más para cosas mas concretas, pero tampoco era la intención.

También hay que plantearse cuando compensa complicarse y cuando no. Si ya existe una imagen que reúne todos los servicios LAMP, para que montar varios contenedores interconectados (Apache, MSQL, PHP...) pudiendo levantar uno solo que ya reúna todas las herramientas, como este caso.

Esto a sido todo, cualquier duda la dejáis en los comentarios y tratare de resolverla.

Fuente: https://docs.docker.com/compose/compose-file

jueves, 11 de octubre de 2018

Diseñando un buen script


Tanto si vas a programar un script para otra persona como para ti mismo, es interesante que su diseño sea limpio, claro y conciso. Si sigues esta serie de pautas lo tendrás.

Ejecución desatendida
En este caso concreto, destacar que el script tiene que ser claro para su posible comprensión o cambios en el futuro. De resto, el script se ejecutará sin ser visto (ninja mode), con lo cual poco importa que sea bonito.

Ejecución manual
Aquí ya la cosa cambia, sobre todo si tenemos un script estilo asistente (mis preferidos). Hablemos de este con un ejemplo:

WindowsLinux
REM Autor: Kevin I.
REM Date: xx/xx/xx
REM Descripcion: Script para bla bla..
echo off
cls 
REM --- VARIABLES ---
set userx=kevin 
REM --- EXECUTIONS ---
echo Hello %userx%
net user %userx% /add
#!bin/bash
# Autor: Kevin I.
# Date: xx/xx/xx
# Descripcion: Script para bla bla..
clear 
#  --- VARIABLES ---
userx=kevin 
# --- EXECUTIONS ---
echo Hello $userx
useradd -m -s /bin/bash $userx
Como podéis observar, destacan 3 partes principales: Descripcion, variables y ejecuciones
Yo particularmente empiezo poniendo el autor (en caso de Linux, también el interprete):

WindowsLinux
rem Autor: Kevin I.#!bin/bash
# Autor: Kevin I.
Luego limpiar la ventana. En windows, para una mejor comprensión, desactivar los echo de los comandos (echo off):

WindowsLinux
echo off
cls
clear
A partir de ahí las variables y las ejecuciones. Con respecto a las variables, mi consejo es que sean descriptivas y con pocos caracteres (nada de %direccion_ip_metida_en_esta_variable%). Llevando la buena practica un poco mas lejos, construir el script completo en ingles.

Creo que es importante separar las variables que van a ser fijas y la que serán modificadas manualmente antes de su ejecución. Aunque podemos evitar eso pasando parámetros al script con las variables que serán modificadas según el caso y de esta forma no tener que editar el archivo cada vez que se quiera cambiar alguna variable:

WindowsLinux
script.bat kevin
script.sh kevin
REM Autor: Kevin I.
echo off
cls 
REM --- VARIABLES ---
set userx=%1 
REM --- EXECUTIONS ---
echo Hello %userx%
net user %userx% /add
#!bin/bash
# Autor: Kevin I.
clear 
#  --- VARIABLES ---
userx=$1
# --- EXECUTIONS ---
echo Hello $userx
useradd -m -s /bin/bash $userx
Hay una opción alternativa a las anteriores y es preguntar por el contenido que tendrán esas variables que cambian. Al ejecutar el script siguiente script, se detendrá para preguntarte "Nombre?:", lo escribes y continua la ejecución del resto del código:

WindowsLinux
REM Autor: Kevin I.
echo off
cls 
REM --- VARIABLES ---
set /p userx=Nombre?: 
REM --- EXECUTIONS ---
echo Hello %userx%
net user %userx% /add
#!bin/bash
# Autor: Kevin I.
clear 
#  --- VARIABLES ---
read -p "Nombre?: " userx
# --- EXECUTIONS ---
echo Hello $userx
useradd -m -s /bin/bash $userx
Otra cosa a tener en cuenta, al igual que cualquier lenguaje de programación, es el tabulado. Importante para facilitar la lectura del código.

Para acabar, dejo de ejemplo un sencillo script en batch que suelo usar con todo lo anterior y algunos extras como un menú. A ver si averiguáis su función:
REM Autor: Kevin I.
REM Date: xx/xx/xx
REM Descripción: DELETED FOR SPOILER
ECHO OFF
CLS
:ZERO
ECHO --------------------------------------
ECHO Menú
ECHO --------------------------------------
ECHO.
ECHO 1.- Direccion IP Red 1 (192.168.0.190)
ECHO 2.- Direccion IP Red 2 (172.20.11.190)
ECHO 3.- Otra IP
ECHO.
SET /p option=Elige una opcion:
IF %option%==1 (
GOTO UNO
)
IF %option%==2 (
GOTO DOS
)
IF %option%==3 (
GOTO TRES
) ELSE (
ECHO Error: Elija una de las opciones
PAUSE
GOTO ZERO
)
:UNO
netsh interface ip set address "Ethernet" static 192.168.0.190 255.255.255.0 192.168.0.254
netsh interface ip set dns "Ethernet" static 8.8.8.8 8.8.4.4
ECHO Direccion IP Red 1 aplicada
ECHO.
PAUSE
EXIT
:DOS
netsh interface ip set address "Ethernet" static 172.20.11.190 255.255.255.0 172.20.11.254
netsh interface ip set dns "Ethernet" static 8.8.8.8 8.8.4.4
ECHO Direccion IP Red 2 aplicada
ECHO.
PAUSE
EXIT
:TRES
CLS
SET /p direc=Direccion IP:
SET /p masc=Mascara:
SET /p gate=Gateway:
SET /p dns1=DNS principal:
SET /p dns2=DNS secundario:
ECHO.
netsh interface ip set address "Ethernet" static %direc% %masc% %gate%
netsh interface ip set dns "Ethernet" static %dns1% %dns2%
ECHO Direccion IP %direc% aplicada
ECHO.
PAUSE
EXIT

lunes, 8 de octubre de 2018

Swithmail - Envío de correos con scripts


¿Queréis programar scripts con avisos al correo electronico pero no tenéis un servidor de correo? Swithmail es tu solución. Un pequeño software portable que podrás usar desde tus scripts de batch.

No quiero extenderme mucho, por que tampoco hay mucho que contar. Les dejaré la pagina oficial al final del blog.

Yo por ejemplo, lo he implementado en un script para backups de SQL Express, de esta forma, me envía correos electrónicos tanto si los backups finalizaron correctamente o no, modificando en cada caso el asunto y cuerpo del correo.

Modo de uso
Simplemente dando doble-click en el ejecutable, el programa nos mostrará su uso por ventana de comandos/scripting.

EDIT: Evitar el uso de correos personales por riesgo de bloqueos de cuenta temporales (hotmail, outlook, gmail, etc). Parece ser que estos servicios no permiten el uso automatizado, infringe las normas.

Página oficial:
https://www.tbare.com/software/swithmail/

jueves, 4 de octubre de 2018

Docker - Conceptos básicos y primer contenedor

Empezar con Docker sin unas serie pautas puede convertirse en un dolor de cabeza, por eso hoy traigo una guía definitiva (me vine arriba) de conceptos y comandos básicos para comenzar a usarlo sin morir en el intento.

En la anterior entrada les recomendaba docker-compose por su sencillez y estructura tan visual, pero este consejo iba destinado a aquellas personas que ya controlan Docker.

Lo básico
Sería lógico comenzar por una explicación de qué es y para qué sirve. Docker es un gestor de contenedores. ¿Contenedores? Si "pequeños" encapsulamientos que traen consigo grupos de funcionalidades. Para partir de una base, se suele comparar vulgarmente con pequeñas máquinas virtuales precocinadas.
Una maquina virtual, parte de un sistema operativo, un programa virtualizador y un sistema operativo virtualizado. Esto, obviamente, consume muchos recursos del anfitrión. Docker no virtualiza todo un sistema operativo, usa las librerías del anfitrión. Aquí dejo una gráfica para que se entienda mejor y dejamos a un lado la explicación.

Conceptos
  • Contenedor: Es la instancia en ejecución de una imagen docker
  • Imagen: Es una especie de plantilla para levantar un contenedor de docker. Cuando vas a levantar un contenedor, Docker busca la imagen en el anfitrión, si no está, la intenta descargar de DockerHub automaticamente.
  • Volumen: Define una unidad de almacenamiento "virtual" (puede compartirse entre contenedores)
  • Docker-Compose: Nos ofrece la posibilidad de formar una plantilla/receta a partir de una o varias imágenes ya creadas, pudiendo levantar varios contenedores intercomunicados.
  • DockerHub: Repositorio de imágenes precocinadas oficiales y no oficiales.
  • Dockerfile: Receta para crear tus propias imágenes personalizadas y posteriormente usarlas o subirlas a DockerHub.
Instalación
Estos son los comandos de instalación de Docker:
sudo apt install curl
curl -fsSL get.docker.com -o get-docker.sh
sudo chmod +x get-docker.sh
sh get-docker.sh
Comandos de uso
Los siguientes comandos muestran los tres principales recursos de docker antes mencionados. Todos esos recursos pueden estar referenciados por un ID o un nombre (si se le asignó previamente).:
docker images list
docker container list
docker volume list
Al igual que listamos con "list" (o "ls") podemos borrar con "rm". El resto dejo que lo investigues tu con la guia (docker image/volume/container ?). Hay que controlar bien esos tres comandos para no volverte loco creando decenas de contenedores/volúmenes.

Estos otros sirven para ver el estado de los contenedores encendidos, apagados y todos:
docker ps
docker ps -f status=exited
docker ps -a
 A continuación comandos para encender o apagar contenedores anteriormente creados:
docker start [nombre/ID]
docker stop [nombre/ID]
Vamos con algunos ejemplos de comandos simples para levantar contenedores:
Crea un contenedor con Ubuntu ultima version
docker run ubuntu:latest
Crea un contenedor interactivo con Apache HTTP Server
docker run -it httpd
Crea un contenedor con MySQL y redirección del puerto 3306 al 3306
docker run mysql -p 3306:3306
Crear un contenedor Wordpress con el nombre wp-tienda y puerto 80
docker run --name wp-tienda -p 80:80 wordpress
Una vez tenemos levantados los contenedores, si ejecutamos "docker ps -a" comprobaremos que están en estado "Exited". Tenemos que iniciarlos con el comando "docker container [nombre/ID] start". De esta forma, ya estarán listos para su uso.

Para finalizar, os dejo dos últimos comandos. Para entrar dentro de un contenedor y para ejecutar comandos desde fuera del contenedor:
docker exec -i -t [nombre/ID] /bin/bash
docker exec [nombre/ID] df -h
Y esto a sido todo, cualquier duda la dejáis en los comentarios y tratare de resolverla.