Tips, Soluciones y Novedades en Tecnología

27/08/2023

Despliegue versionado con Docker Compose


Cuando tenemos ambientes productivos en el cual utilizamos Docker para gestionar nuestras aplicaciones, es mucho mas práctico ya que no tenemos que preocuparnos de las configuraciones y versión de cada software que desplegamos debido a que cada contenedor internamente esta preparado para funcionar sin realizar configuración extra por parte de los administradores de servidores o sysadmin.


Los despliegues en producción requieren una trazabilidad, muy importante para poder hacer rollback ante cualquier incidencia nueva que genere algún error o por cualquier otro motivo, por ello es necesario implementar mecanismos de versionamiento de las imágenes.

Una de las recomendaciones es versionar las imágenes cada vez que se envían a producción, por ejemplo si tenemos una imagen con el siguiente nombre: app-portal, podemos versionar de la siguiente manera.

- app-portal:prod_1

- app-portal:prod_2

- app-portal:prod_3

- app-portal:prod_4

Lógicamente esas imágenes requiere un repositorio como Docker Registry, GitLab Registry u otro proveedor para almacenar imágenes Docker.

Una vez que nuestro repositorio tenga las imágenes versionados, necesitamos scripts que nos permita ejecutar contenedor con versiones especificas.


Tenemos 3 versiones de un servidor NGINX el cual se encuentra con el siguiente nombre: app-portal, y se encuentra en local con el siguiente contenido, modificaremos el texto y generaremos una versión hasta tener las 3 versiones distintas.



Una vez accesible las versiones de imágenes podremos ver un resultado como la siguiente:

 - docker images


Ahora lo que debemos hacer es un archivo docker-compose que permita desplegar un contenedor recibiento el nombre del contenedor con la versión indicada.

version: "3.9"
services:
 app-portal:
    container_name: app-portal
    image: ${CONTAINER_PORTAL_VERSION}
    ports:
     - 80:80
    restart: always
    network_mode: bridge

Como podemos observar, la variable: CONTAINER_PORTAL_VERSION, debemos pasarle para que docker-compose pueda remplazar con el valor proporcionado en el script.

Ahora generamos un script deploy_portal.sh para ejecutar docker-compose.

#!/bin/bash
echo "------- Detenemos el contenedor -----"

CONTAINER_PORTAL_VERSION="$1" docker-compose -f portal/docker-compose.yaml down
echo "Iniciamos la nueva version" CONTAINER_PORTAL_VERSION="$1" docker-compose -f portal/docker-compose.yaml up -d echo "contenedor desplegado"


Para ejecutar el script es necesario aplicar permiso de ejecución y ejecutar el archivo de la siguiente forma.

./deploy_portal.sh "app-portal:prod_1"

Ahora ejecutamos el siguiente comando

./deploy_portal.sh "app-portal:prod_2"

Y por ultimo la versión 3.

./deploy_portal.sh "app-portal:prod_3"



Como podemos ver, de esta forma podemos gestionar las versiones de los contenedores utilizando docker-compose, con eso nos aseguramos que cada vez que ejecutamos un nuevo contenedor en entorno de producción siempre tendremos la versión que se pasa como parámetro.


Este procedimiento se puede utilizar para automatizar en entornos DevOps facilitando el despliegue y manejando las versiones eficientemente, debido a que en caso se requiera hacer un rollback, solo se deben pasar al script la imagen y la versión anterior al ultimo pase, esto se puede hacer de forma manual o automatizada.

Saludos.


11/06/2023

Desplegar SQL Server 2017 en contenedores Docker


En versiones anteriores a SQL Server 2017, normalmente se solía correr  SQL Server en servidores dedicados o en maquinas virtuales, pero ante la creciente incremento de la contenerización, eso se convierte en una necesidad empresarial, entonces Microsoft entendió y preparó para poder correr Instancias SQL Server en contenedores docker, para ello hay varios formas de desplegar, en este Post veremos como desplegar de forma fácil.



Descargar la imagen SQL Server 2017

docker pull mcr.microsoft.com/mssql/server:2017-latest

Una vez descargado la imagen, necesitamos completar algunos parámetros para desplegar.


docker run -d -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=SQL3032$" -p 1433:1433 -d mcr.microsoft.com/mssql/server:2017-latest

Las variables ACCEPT_EULA, es para aceptar el término de la licencia, y MSSQL_SA_PASSWORD es para asignar la contraseña al usuario por defecto "sa", con ello ya podremos tener SQL Server 2017 en ejecución.

