jueves, 29 de diciembre de 2022

[eBook] Add Security to Your Amazon EKS with NGINX

 

EBOOK

[eBook] Add Security to Your Amazon EKS with NGINX

Hi Emanuel,

Keeping applications secure can be one of the most daunting—and critical—challenges for any enterprise to figure out. Attempts to breach security happen thousands of times a day. The speed at which applications are now developed comes with a challenge: how can you keep up with the need to check apps when developers outnumber security pros 500:1?

Discover how you can prevent security breaches with NGINX and AWS. Learn how to protect your apps in an Amazon Elastic Kubernetes Service (Amazon EKS) deployment from a range of threats, including the OWASP Top 10 and beyond.

In this eBook you will learn:

  • Five ways NGINX Plus can help your organization mitigate vulnerabilities faster and easier 
  • How NGINX App Protect easily integrates with the NGINX Ingress Controller to secure your Kubernetes apps at scale
  • Why moving a WAF closer to the modern apps it protects can prevent a security breach

miércoles, 28 de diciembre de 2022

Resty, un cliente rest simple para Golang

 


Resty, es un cliente simple para consultar Apis http. Tiene muchas características :

  • Todos los métodos http: GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS, etc.
  • Métodos simples y encadenables para configuraciones y solicitudes.
  • El cuerpo de la solicitud puede ser una cadena, [] byte, estructura, mapa, segmento e io.Reader también detecta automáticamente el tipo de contenido
  • Procesamiento sin búfer para io.Reader
  • Se puede acceder a la instancia *http.Request nativa durante la ejecución del middleware y la solicitud a través de Request.RawRequest
  • El cuerpo de la solicitud se puede leer varias veces a través de Request.RawRequest.GetBody()
  • Acceso como matriz de []bytes - respuesta.Cuerpo() O Acceso como cadena - respuesta.Cadena()
  • Clasificación y desclasificación automáticas para el tipo de contenido JSON y XML
  • El valor predeterminado es JSON, si proporciona estructura/mapa sin encabezado Content-Type
  • Compatible con RFC7807: application/problem+json & application/problem+xml
  • Resty proporciona una opción para anular JSON Marshal/Unmarshal y XML Marshal/Unmarshal
  • Fácil de cargar uno o más archivos a través de multipart/form-data
  • Detecta automáticamente el tipo de contenido del archivo
  • Solicitud de parámetros de ruta de URL (también conocidos como parámetros de URI)
  • Mecanismo de reintento de retroceso con referencia de función de condición de reintento
  • Middleware de solicitud y respuesta HTTP y REST del cliente Resty
  • Solicitud.SetContext compatible
  • Opción de autorización de BasicAuth y Bearer token
  • Establecer el valor de ContentLength de solicitud para todas las solicitudes o solicitudes en particular
  • Certificados raíz personalizados y certificados de cliente
  • Descargue/guarde la respuesta HTTP directamente en el archivo, como el indicador curl -o. Consulte SetOutputDirectory y SetOutput.
  • Cookies para su solicitud y soporte de CookieJar
  • Solicitud basada en registro SRV en lugar de URL de host
  • Configuración del cliente como Tiempo de espera, RedirectPolicy, Proxy, TLSClientConfig, Transporte, etc.
  • Opcionalmente, permite la solicitud GET con carga útil
  • Admite el registro de la biblioteca JSON externa en Resty
  • Expone el lector de respuestas sin leer la respuesta (sin desarme automático) si es necesario
  • Opción para especificar el tipo de contenido esperado cuando falta el encabezado del tipo de contenido de respuesta. 
  • Admite la implementación de http.RoundTripper
  • seguridad concurrente con goroutine
  • Seguimiento podemos usar Client.EnableTrace y Request.EnableTrace
  • Desde v2.4.0, la información de seguimiento contiene un valor de RequestAttempt y el objeto Request contiene un atributo de intento.
  • Modo de depuración
  • Funciona con HTTP/2 y HTTP/1.1