Ejecutamos "docker ps" para ver el contenedor en ejecución.



Ahora abriremos SQL Management Studio para conectarnos a la base de datos en ejecución.





Como se puede ver, se puede crear las bases de datos que consideremos necesarias, pero recordar que en cuanto eliminemos el contenedor también se eliminarán las bases de datos creados, por lo que ahora configuraremos un volumen para que SQL Server almacene los datos fuera del contenedor y que cuando se elimine el contenedor no se pierdan los datos previamente configurados.

Para mantener los datos en un directorio externo al contenedor, debemos configurar de la siguiente forma:

Ejemplo en Linux

docker run -d \
-e "ACCEPT_EULA=Y" \
-e "MSSQL_SA_PASSWORD=SQL3032$" \
-e "MSSQL_PID=Express" \
-p 1433:1433 \
-v /opt/sql_server_2017/data:/var/opt/mssql/data \
-v /opt/sql_server_2017/log:/var/opt/mssql/log \
-v /opt/sql_server_2017/secrets:/var/opt/mssql/secrets \
-d mcr.microsoft.com/mssql/server:2017-latest

Ejemplo en Windows

docker run -d -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=SQL3032$" -e "MSSQL_PID=Express" -p 1433:1433 -v C:\sql_server_2017/data:/var/opt/mssql/data -v C:\sql_server_2017/log:/var/opt/mssql/log -v C:\sql_server_2017/secrets:/var/opt/mssql/secrets -d mcr.microsoft.com/mssql/server:2017-latest


Las variables que le pasamos son:
ACCEPT_EULA: Aceptación de término de licencia
MSSQL_SA_PASSWORD: Contraseña del usuario sa
MSSQL_PID: Versión de SQL Server, si no ponemos este versión por defecto nos levanta la versión Developer. estas son valores que se puede configurar:

Developer: Esto ejecutará el contenedor usando Developer Edition (este es el valor predeterminado si no se proporciona una variable de entorno MSSQL_PID)
Express: Esto ejecutará el contenedor usando Express Edition
Estándar: Esto ejecutará el contenedor usando la Edición Estándar
Enterprise: Esto ejecutará el contenedor usando Enterprise Edition
EnterpriseCore: Esto ejecutará el contenedor utilizando Enterprise Edition Core

Una vez ejecutado el comando docker, si hacemos "docker ps" veremos los siguiente:



Como la ejecución lo estamos realizando en windows, vemos el contenido de la carpeta asignado como volumen:



Creamos 3 bases de datos:



Ahora vemos si se encuentra en la carpeta "data":


Como se puede ver, los datos y configuraciones de SQL Server, lo guarda en una carpeta externa al contenedor que al momento de iniciar el contenedor se les pasó como parámetro.

Esto es recomendable usar en entornos de producción, donde si por alguna razón tenemos alguna falla en el contenedor, los datos no se pierdan y podremos iniciar otra instancia en un nuevo contenedor y podremos ver los datos nuevamente.


Adicionalmente si queremos habilitar el Agente para los Backups programados, debemos hacerlo mediante un archivo Dockerfile, para ello, creamos un archivo Dockerfile con el siguiente contenido:

FROM mcr.microsoft.com/mssql/server:2017-latest
USER root
RUN /opt/mssql/bin/mssql-conf set sqlagent.enabled true

Ejecutamos el comando:

docker build -t mssql-server:2017-latest .



Ahora ejecutamos, la versión Developer, por que en la versión Express, no se puede habilitar la característica del agente de SQL Server.

Ejecutamos el siguiente comando:

docker run -d -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=SQL3032$" -e "MSSQL_PID=Developer" -p 1433:1433 -v C:\sql_server_2017/data:/var/opt/mssql/data -v C:\sql_server_2017/log:/var/opt/mssql/log -v C:\sql_server_2017/secrets:/var/opt/mssql/secrets -d mssql-server:2017-latest


Y nuevamente nos conectamos:


Como se puede ver, se tiene habilitado el SQL Server Agent.

Es relativamente práctico trabajar con contenedores, esto puede facilitar al desarrollador a que pueda crear su base de datos sin necesidad de requerir un ambiente extra y para los administradores, tener múltiples instancias en múltiples versiones en un mismo servidor.

Saludos.



05/06/2023

Generando Imagen QR en Java



Google a creado varias APIS para facilitar el desarrollo de proyectos Java.