Puf un monton y si llegaste hasta aca leyendo, te felicito. Ahora vamos a ver un ejemplo, imprimir datos de la api de github : 

package main

import (
"bufio"
"fmt"
"github.com/go-resty/resty/v2"
"os"
"strings"
)

func main() {
fmt.Println("Ingrese el usuario de github : ")

reader := bufio.NewReader(os.Stdin)
user, _ := reader.ReadString('\n')
user = strings.ReplaceAll(user, "\n", "")

url := "https://api.github.com/users/" + user

// Create a Resty Client
client := resty.New()

resp, err := client.R().
EnableTrace().
Get(url)

if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("  Status Code:", resp.StatusCode())
fmt.Println("  Status     :", resp.Status())
fmt.Println("  Proto      :", resp.Proto())
fmt.Println("  Time       :", resp.Time())
fmt.Println("  Received At:", resp.ReceivedAt())
fmt.Println("  Body       :\n", resp)
fmt.Println()
// Explore trace info
fmt.Println("Request Trace Info:")
ti := resp.Request.TraceInfo()
fmt.Println("  DNSLookup     :", ti.DNSLookup)
fmt.Println("  ConnTime      :", ti.ConnTime)
fmt.Println("  TCPConnTime   :", ti.TCPConnTime)
fmt.Println("  TLSHandshake  :", ti.TLSHandshake)
fmt.Println("  ServerTime    :", ti.ServerTime)
fmt.Println("  ResponseTime  :", ti.ResponseTime)
fmt.Println("  TotalTime     :", ti.TotalTime)
fmt.Println("  IsConnReused  :", ti.IsConnReused)
fmt.Println("  IsConnWasIdle :", ti.IsConnWasIdle)
fmt.Println("  ConnIdleTime  :", ti.ConnIdleTime)
fmt.Println("  RequestAttempt:", ti.RequestAttempt)
fmt.Println("  RemoteAddr    :", ti.RemoteAddr.String())
}

}

Y si ingresamos emanuelpeg por ejemplo obtendremos : 

Ingrese el usuario de github : 

emanuelpeg

  Status Code: 200

  Status     : 200 OK

  Proto      : HTTP/2.0

  Time       : 365.365001ms

  Received At: 2022-12-28 16:25:37.481908946 -0300 -03 m=+9.137266439

  Body       :

 {"login":"emanuelpeg","id":1281319,"node_id":"MDQ6VXNlcjEyODEzMTk=","avatar_url":"https://avatars.githubusercontent.com/u/1281319?v=4","gravatar_id":"","url":"https://api.github.com/users/emanuelpeg","html_url":"https://github.com/emanuelpeg","followers_url":"https://api.github.com/users/emanuelpeg/followers","following_url":"https://api.github.com/users/emanuelpeg/following{/other_user}","gists_url":"https://api.github.com/users/emanuelpeg/gists{/gist_id}","starred_url":"https://api.github.com/users/emanuelpeg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emanuelpeg/subscriptions","organizations_url":"https://api.github.com/users/emanuelpeg/orgs","repos_url":"https://api.github.com/users/emanuelpeg/repos","events_url":"https://api.github.com/users/emanuelpeg/events{/privacy}","received_events_url":"https://api.github.com/users/emanuelpeg/received_events","type":"User","site_admin":false,"name":"Emanuel","company":"assembly","blog":"http://emanuelpeg.blogspot.com/","location":"Crespo","email":null,"hireable":null,"bio":null,"twitter_username":null,"public_repos":51,"public_gists":19,"followers":15,"following":9,"created_at":"2011-12-23T03:12:26Z","updated_at":"2022-12-12T19:06:19Z"}