Cuando trabajamos con códigos de barras, código QR etc, tenemos que tener buenas librerías para que nos de soporte para generar estos formatos cifrados.



Ejemplos de usos son: (DNI trabajador, Código Universitario, etc), estos pueden ser imprimidos en fotocheck o carnets y con ellos se puede controlar muchos aspectos como Horarios de trabajos, fecha de ingreso, salida e identificación del mismo, en fin hay un sin números de usos para este tipo de cifrados.

A continuación vamos a generar un código QR en una imagen .PNG, le pasaremos un código a cifrar.

Primero tenemos que definir la deprencia a nuestro proyecto añadiendo la dependencia a pom.xml de nuestro proyecto, y si no utilizan maven lo pueden bajar diretamente el .jar (.jar) y agregarlo a la librería del proyecto.




 1
2
3
4
5
6
7
8
9
10
11

 <!-- Barcode image processing -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>2.2</version>
</dependency>



El código en java para generar seria el siguiente.




 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

public static void main(String[] args) throws Exception {
generarImageQR("123456789", "png", "D:\\data\\imageQR.png");
}

private static void generarImageQR(String code, String TypeImage, String urlFile) throws Exception {
int size = 125;
String fileType = TypeImage;
File myFile = new File(urlFile);
try {
Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<>();
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix byteMatrix = qrCodeWriter.encode(code, BarcodeFormat.QR_CODE, size, size, hintMap);
int CrunchifyWidth = byteMatrix.getWidth();
BufferedImage image = new BufferedImage(CrunchifyWidth, CrunchifyWidth, BufferedImage.TYPE_INT_RGB);
image.createGraphics();
Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, CrunchifyWidth, CrunchifyWidth);
graphics.setColor(Color.BLACK);
for (int i = 0; i < CrunchifyWidth; i++) {
for (int j = 0; j < CrunchifyWidth; j++) {
if (byteMatrix.get(i, j)) {
graphics.fillRect(i, j, 1, 1);
}
}
}
ImageIO.write(image, fileType, myFile);
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}



Validando nuestra Imagen generada en : Read Online Image QR





Saludos cordiales.

Escalamiento horizontal en Docker


El despliegue de las aplicaciones en contenedores docker es una tarea manual, sobre todo si queremos escalar, docker solo no permite escalar, pero docker compose si que lo permite, y nos da la facilidad para escalar con simples comandos y de varias maneras.

En este Post estamos utilizando Docker desktop para Windows, Para la instalación seguir la guía correspondiente:https://docs.docker.com/desktop/install/windows-install/


Una vez instalado, habilitamos la opción de docker compose:


Abrimos la consola y verificamos si todo esta configurado correctamente:


Verificamos la versión de docker compose:



Ahora non ubicamos en una carpeta en particular, en este caso C:\docker\docker-nginx y dentro creamos el archivo .yml  con el siguiente contenido. 

C:\docker\docker-nginx\docker-compose.yml

version: '3'
services:
  nginx:
    image: nginx
    deploy:
      replicas: 3
    network_mode: bridge


Ahora abrimos la consola y ejecutamos el siguiente comando para iniciar el contenedor:
Nos ubicamos en el directorio del archivo  "docker-nginx"

C:\docker\docker-nginx>docker-compose up -d 


El resultado se descargará la imagen de nginx y creará 3 instancias.

Ahora para escalar a mas de 3 instancias podemos hacerlos de 2 maneras.

Primera:

Modificando el archivo docker-compose.yml y aumentando el numero de replicas, ejemplo a 5. volvemos a ejecutar

C:\docker\docker-nginx>docker-compose up -d 

Y tendremos 5 instancias de nginx corriendo.

Segunda:

Esta segunda es mediante un flag de docker-compose, llamado scale, y seria de la siguiente forma:

C:\docker\docker-nginx>docker-compose up -d --scale nginx=5

El resultado lo podemos ver:



Nuevamente podemos ejecutar pero ahora con 10 instancias:

C:\docker\docker-nginx>docker-compose up -d --scale nginx=10


Ahora reducimos a 2 instancias:

C:\docker\docker-nginx>docker-compose up -d --scale nginx=2


Y así podremos ir escalando en medida que necesitemos y los recursos los soporten.

La fuente también lo pueden descargar en Github

Saludos.



04/06/2023

Enviar Logs desde Spring Boot a Logstash


La gestión de logs en proyecto java, normalmente se registran en archivos según la configuración va generando historial con el tiempo.