Request Trace Info:

  DNSLookup     : 33.874537ms

  ConnTime      : 165.492638ms

  TCPConnTime   : 48.333281ms

  TLSHandshake  : 83.032505ms

  ServerTime    : 199.757211ms

  ResponseTime  : 274.029µs

  TotalTime     : 365.365001ms

  IsConnReused  : false

  IsConnWasIdle : false

  ConnIdleTime  : 0s

  RequestAttempt: 1

  RemoteAddr    : 20.201.28.148:443


Process finished with the exit code 0


Y Listo!! 


martes, 27 de diciembre de 2022

Foldable y Traverse parte 3

 Foldable define foldRight de manera diferente a foldLeft, en términos de la mónada Eval:


def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B]


El uso de Eval significa que el plegado siempre es seguro para la pila, incluso cuando la definición predeterminada de foldRight de la colección no lo es. Por ejemplo, la implementación predeterminada de foldRight para LazyList no es segura a nivel de pila. Cuanto más larga sea la lista perezosa, mayores serán los requisitos de pila para el pliegue. Una lista perezosa lo suficientemente grande provocará un StackOverflowError:


import cats.Eval

import cats.Foldable

def bigData = (1 to 100000).to(LazyList)

bigData.foldRight(0L)(_ + _)

// java.lang.StackOverflowError ...


El uso de Foldable nos obliga a usar operaciones seguras de pila, lo que corrige la excepción de desbordamiento:


import cats.instances.lazyList._ // for Foldable

val eval: Eval[Long] =

    Foldable[LazyList].

        foldRight(bigData, Eval.now(0L)) { (num, eval) =>

            eval.map(_ + num)

        }

eval.value

// res3: Long = 5000050000L


Foldable nos proporciona una gran cantidad de métodos útiles definidos en la parte superior de foldLeft. Muchos de estos son facsímiles de métodos familiares de la biblioteca estándar: find, exist, forall, toList, isEmpty, nonEmpty, etc.

Además de estos métodos familiares, Cats proporciona dos métodos que hacen uso de Monoids:

  • combineAll (y su alias fold) combina todos los elementos en la secuencia usando su Monoid;
  • foldMap mapea una función proporcionada por el usuario sobre la secuencia y combina los resultados usando un Monoid.

Por ejemplo, podemos usar combineAll para sumar sobre List[Int]:


import cats.instances.int._ // for Monoid

Foldable[List].combineAll(List(1, 2, 3))

// res8: Int = 6


Alternativamente, podemos usar foldMap para convertir cada Int en un String y concatenarlos:


import cats.instances.string._ // for Monoid

Foldable[List].foldMap(List(1, 2, 3))(_.toString)

// res9: String = "123"


Finalmente, podemos componer Foldables para admitir un recorrido profundo de secuencias anidadas:


import cats.instances.vector._ // for Monoid

val ints = List(Vector(1, 2, 3), Vector(4, 5, 6))

(Foldable[List] compose Foldable[Vector]).combineAll(ints)

// res11: Int = 21


lunes, 26 de diciembre de 2022

Foldable y Traverse parte 2

Foldable en cats es un type class que contiene el método foldLeft y foldRight. Las instancias de Foldable definen estos dos métodos y heredan una serie de métodos derivados. Cats proporciona instancias listas para usar de Foldable para un puñado de tipos de datos de Scala: List, Vector, LazyList y Option.

Podemos invocar instancias como de costumbre usando Foldable.apply y llamar directamente a sus implementaciones de foldLeft. Aquí hay un ejemplo usando List:


import cats.Foldable

import cats.instances.list._ // for Foldable

val ints = List(1, 2, 3)

Foldable[List].foldLeft(ints, 0)(_ + _)

// res0: Int = 6


Otras secuencias como Vector y LazyList funcionan de la misma manera. Aquí hay un ejemplo usando Option, que se trata como una secuencia de cero o uno elementos:


import cats.instances.option._ // for Foldable

val maybeInt = Option(123)

Foldable[Option].foldLeft(maybeInt, 10)(_ * _)

// res1: Int = 1230



sábado, 24 de diciembre de 2022

Obtener un tipo desde un string en C#


Post cortito, necesitaba por X motivo obtener un tipo desde un string y esto es tan fácil como hacer 


var myType  = Type.GetType(string);


Y luego con el tipo podes utilizar reflexión para saber si tiene constructores, si es una clase, etc. 


Dejo link : https://learn.microsoft.com/en-us/dotnet/api/system.type.gettype?view=net-7.0

martes, 20 de diciembre de 2022

Foldable y Traverse

La clase de tipo Foldable captura los métodos foldLeft y foldRight a los que estamos acostumbrados en secuencias como Lists, Vectors, y Streams. Usando Foldable, podemos escribir pliegues genéricos que funcionan con una variedad de tipos de secuencias. También podemos inventar nuevas secuencias y conectarlas a nuestro código.

Foldable nos brinda excelentes casos de uso para Monoids y la mónada Eval.

Comencemos con un resumen rápido del concepto general de plegado. Suministramos un valor acumulador y una función binaria para combinarlo con cada elemento de la secuencia:


def show[A](list: List[A]): String =

    list.foldLeft("nil")((accum, item) => s"$item then $accum")

show(Nil)

// res0: String = "nil"

show(List(1, 2, 3))

// res1: String = "3 then 2 then 1 then nil"


El método foldLeft funciona recursivamente en la secuencia. Nuestra función binaria se llama repetidamente para cada elemento, y el resultado de cada llamada se convierte en el acumulador de la siguiente. Cuando llegamos al final de la secuencia, el acumulador final se convierte en nuestro resultado final.

Dependiendo de la operación que estemos realizando, el orden en el que plegamos puede ser importante. Debido a esto, hay dos variantes estándar de pliegue:

  • foldLeft atraviesa de "izquierda" a "derecha" (de principio a fin);
  • foldRight atraviesa de "derecha" a "izquierda" (de fin a principio).

foldLeft y foldRight son equivalentes si nuestra operación binaria es asociativa.

Por ejemplo, podemos sumar List[Int] doblando en cualquier dirección, usando 0 como nuestro acumulador y la suma como nuestra operación pero no podemos hacer lo mismo con la resta :


List(1, 2, 3).foldLeft(0)(_ - _)

// res4: Int = -6

List(1, 2, 3).foldRight(0)(_ - _)

// res5: Int = 2




viernes, 16 de diciembre de 2022

Juego de Serie en Go


Cuando quiero aprender un nuevo lenguaje desarrollo un juego de series, es decir aparece una serie con un valor faltante y el jugador debe completarlo.

Uno de los requerimientos no funcionales es que se pueda agregar una serie nueva fácilmente, para cumplirlo vamos a utilizar las ventajas de go.

Empecemos desarrollo de la serie, la serie tiene como responsabilidad generarse :

func IniciarSecuencia() [4]int {

rand.Seed(time.Now().Unix())

semilla := rand.Intn(3)

switch semilla {

case 0:

return generarSecuenciaPar()

case 1:

return generarSecuenciaInpar()

default:

return generarFibonacci()

}

}

Esta función genera la serie y para eso utiliza diferentes funciones que generan diferentes tipos de secuencias : 

import (
"math/rand"
"time"
)

func generarSecuenciaPar() [4]int {
var resultado [4]int
rand.Seed(time.Now().Unix())
semilla := rand.Intn(100)
for i := 0; i < 4; i++ {
resultado[i] = semilla + i*2
}
return resultado
}

func generarSecuenciaInpar() [4]int {
var resultado [4]int
rand.Seed(time.Now().Unix())
semilla := rand.Intn(100)
for i := 0; i < 4; i++ {
resultado[i] = semilla + i*2 + 1
}
return resultado
}