Para tener disponible mediante acceso web a los logs del servidor, una buena practica es gestionar con herramientas especializadas y segun nuestras necesidades explotar esos logs con el obetivo de entender mejor que esta pasando en el funcionamiento de nuestra aplicación

En este Post veremos como configurar la librería Logback que permite enviar logs desde un proyecto Spring Boot al servidor LogStash, y este podrá enviar a un servidor ElasticSearch u otro segun necesidad.

Agregamos la dependencia maven al proyecto

<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.6</version>
</dependency>

Configuración de Logback junto al archivo de application.yml de spring

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property resource="application.yml" />
    <springProperty scope="context" name="logstash" source="logging.logstash.url"/>
    <springProperty scope="context" name="loglevel" source="logging.level.root"/>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>${logstash}</destination>
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <mdc />
                <context />
                <logLevel />
                <loggerName />
                <pattern>
                    <pattern>
                        {
                        "app": "myapp"
                        }
                    </pattern>
                </pattern>
                <threadName />
                <message />
                <logstashMarkers />
                <stackTrace />
            </providers>
        </encoder>
    </appender>
    <logger level="${loglevel}">
        <appender-ref ref="logstash"/>
    </logger>
    <root level="${loglevel}">
        <appender-ref ref="logstash"/>
    </root>
</configuration>

Ahora configuramos el archivo application.yml del proyecto de Spring.

# Configuración de Logs
logging:
  file:
    name: /opt/apps/myapp.log
    max-size: 10MB
    max-history: 30
    clean-history-on-start: true
  logstash:
    url: logstash.mydominio.com:5000
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} - %msg%n"
  level:
    root: INFO
    org.springframework.web: INFO

Como se puede apreciar, en la secion "logging" se define file y logstash, esto permitirá escribir los logs en disco y enviar a logstash al mismo tiempo.

Ahora vamos a ver el contenido del archivo de configuración de logstash que estará escuchando en el puerto 5000, esperando que logback envie los logs desde spring boot.

Crear el archivo apps.conf en /etc/logstash/conf.d

input {
  tcp {
        port => "5000"
        codec => json_lines
    }
}
filter {
}
output {
  elasticsearch {
    hosts => ["https://localhost:9200"]
    user => "logstash"
    password => "123456789"
    cacert => "/etc/logstash/certs/http_ca.crt"
    ssl => true
    ssl_certificate_verification => false
    index => "miempresa-apps-%{+YYYY.MM.dd}"
  }
}

El codigo de la configuración de logstash decepciona el log, no aplica filtro y envía a elasticsearch para su indexación y su posterior visualización desde Kibana, similar a la imagen siguiente.



Saludos.




Envía alertas por correo electrónico sin licencia (Gold) de Kibana


Las notificaciones en Elastic Kibana Free edition, están restringidas a solo la creación de índice y registro en log,  usar otro tipos de conectores, requiere una licencia Gold.



Nuestro objetivo es enviar correo, incluso mensaje de texto con cada alerta que se generan en kibana, para ello vamos apoyarnos de librerías y utilitarios en linux, en este post se ha realizado el envío desde un Linux Ubuntu 22.04.

Instalamos requeridas:

apt-get install swatch

apt-get install jq

apt-get install mailutils

Ahora debemos identificar la ruta de log de kibana, normalmente es:

/log/kibana/kibana.log

Cada vez que se genera una alerta, se registrará en el log, un mensaje similar a esta:

{"service":{"node":{"roles":["background_tasks","ui"]}},"ecs":{"version":"8.4.0"},"@timestamp":"2023-06-04T22:20:32.081+00:00","message":"Server log: Monitor (Nombre del monitor XXX) with url https://api.miempresa.com/api/clientes has recovered with status Up","log":{"level":"INFO","logger":"plugins.actions.server-log"},"process":{"pid":543029},"trace":{"id":"4c78054535a5a5fa47375001a7c3a01d"},"transaction":{"id":"ca3102c7e809fce5"}}

Ahora creamos el archivo .swatchdogrc:

vi /root/.swatchdogrc

/root/scripts/swatchdog-notify.sh
watchfor /Server log/
exec /root/scripts/swatchdog-notify.sh '$_'

Creamos el archivo swatchdog-notify.sh

#!/bin/bash
echo $1 > message.txt
mensaje=$(jq ".message" message.txt)
if [[ $(echo "$mensaje" | grep -i "Monitor") ]]; then
    if [[ $(echo "$mensaje" | grep -i "Up") ]]; then
       monitor=$(echo "$mensaje" | grep -oP '\((.*?)\)' | head -1 | tr -d '()')
       CONTENT=$(sed -e 's/{{monitor}}/'"$monitor"'/g' -e 's|{{status}}|'"$mensaje"'|g' -e 's/{{mensaje}}/DISPONIBLE/g'  -e 's/{{color}}/green/g' -e 's/{{color2}}/green/g' /opt/elastic/template/template_email_alert.html)
       mail -a "Content-Type: text/html"  -s "Alerta - Monitoreo $monitor" -a "From: alerts_elastic@midomain.com" $(cat /opt/elastic/notificacion/list_emails_alerts.txt) <<< $CONTENT
       /opt/elastic/scripts/script_enviar_sms.sh "$monitor" "DISPONIBLE"
       echo "Correo enviado correctamente STATUS ..."
    else
       monitor=$(echo "$mensaje" | grep -oP '\((.*?)\)' | head -1 | tr -d '()')
       CONTENT=$(sed -e 's/{{monitor}}/'"$monitor"'/g' -e 's|{{status}}|'"$mensaje"'|g' -e 's/{{mensaje}}/NO DISPONIBLE/g'  -e 's/{{color}}/red/g' -e 's/{{color2}}/red/g'  /opt/elastic/template/template_email_alert.html)
       mail -a "Content-Type: text/html"  -s "Alerta - Monitoreo $monitor" -a "From: alerts_elastic@midomain.com"  $(cat /opt/elastic/notificacion/list_emails_alerts.txt) <<< $CONTENT
       /opt/elastic/scripts/script_enviar_sms.sh "$monitor" "NO DISPONIBLE"
       echo "Correo enviado correctamente ERROR ..."
    fi
else
     echo "No tiene formato de monitoreao elastic"
fi


El script del código anterior, realiza una extracción de ciertos campos de la alerta del log y envía un correo mediante mailutils, además ejecuta otro script para enviar mensaje de texto con el asunto de la notificación, para el envio de correo utiliza una plantilla en formato html y una lista .txt en el cual se apilan los correos.

Este script se ejecutará cada vez que se genere una alerta, el cual es muy util para notificar a los encargados cuando unos de los monitores registrados mediante heartbeat falle o tengo algún error.

Ahora lo que se necesita es crear el servicio de swatch:

[Unit]
Description=Swatchdog Service
After=network.target
[Service]
Type=forking
User=root
ExecStart=/usr/bin/swatchdog --daemon -c /root/.swatchdogrc -t '/var/log/kibana/kibana.log'
[Install]
WantedBy=multi-user.target

Iniciamos el servicio:

systemctl start swatch

Al ser un servicio, swatch detectará cambios en el log y ejecutará el script de la configuración y podremos enviar notificaciones a correos y otros servicios según nuestras necesidades.





El código completo y funcional lo pueden encontrar en el repositorio de GitHub

Migración Excel a FireStore


 

Una forma de gestionar los datos de forma práctica en el Firebase es haciendo uso de FireStore, pero a diferencia de RealTime Database, no tiene opciones para importar o exportar, esas operaciones deben realizarse desde otras herramientas.


Justamente por ello vamos hacer una implementación que nos permita sincronizar nuestros registros, pero forma mas familiar haciendo uso de un archivo Excel.


El proceso de reduce a modificar el archivo Excel (agregar, actualizar o quitar) y automaticamente nuestra base de datos en Firebase FireStore se sincronizará en función a los datos que dispone nuestro archivo.

Para ellos haremos uso de GitLab-CI, datos que nos facilita la integración continua y despliegue continua a cualquier ambiente destino. 


Para ello debemos ejecutar los siguientes pasos:

1. Configuración web del proyecto en Firebase

Configuramos Firebase para proyectos web.


Le asignamos un nombre al proyecto


Copiamos la configuración y pegamos en el archivo "config/config.js"



2. Cuentas de servicio en Firebase

Nos movemos a cuentas de servicio del proyecto y seleccionamos NODE.


Posteriormente hacemos click en generar nuestra clave privada y nos descargará un archivo .json, renombramos al archivo y colocamos en la carpeta "config/serviceAccount.json" del proyecto.


3. Desarrollo

Creamos 2 archivos "readExcel.js" y "import.js" en la carpeta "main" con el siguiente contenido.

readExcel.js

var fs = require('fs');
const xlsxFile = require('read-excel-file/node');