func generarFibonacci() [4]int {
var resultado [4]int
rand.Seed(time.Now().Unix())
semilla := rand.Intn(50)
for i := 0; i < 4; i++ {
if i < 2 {
resultado[i] = semilla
} else {
resultado[i] = resultado[i-1] + resultado[i-2]
}
}
return resultado
}

Y listo!! ahora en el main tenemos que llamar a esta función y ver si esta bien el resultado: 

package main

import (
"example/secuencia/secuencia/model"
"fmt"
"os"
)

func main() {

fmt.Println("------------- Bienvenido !! ----------------")

exit := 'Y'
puntaje := 0

for exit != 'N' {
secuencia := model.IniciarSecuencia()
for i := 0; i < len(secuencia); i++ {
if i != 2 {
fmt.Print(secuencia[i])
fmt.Print(" ")
} else {
fmt.Print("________  ")
}
}

fmt.Println()
fmt.Println("--------------------------")
fmt.Print(" Faltante :")

var nro int

n, err := fmt.Scanf("%d\n", &nro)
if err != nil {
fmt.Println(n, err)
os.Exit(n)
}

if nro == secuencia[2] {
fmt.Print(" Ganaste!! ")
puntaje++
} else {
fmt.Print(" Perdiste!! ")
puntaje--
}
fmt.Println(" Puntaje : ", puntaje)
fmt.Print(" Desea continuar jugando ? (Y/N) ")
fmt.Scanf("%c\n", &exit)
}

}

Y eso es todo a jugar se a dicho!!




jueves, 15 de diciembre de 2022

[eBook] Secure, Scale, and Monitor Kubernetes with AWS and F5 NGINX

 

EBOOK

[eBook] Secure, Scale, and Monitor Kubernetes with AWS and F5 NGINX

Hi Emanuel,

In this eBook, discover how F5 NGINX, available in the AWS Marketplace, complements Amazon EKS with advanced networking and security solutions for Kubernetes that are platform agnostic, enable production-grade Kubernetes at scale, and effortlessly handle traffic spikes and security threats without compromising on performance.

In this eBook you will learn:

  • The three main components needed to make Kubernetes production grade
  • Why Kubernetes clusters require “fine-grained” security inside the cluster and three locations where you may need to deploy a WAF
  • How platform-agnostic tools reduce complexity and improve security to create a unified “single pane of glass” view of your infrastructure
  • How NGINX Kubernetes solutions enable automation, security, performance, and insights for easy Kubernetes scalability on Amazon EKS

martes, 13 de diciembre de 2022

Semigroupal, Parallel y Applicative parte 8


Con la introducción de Apply y Applicative, podemos alejarnos y ver toda una familia de clases de tipos que se ocupan de secuenciar cálculos de diferentes maneras. 

Cada clase de tipo en la jerarquía representa un conjunto particular de semántica de secuenciación, presenta un conjunto de métodos característicos y define la funcionalidad de sus supertipos en términos de ellos:

  • toda mónada es un aplicativo;
  • cada aplicativo un semigrupal;
  • y así.

Debido a la naturaleza de las relaciones entre las type class, las relaciones de herencia son constantes en todas las instancias.

Apply define product en términos de ap y map; Monad define product, ap y map, en términos de  pure y flatMap.

Para ilustrar esto, consideremos dos tipos de datos hipotéticos:

• Foo es una mónada. Tiene una instancia de la type class Monad que implementa pure y flatMap y hereda definiciones estándar de product, map y ap;

• Bar es un funtor aplicativo. Tiene una instancia de Applicative que implementa pure y ap y hereda definiciones estándar de product y map.

¿Qué podemos decir sobre estos dos tipos de datos sin saber más sobre su implementación?

Sabemos estrictamente más sobre Foo que sobre Bar: Monad es un subtipo de Applicative, por lo que podemos garantizar propiedades de Foo (a saber, flatMap) que no podemos garantizar con Bar. Por el contrario, sabemos que Bar puede tener una gama más amplia de comportamientos que Foo. Tiene menos leyes que obedecer (sin flatMap), por lo que puede implementar comportamientos que Foo no puede.