xlsxFile('./DATABASE.xlsx', { sheet: 'PERSONAS' }).then((rows) => {
const header = rows[0];
var data=[];
for (let index = 1; index < rows.length; index++) {
var item={};
const element = rows[index];
for (cel in element) {
if(element[cel]!=null){
item[header[cel]]=element[cel];
}
}
data.push(item);
}
fs.writeFile('./data/personas.json', JSON.stringify({"personas":data}), 'utf8',callback);
})

function callback(){
console.log("operation end");
}

 import.js

// Imports
const firestoreService = require('firestore-export-import');
const firebaseConfig = require('../config/config');
const serviceAccount = require('../config/serviceAccount.json');

// JSON To Firestore
const jsonToFirestore = async () => {
try {
console.log('Initialzing Firebase');
await firestoreService.initializeApp(serviceAccount, firebaseConfig.databaseURL);
console.log('Firebase Initialized');

await firestoreService.restore('./data/personas.json');
console.log('Upload Success');
}
catch (error) {
console.log(error);
}
};

jsonToFirestore();

4. Ejecución

Para instalar las dependencias, ejecutar "npm install" en el proyecto y tendremos listo para comenzar con la ejecución.

nos movemos al proyecto y ejecutamos  "node main/readExcel.js" y posteriormente "node main/import.js".

Una vez ejecutado se podrá ver la siguiente salida.



Si nos vamos a Cloud FireStore podemos ver.



De esa forma nos olvidamos de estar actualizando manualmente nuestros datos en firestore.

5. Automatización

Al actualizar su repositorio con las credenciales y hacer commit, se ejecutará el job que se encargado de generar el archivo JSON y desplegar el Firestore.




La fuente del proyecto lo pueden descargar en GitLab



09/01/2021

Login con Flutter y Auth0



En este Post vamos a integrar una App Flutter con Auth0, para ello tenemos que hacer una serie de pasos que explicaré a continuación.





1. Crear una cuenta en auth0.com

Auth0 nos permite gestionar hasta 7000 usuarios en el plan free sin requerir asociar tarjeta alguna, es una buena opción si queremos integrar un componente de login de manera práctica,

Seleccionar el tenant a configurar.

2. Configurar una base de datos

Crear una nueva base de datos para almacenar  nuestros usuarios, o simplemente usar la que nos crea por defecto.





3. Crear una aplicacion

Crear la aplicación tipo Native, según la imagen que se muestra a continuación.


  Agregar el siguiente código para habilitar la autenticación desde la app
4. Instalar dependencias en Flutter

Instalar las siguientes dependencias.



5. Configurar Gradle



6. Configurar variables



7. Ejecutar

Si revisamos los usuarios en Auth0.



El código fuente lo pueden descargar desde Github





09/11/2020

Descarga Videos de Microsoft Teams


 

A veces tenemos la necesidad de descargar videos de cursos o reuniones donde no somos el anfitrión y no nos han habilitado la opción de descargar en Microsoft Teams, Microsoft Teams guarda sus medios en su repositorio Microsoft Streams.

Para poder hacer esta acción necesitamos instalar algunas dependencias.

1. Se requiere Windows o Linux (pero con interface de usuario)

2. Node JS. 10.x y "ffmpeg"

 https://nodejs.org/en/download/

 https://www.ffmpeg.org/download.html

2. Tener el usuario y contraseña que tenga acceso a reproducir los videos de Microsoft Teams.






3. Click derecho en el video copiamos la URL.






Debemos copiar la URL de los videos que necesitamos descargar en un archivo .txt

Ejemplo:
 


4. Descargar el proyecto "destreamer" desde github.
 
git clone https://github.com/snobu/destreamer.git




5. Instalar las dependencias del proyecto.

Ejecutar: 

    cd destreamer

    npm install

   npm run buld

6. Ejecutar el archivo "destreamer.cmd" en Windows y "destreamer.sh" en Linux.

 destreamer.cmd -u micorreo@empresaperu.com --skip --format mp4 --outputDirectory carpeta_videos -f archivos-url.txt

Para mas opciones de configuración lo pueden ver en la página GitHub del proyecto

Ejecutamos y esperamos unos segundos.


Se iniciará un navegador solicitando las credencial de Microsoft Teams.


 Aceptamos la opción de mantener la sesión.


 

Completar las credenciales y se serrará automáticamente y comenzará a descargar los videos del archivo .txt.

Esta vista se generará por cada video y podremos ver el porcentaje de la descarga de cada video.




Una vez descargado podemos ver en la carpeta "carpeta_videos".

Nos vemos pronto.