Esto demuestra el clásico intercambio de poder (en el sentido matemático) versus restricción. Cuantas más restricciones imponemos a un tipo de datos, más garantías tenemos sobre su comportamiento, pero menos comportamientos podemos modelar.

Las mónadas resultan ser un punto dulce en esta compensación. Son lo suficientemente flexibles para modelar una amplia gama de comportamientos y lo suficientemente restrictivos para dar garantías sólidas sobre esos comportamientos. Sin embargo, hay situaciones en las que las mónadas no son la herramienta adecuada para el trabajo. A veces queremos comida tailandesa y los burritos simplemente no satisfacen.

Mientras que las mónadas imponen una secuencia estricta en los cálculos que modelan, los aplicativos y los semigrupos no imponen tal restricción. Esto los coloca en un punto dulce diferente en la jerarquía. Podemos usarlos para representar clases de cálculos paralelos/independientes que las mónadas no pueden.

Elegimos nuestra semántica eligiendo nuestras estructuras de datos. Si elegimos una mónada, obtenemos una secuencia estricta. Si elegimos un aplicativo, perdemos la capacidad de flatMap. Esta es la compensación impuesta por las leyes de consistencia. ¡Así que elige tus tipos con cuidado!

Si bien las mónadas y los funtores son los tipos de datos de secuenciación más utilizados, los semigrupos y los aplicativos son los más generales.

Estas clases de tipos proporcionan un mecanismo genérico para combinar valores y aplicar funciones dentro de un contexto, a partir del cual podemos crear mónadas y una variedad de otros combinadores.

Semigroupal y Applicative se usan más comúnmente como un medio para combinar valores independientes, como los resultados de las reglas de validación. Cats proporciona el tipo Validated para este propósito específico, junto con la sintaxis de aplicación como una forma conveniente de expresar la combinación de reglas.

lunes, 12 de diciembre de 2022

Semigroupal, Parallel y Applicative parte 7

Los semigrupos no se mencionan con frecuencia en la literatura más amplia de programación funcional. Proporcionan un subconjunto de la funcionalidad de un type class relacionada llamada funtor aplicativo ("aplicativo" para abreviar).

Semigroupal y Applicative proporcionan codificaciones alternativas de la misma noción de unir contextos. Ambas codificaciones se presentan en el mismo artículo de 2008 de Conor McBride y Ross Paterson.

Cats modela applicatives usando dos type classes. El primero, cats.Apply, extiende Semigroupal y Functor y agrega un método ap que aplica un parámetro a una función dentro de un contexto. El segundo, cats.Applicative, extiende Apply y agrega el método  pure. Aquí hay una definición simplificada en el código:


trait Apply[F[_]] extends Semigroupal[F] with Functor[F] {

    def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]

    def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] =

         ap(map(fa)(a => (b: B) => (a, b)))(fb)

}

trait Applicative[F[_]] extends Apply[F] { 

     def pure[A](a: A): F[A]

}

Desglosando esto, el método ap aplica un parámetro fa a una función ff dentro de un contexto F[_]. El método product de Semigroupal se define en términos de ap y map.

No se preocupe demasiado por la implementación de product: es difícil de leer y los detalles no son particularmente importantes. El punto principal es que existe una estrecha relación entre product, ap y map que permite definir cualquiera de ellos en términos de los otros dos.

El Applicative también introduce el método pure. Este es el mismo pure que vimos en Monad. Construye una nueva instancia de aplicación a partir de un valor no encapsulado. En este sentido, Applicative está relacionado con Apply como Monoid está relacionado con Semigroup.



viernes, 9 de diciembre de 2022

Forrester: Ahorros y beneficios de Google Kubernetes Engine para las empresas