Python 521
Python 521
Python 521
www.4linux.com.br
Sumário
1 API 2
SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
API REST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Endpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Verbo ou Método . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 cURL 5
Instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Utilização . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3 Postman 7
Instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Utilização . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
5 Docker 19
Contêineres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Máquinas Virtuais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
VM vs Contêiner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Debian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
CentOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Testando a instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Primeiros Passos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Listagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Imagens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Iniciando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Detalhes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Limpeza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Imagens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Camadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1
Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Criando Aplicações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Portas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Variáveis de ambiente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Volumes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Logs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Dockerfile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Exercício . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Registry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Exercício . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
6 Docker API 32
Unix Socket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Listagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Exercício . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Criação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Exercício . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
7 Git 36
História . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Clientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Utilizando o Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Criando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Clonando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Gravando Alterações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Verificando Alterações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Subir alterações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Baixar alterações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Conflitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Trocando de branch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Merge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Pull . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
8 Gerenciadores do Git 40
GitLab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Gogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
9 Jenkins 41
História . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
10 Preparação 42
Gitlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Jenkins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
11 Flask 44
Aplicação Simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Blueprints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
12 Jinja 46
Básico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Variáveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Filtros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
2
Blocos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Condições . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Repetições . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
13 LDAP 49
Mas e o banco? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
OpenLDAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Buscar Entradas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Adicionar Usuário . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Apache Directory Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
ldap3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
14 Apache 53
Copiar aplicação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Criar WSGI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Configuração do Site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
15 Logs 54
logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
16 Paramiko 56
Instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
17 AWS 58
EC2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
awscli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
boto3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3
Capítulo 1
API
SOAP
SOAP - Simple Object Access Protocol - ou em português, protocolo simples de objeto de acesso é um protocolo que de simples
possui apenas a nomenclatura. O SOAP foi o padrão de comunicação utilizado a algum tempo atrás. Suas mensagens são
trocadas através de XML.
É importante lembrar que o SOAP não é apenas uma definição de troca de mensagens, mas toda a implementação de um
protocolo - diferente do HTTP. O SOAP implementa por exemplo mais segurança, verificação de identidade através de
terceiros, tentativa de reconexão em casos de falha e transações ACID.
Devido a grande maioria das implementações do SOAP utilizar apenas o RPC - Remote Procedure Call - e a relativa
complexidade para pequenas aplicações, o padrão de API REST foi adotado.
XML
1 <?xml version ="1.0" encoding="UTF -8" ?>
2 <root >
3 <id>1</id>
4 <nome >Guido van Rossum </nome >
5 <projetos >
6 <nome >Python </nome >
7 <ano>1989 </ano>
8 </projetos >
9 <projetos >
10 <nome >Computer Programming for Everybody </nome >
11 <ano>1999 </ano>
12 </projetos >
13 <projetos >
14 <nome >Dropbox </nome >
15 <ano>2013 </ano>
16 </projetos >
17 </root >
4
API REST
API REST - Representational State Transfer - é um tipo de API que utiliza endpoints, verbos e status para definir sua
utilização e respostas. APIs REST são largamente utilizadas para comunicação entre diferentes serviços devido sua
natureza genérica.
Geralmente são mais leves pois na maioria das vezes transportam apenas texto em formato JSON, suportam cache e é
relativamente mais fácil de entender.
Muitos serviços possúem APIs REST, como os correios, a wikipedia o imdb e etc. Como a troca de mensagens entre APIs
REST ocorre em formato de texto puro, praticamente qualquer ferramente capaz de fazer uma chamada HTTP pode ser
utilizada para consumir a API, como por exemplo o o comando curl ou o wget.
As linguagens de programação como Python, Perl, PHP, Java, Go e praticamente qualquer outra também podem consultar
APIs REST.
Não se assuste! As APIs REST funcionam de forma muito similar ao que já fazemos em nossos navegadores no dia a dia.
Consultamos URLs, enviamos formulários e etc.
Endpoint
Um endpoint nada mais é do que um endereço de acesso, uma rota. Por exemplo, se tivéssemos um site com o endereço
www.python.example.com e no seguinte endereço www.python.example.com/version obtivéssemos uma resposta
indicando a versão da linguagem, nosso endpoint seria /version.
Podemos fazer uma analogia como o endereço em que um determinado formulário é enviado, por exemplo, ao clicar no
botão de login.
Verbo ou Método
O verbo indica o tipo de ação que pretendemos realizar ao utilizar uma determinada rota. É mais comum encontrarmos a
palávra método em relação a verbo, portanto utilizaremos a palavra método daqui em diante. Existem muitos métodos, mas
os os principais são:
• GET - consulta
• POST - cadastra
• PUT - atualiza
• DELETE - remove
Obs: Os métodos existentes no HTTP 1.0 eram apenas o GET e o POST, porém com a atualização do HTTP para 1.1 dezenas
de outros, incluindo os citados aqui, passaram a existir.
GET
O GET é o mais simples dos métodos, ele realiza uma consulta em um determinado endpoint. Um bom exemplo de um
método GET é o simples acesso a qualquer site.
POST
O POST é o método utilizado quando queremos gravar algo em algum sistema. Por exemplo ao preencher algum formulário
de cadastro de produto ou de identidade em algum site. Os formulários de login - embora não cadastrem o usuário - são
implementados como POST.
PUT
O método PUT é utilizado quando desejamos atualizar algo dentro do sistema, este método já pertence ao HTTP 1.1. Existe
um segundo método chamado PATCH que difere um pouco em relação ao PUT. O PATCH, por convenção, atualiza um
pedaço do recurso em questão, já o PUT atualiza por completo. Não é muito comum encontrar métodos PATCH por aí,
neste caso, por questões de simplicidade, utilizaremos apenas o PUT.
5
DELETE
O DELETE fala por sí só, o utilizamos quando queremos apagar algum recurso no sistema.
Status
O Status é o código que a resposta da chamada retorna. É o status enviado pelo servidor indicando o sucesso, a falha ou
qualquer outra mensagem descrita no protocolo HTTP. Os mais conhecidos são:
• 200 - Tudo Certo
• 201 - Criado
• 301 - Movido Permanentemente
• 302 - Encontrado
• 400 - Requisição Ruim
• 401 - Não Autorizado
• 403 - Proibido
• 404 - Não Encontrado
• 500 - Erro interno
OBS: Apesar do status 401 referir-se a autorização seu verdadeiro uso está nos processos de autenticação, para
autorização utilizamos o status 403.
As mensagems são divididas nos seguintes limites:
• 1xx - Informacional
• 2xx - Sucesso
• 3xx - Redirecionamento
• 4xx - Erro do Cliente
• 5xx - Erro no Servidor
Isso significa que precisamos estar atentos ao status retornado por nossas requisições e tratar as diferentes respostas em
nosso código.
É importante ressaltar que tudo isso é apenas uma convenção, mensagens podem vir em qualquer formato com qualquer
tipo de resposta. Cabe a nós, ao criarmos nossas APIs a respeitar esse padrão e facilitar a utilização por terceiros.
JSON
JSON - JavaSscript Object Notation - é um formato de transporte de dados criado por Douglas Crockford. Seu formato
lembra muito o dicionário do Python, exceto que para definir chaves e valores apenas a aspa - e não o apóstrofo - é permitida.
1 {
2 "id": 1,
3 "nome ": "Guido van Rossum",
4 "projetos ": [
5 {" nome" : "Python", "ano" : 1989} ,
6 {" nome" : "Computer Programming for Everybody", "ano" : 1999} ,
7 {" nome" : "Dropbox", "ano" : 2013}
8 ]
9 }
Obs: Você pode consultar um pouco mais sobre o JSON e seu formato em https://www.json.org/.
6
Capítulo 2
cURL
Conforme foi explicado, APIs REST podem ser consumidas com praticamente qualquer ferramenta capaz de realizar
chamadas HTTP. Existe uma ferramenta de console muito conhecida chamada cURL, apesar de parecer pouco atrativo, o
curl é extremamente poderoso, principalmente para a automação de requisições deste tipo.
Instalação
1 # Debian
2 apt -get install -y curl
3 # CentOS
4 yum install -y curl
Utilização
Com o cURL podemos consultar qualquer página na internet, enviar e receber dados. Dessa mesma forma podemos
consultar APIs REST. Um bom exemplo é utilizar a api https://viacep.com.br/.
1 {
2 "cep": "04101 -300" ,
3 "logradouro ": "Rua Vergueiro",
4 "complemento ": "de 2771 a 5049 - lado ímpar",
5 "bairro ": "Vila Mariana",
6 "localidade ": "São Paulo",
7 "uf": "SP",
8 "unidade ": "",
9 "ibge ": "3550308" ,
10 "gia": "1004"
7
1 <?xml version ="1.0" encoding="UTF -8"?>
2 <xmlcep >
3 <cep>04101 -300 </cep>
4 <logradouro >Rua Vergueiro </logradouro >
5 <complemento >de 2771 a 5049 - lado ímpar </complemento >
6 <bairro >Vila Mariana </bairro >
7 <localidade >São Paulo </localidade >
8 <uf>SP</uf>
9 <unidade ></unidade >
10 <ibge >3550308 </ibge >
11 <gia>1004 </gia>
12 </xmlcep >
8
Capítulo 3
Postman
O Postman é uma aplicação utilizada geralmente por pessoas de QA - Q uality Assurance - para realizar testes em rotas de
API REST. Mas é claro, podemos utilizá-lo também durante o desenvolvimento de nossas APIs.
Diferente do cURL o Postman fornece uma interface gráfica, histórico de fácil acesso e as opções disponíveis de forma
bastante intuitiva, facilitando a utilização para pessoas iniciantes.
Instalação
Baixe o Postman em https://www.getpostman.com/downloads/, extraia o conteúdo do arquivo em Downloads, entre no
diretório e execute o programa clicando duas vezes no ícone Postman.
Podemos também fazer o mesmo através do terminal:
1 cd Downloads
2 # Utilizando wget
3 wget https ://dl.pstmn.io/download/latest/linux64 -O postman.tar.gz
4 # Utilizando o cURL
5 curl -L https ://dl.pstmn.io/download/latest/linux64 > postman.tar.gz
6
7 tar -xzvf postman.tar.gz
8 cd Postman
9 ./ Postman
Utilização
O Postman é bastante amigável mas possui muitas opções. Se entendemos os conceitos de uma requisição HTTP sua
interface torna-se bastante sugestiva.
9
Figura 3.1: Tela Login
Esta tela aparece na primeira vez que iniciamos o Postman. Podemos criar uma conta para guardar nossas requisições e
preferências, mas para este momento não precisamos.
1. Utilize a opção para se cadastrar com e-mail e clique na próxima opção pedindo para pular esta etapa.
10
Figura 3.3: GET
Ao adicionar uma nova requisição a tela será semelhante para qualquer tipo, com pequenas modificações. Este exemplo
utiliza um GET.
1. Aqui podemos selecionar qual o tipo de requsição queremos utilizar, neste caso um GET.
2. Este é o endereço em que faremos nossas requisições.
3. Este botão dispara a requisição.
4. Ao enviar uma requisição podemos ter acessoa a todos os detalhes nesta barra.
5. O corpo da resposta está dentro desta caixa, e pode ser visualizado de várias formas.
1. Aqui podemos selecionar qual o tipo de requsição queremos utilizar, neste caso um POST.
2. Este é o endereço em que faremos nossas requisições.
3. Como este é um POST enviaremos dados:
3.1. Clique em Body.
3.2. Selecione x-www-urlencoded.
4. Preencha os campos necessários para a requisição, neste caso precisamos de uma chave chamada text.
5. Este botão dispara a requisição.
6. Ao enviar uma requisição podemos ter acesso a todos os detalhes nesta barra.
7. O corpo da resposta está dentro desta caixa, e pode ser visualizado de várias formas.
11
Capítulo 4
Agora que aprendemos algumas formas de consultar APIs REST estamos prontos para fazer o mesmo através do Python.
Isso significa que poderemos tratar os dados de uma forma melhor e ainda fornecer uma interface para novas consultas ou
realizar consultas mais complexas.
Para facilitar a localização dos arquivos, criaremos um diretório chamado 521 no diretório do nosso usuário:
1 mkdir ~/521
Módulo Requests
O módulo padrão para requisições HTTP - e consequentemente APIs REST - utilizado pelo python chama-se requests.
Apesar de poderoso, sua utilização é bastante simples e talvez isso explique o título “HTTP for Humans” presente na página
do projeto.
Instalação
Para instalar o módulo requests com o gerenciador de pacotes na nossa máquina virtual execute o seguinte:
1 su -
2 apt -get update
3 apt -get install -y python3 -requests
Caso deseje utilizar o virtualenv precisaremos instalar o pip e o próprio pacote pelo sistema, neste caso faça o seguinte:
1 su -c 'apt -get update && apt -get install -y python3 -venv '
2 python3 -m venv 521
3 source 521/ bin/activate
4 pip install requests
Preparando Ambiente
Para testarmos outros métodos além do GET precisaremos de algo mais consistente do que uma API de consulta, e realizar
um POST no dontpad.com não nos permite enviar um JSON, apenas campos de formulário.
Para resolver este problema vamos utilizar o serviço do https://beeceptor.com. O Beeceptor nos fornece uma interface para
criar mocks - simulação - de endpoints e respostas para APIs REST.
12
Acesse o BeeCeptor e vamos criar nossos mocks!
Digite um nome que deseje utilizar para o endereço da API, neste caso escolhemos python.
Neste dashboard teremos um histórico de nossas requisições, podemos utilizar o comando curl - veja como este comando é
versátil e utilizado como exemplos nos mais diversos serviços - fornecido como exemplo.
1. Clique em Mocking Rules para criar suas regras.
13
Figura 4.3: Criar Rule
Aqui temos uma listagem de nossos endpoints, clique em Create New Rule para criar um nova rule.
14
Figura 4.5: Post Rule Criada
15
Figura 4.7: Delete Rule
Criando requisições
Vamos criar quatro arquivos, cada um será um exemplo de requisição. Podemos criar pela interface gráfica, mas por
comodidade mostraremos como se faz pelo terminal:
GET
O método GET é bastante simples, por conta disso utilizaremos o https://viacep.com.br.
get.py
16
POST
Se o endpoint foi configurado corretamente no BeeCeptor o seguinte comando do curl - ou equivalente no Postman - poderá
consumi-lo:
1 curl -X POST -d '{" nome" : "Paramahansa Yogananda "}' 'https :// python.free.beeceptor.com/usuarios ' -H
'Content -Type: application/json '
OBS: O cabeçalho enviado Content-Type: application/json não é obrigatório, mas vamos utilizá-lo pois a maioria
das APIs REST nos obriga a enviá-lo. O parâmetro -X POST pode ser omitido caso utilizemos o -d.
post.py
PUT
O PUT é muito semelhante ao POST, se o Beeceptor foi configurado corretamente, poderemos testá-lo da seguinte forma:
1 curl -X PUT -d '{" nome" : "Paramahansa Yogananda "}' 'https :// python.free.beeceptor.com/usuarios ' -H
'Content -Type: application/json '
put.py
DELETE
O DELETE é muito parecido com o método GET, por padrão não possui corpo mas quase sempre carrega um query string
para filtragem:
delete.py
17
1 #!/ usr/bin/env python3
2 import requests
3
4 response = requests.delete('https :// python.free.beeceptor.com/usuarios?id=1')
5
6 if response.status_code == 200:
7 print(response.json ())
Exercício
Agora que já vimos aquilo que é extritamente necessário para consumir APIs REST, vamos utilizar uma pequena landing page
- escrito em Flask - que pode ser gerenciada via API REST. Esta página aceita todos os métodos e podemos controlar mais
algumas partes do que outras.
O código pode ser obtido em https://github.com/hector-vido/flask-api e a documentação está no próprio README.md do
projeto, podendo ser visualizada o próprio GitHub.
Clone o projeto na raíz do seu usuário:
1 cd
2 git clone https :// github.com/hector -vido/flask -api.git
Precisaremos do Flask:
1 su -c 'apt -get update && apt -get install -y python3 -flask '
2 cd ~/flask -api
3 python3 app.py
1 cd ~/flask -api
2 python3 -m venv .
3 source ~/flask -api/bin/activate
4 pip install flask
5 python3 app.py
18
Figura 4.8: Flask API 1
Esta é página inicial - e a única que recebe alterações. Podemos alterar os seguintes itens:
• O título que aparece na barra
• O grande título na frente do fundo roxo
• O texto abaixo deste grande título
Esta parte está um pouco mais abaixo do início, aqui podemos alterar os seguintes itens:
• O título escuro centralizado
• O texto abaixo deste título centralizado
• O ícone, o título e o texto dos três blocos
19
Objetivo
O objetivo é tentar utilizar a api apenas consultando a documentação e verificando as mensagens e status de retorno - sem
a ajuda do professor, se é que você tem um!
Quando se sentir confortável crie um script em Python que utilize a API do site para completar os seguintes items:
1. Alterar o título da página inicial para “4Linux - SysAdmin & APIs”.
2. Alterar o parágrafo do fundo roxo para “Django, Flask e Pyramid são alguns exemplos de frameworks para Python.
Neste caso estamos utilizando o Flask por ser o mais simples e prático!”.
3. Criar um bloco com o ícone “ti-game” de título “Gamefication” e conteúdo “Se eu consegui colocar este bloco no site,
significa que entendi como funciona uma API REST!”.
E valide se suas alterações funcionaram com o seguinte comando dentro do diretório clonado:
1 python3 validate.py
OBS: As verificações são case-insensitive mas os espaços são importantes. Mas isso não signiica que devemos
deixar o site feio.
20
Capítulo 5
Docker
Docker é uma ferramenta open source escrita em Go que automatiza a criação de contêineres dentro de ambientes Linux,
abstraindo a complexidade e adicionando uma camada que facilita o desenvolvimento de aplicações, empacotando-as
juntamente com suas dependências em formatos de simples manutenção.
Sua primeira versão apareceu em março de 2013 durante a conferência de Python chamada PyCon através de uma empresa
chamada dotCloud. Seu sucesso meteórico fez com que a empresa trocasse de nome para Docker, Inc.
Contêineres
Em Linux, contêineres são processos que funcionam isoladas do restante do sistema, diferentemente da virtualização de
máquinas em que o processo em sí é um outro sistema com dezenas de outros processos. O Docker não é a tecnologia
de contêiner, os contêineres são resultados de uma junção de recursos do kernel do Linux, como namespaces e cgroups.
Os contêineres compartilham o kernel e algumas outras bibliotecas essenciais da máquina hospedeira, porém dentro de sí
contêm todas as dependências necessárias para que a aplicação funcione, incluindo um pequeno sistema operacional, mas
bem diferente dos das máquinas virtuais. Contêineres são efêmeros, ou seja, temporários, seus dados normalmente são são
persistidos.
Assim como as máquinas virtuais, os contêineres dependem de uma imagem, essa imagem é quem contêm todas as
dependências bem como nossa aplicação.
21
Máquinas Virtuais
As máquinas virtuais eram até então uma das únicas formas de melhor alocar o hardware para determinadas aplicações e
ainda manter um elevado nível de isolamento. São dispostas em uma infraestrutura que possuí um Hypervisor responsável
pela virtualização - as vezes é necessário que o próprio Hypervisor faça o papel de sistema operacional, porém em outras
vezes, como o é o caso com o VirtualBox ou mesmo o QEMU, existe um sistema operacional comum fornecendo o suporte
necessário. Depois do Hypervisor, cada VM é composta por um Sistema Operacional, cada qual com seus devidos processos
repetindo-se todas as vezes que uma nova máquina virtual é criada. Acima dos sistemas operacionais de cada VM existe a
aplicação, quase sempre compartilhando bibliotecas com o resto do sistema.
VM vs Contêiner
Para cada máquina virtual, assim como em sua máquina física, existirá um kernel, bibliotecas, binários e outros processos
que estarão carregados apenas para manter o sistema operacional em funcionamento. Essa necessidade não existe nos
contêineres, já que se utilizam do sistema operacional hospedeiro para os processos básicos. As inicializações também
são um ponto chave, as máquinas virtuais levam quase o mesmo tempo que máquinas físicas para se inicializarem, já os
contêineres podemos dizer que são quase instantâneos.
Por mais detalhes que possamos abordar, essa simples comparação já demonstra que contêineres utilizam menos recursos,
e por tanto são mais leves.
OBS: Em virtualização, chamamos a máquina física de host e as virtuais de guests.
Instalação
A instalação do Docker é muito simples, por mais que seja um curso voltado à programação, por questões didáticas vamos
abordar a mais completa.
Debian
Como root executar os seguintes comandos:
22
CentOS
1 yum install -y yum -utils device -mapper -persistent -data lvm2
2 yum -config -manager --add -repo 'https :// download.docker.com/linux/centos/docker -ce.repo '
3 yum install -y docker -ce docker -ce -cli containerd.io
4 systemctl enable docker
5 systemctl start docker
OBS: É possível ativar o grupo do docker para a sessão atual utilizando o comando: newgrp docker
Testando a instalação
Para testar se o docker está funcionando, execute o comando de teste:
Primeiros Passos
Abaixo, segue uma lista de comandos básicos para a utilização do Docker.
Listagem
Temos apenas um contêiner, mas é suficiente:
1 docker ps
2 docker container ls
Nada apareceu, certo? Apenas o cabeçalho. Isso é porque nosso contêiner terminou, não houve um processo persistente
capaz de deixar o contêiner funcionando. Neste caso, para listarmos todos os contêineres precisamos do parâmetro –all ou
-a.
1 docker ps -a # ou --all
2 docker container ls -a
23
A saída será a seguinte:
Todo contêiner possui um ID aleatório de 64 caracteres, mas aqui apenas os 12 primeiros aparecem, uma imagem base que
neste caso é hello-world, um comando - /hello - e um nome que caso não seja especificado é composto de um adjetivo e o
nome de um cientista famoso. Existem dezenas de outros parâmetros, mas citamos apenas os mais importantes.
Imagens
As imagens são a base de onde os contêineres usam suas bibliotecas e binários:
Iniciando
Para iniciar um contêiner, podemos utilizar o subcomando run:
Porém, neste caso, a imagem do fedora tentará iniciar um shell bash, e para isso precisamos dos parâmetros -t para alocar
um terminal virtual, e -i para o modo interativo, ou seja, para podermos escrever coisas no shell que se abrirá dentro do
contêiner:
Obs: Para sair do contêiner sem finalizar o processo principal - o que pararia o contêiner - podemos utilizar a combinação
CTRL + P + Q.
Para não ficarmos com o terminal atachado no processo do contêiner e mandá-lo para background podemos utilizar a opção
-d:
Detalhes
É possível extrair mais detalhes das execuções dos contêineres com os seguintes comandos:
24
E o consumo de recursos:
Limpeza
Para remover todos os contêineres, independente se estão rodando ou não:
Imagens
Onde estão as imagens do Docker que estamos baixando? Estas imagens estão no hub.docker.com.
Procure por outras imagens ou role a página para baixo, veja que nem todas as imagens são oficiais. Sempre que for utilizar
imagens dê preferência para as oficiais ou aquelas com mais estrelas.
Também podemos buscar imagens pelo próprio terminal, com uma interface um pouco mais limitada:
25
Podemos listar as imagens dos contêineres com o seguinte comando:
1 docker images
2 docker image ls
Existem centenas de imagens do Docker, umas são menores do que as outras. Muitas vezes as imagens menores são
identificadas por uma tag. Todas as imagens possuem tags, e caso não especifiquemos, o docker utilizará a tag :latest.
1 docker images
Camadas
Façamos o seguinte teste, vamos baixar uma image do alpine - uma pequena distribuição, muito utilizada em contêineres,
e algumas outras imagens:
26
Figura 5.4: Layers
Porém quando um arquivo presente na imagem base é alterado - lembre-se que a imagem é somente leitura - este arquivo é
copiado para a camada de escrita e modificado durante a cópia através de um processo chamado COW.
Exercícios
1. Baixe a versão 3.8 da imagem do python baseada em alpine.
1. Criar um contêiner chamado redis com a imagem redis da versão 5 baseada em qualquer versão do alpine.
2. Descobrir o endereço IP do contêiner e a porta do Redis
3. Executar um netcat no contêiner para receber a mensagem de retorno - seguir instruções abaixo:
Criando Aplicações
Veremos agora alguns aspectos mais interessantes com contêineres um pouco mais complexos.
Portas
Para iniciar um contêiner e expor uma porta na máquina através de NAT, podemos utilizar o parâmetro -p:
Variáveis de ambiente
Como as senhas, pontos de acesso e centenas de outras configurações mudam com o tempo, é interessante disponibilizar
esses valores através de variáveis de ambiente com o parâmetro -e:
27
Dentro do contêiner podemos verificar as variáveis da seguinte forma:
Variáveis de ambiente são muito interessante para modificar o comportamento das imagens com base no ambiente em que
está executando, como por exemplo, produção ou desenvolvimento. Um bom guia para desenvolver aplicações “modernas”
pode ser encontrado em https://12factor.net/.
Volumes
Os contêineres quando removidos, levam consigo todos os dados que foram modificados durante seu ciclo de vida. Para
persistir estes dados, utilizamos volumes, que são locais fora do contêiner utilizados para guardar arquivos.
Existem alguns tipos de volumes que podemos utilizar no Docker, o primeiro deles e talvez um dos mais interessantes para
nossos testes é o ponto de montagem, em que um diretório na sua máquina é disponibilizado dentro do contêiner:
1 mkdir -p ~/ html
2 echo '<marquee ><h1 >Docker !</h1 ></marquee >' > ~/ html/index.html
3 docker run -dti -p 8080:80 -v /root/html :/usr/local/apache2/htdocs/ httpd
1 docker run -dti --name mysql -e MYSQL_ROOT_PASSWORD =4 linux -v mysql_data :/var/lib/mysql mysql :5.7
Logs
Podemos visualizar os logs dos contêineres da seguinte forma:
1 AH00558: httpd: Could not reliably determine the server 's fully qualified domain name , using
172.17.0.2.
2 AH00558: httpd: Could not reliably determine the server 's fully qualified domain name , using
172.17.0.2.
3 [Sat Mar 14 02:15:40.230545 2020] [mpm_event:notice] [pid 1:tid 139629883792712] AH00489: Apache
/2.4.41
4 [Sat Mar 14 02:15:40.230587 2020] [pid 1:tid 139629883792712] AH00094: Command line: 'httpd -D
FOREGROUND '
Exercícios
1. Crie um contêiner baseado em nginx:alpine com o mesmo conteúdo adicionado ao contêiner do apache. Procurar na
documentação da imagem presente no Docker Hub para descobrir o diretório correto.
A maioria dos contêineres podem ter seus comandos alterados passando este comando ao final do docker run depois do
nome da imagem.
O python 3 possui um servidor HTTP embutido que pode ser executado através do seguinte comando:
28
1 # python3 -c 'help (" modules ") ' - para listar os módulos instalados
2 python3 -m http.server -d site # -d indica um diretório
1 mkdir ~/ site
2 git clone https :// github.com/4 linux /4542 - site.git ~/ site
2. Inicie um contêiner chamado site baseado em qualquer versão acima do python 3.7 que consiga exibir no navegador
o conteúdo do diretório ~/site.
2.1. Utilize um volume para o diretório ~/site 2.2. Exponha a porta 8000
Se tudo der certo, o site aparecerá:
Dockerfile
O Dockerfile é a forma de criarmos nossas imagens, através dele é possível fechar imagens com nossa aplicação e suas
dependências. Existe uma outra forma de criar uma imagem com o Docker, utilizando-se do comando docker commit,
porém é uma forma bastante rudimentar e não vamos abordá-la.
Com o Dockerfile é possível versionar a criação da sua imagem e seu formato de fácil leitura ajuda na compreensão do que
foi feito.
Por padrão, o nome do arquivo é Dockerfile, com a primeira letra em maíusculo:
1 mkdir ~/ minhaimagem
2 cd ~/ minhaimagem
3 vim Dockerfile
29
1 FROM alpine
2 RUN apk add curl vim htop
3 CMD sh
Imagine que na imagem anterior nossa intenção seja adicionar um arquivo de configuração qualquer dentro da imagem
durante a construção. Neste caso, utilizamos o comando COPY:
1 mkdir ~/ minhaimagem2
2 cd ~/ minhaimagem2
3 echo 'Python Sysadmin - Docker ' > arquivo.txt
4 vim Dockerfile
1 FROM alpine
2 RUN apk add curl vim htop
3 # Os diretórios sempre são criados
4 COPY arquivo.txt /arquivos/arquivo.txt
5 CMD sh
OBS: Também é possível adicionar o diretório inteiro da seguinte forma: COPY . /dir e ignorar arquivos através
do .dockerignore assim como fazemos no git.
Ao construir esta imagem, o arquivo “arquivo.txt” sempre estará dentro dos contêineres gerados:
Exercício
Limpe o ambiente:
Criar um Dockerfile baseado nas imagens apache ou nginx - sinta-se livre se quiser utilizar a tag alpine - com as seguintes
características:
1. Utilizar EXPOSE para informar que a porta 80 será utilizada
2. Utilizar COPY para copiar o conteúdo do diretório ~/site para o diretório correto
3. Ignorar - com o arquivo .dockerignore - a pasta .git
4. Chamar a imagem de “site:v1”
5. Iniciar um contêiner baseado nesta imagem escutando na porta 9090
6. Acessar o servidor web do contêiner pelo navegador
30
Registry
Um registry é um repositório de imagens, um local de onde podemos baixá-las e enviá-las. Neste caso, iremos utilizar o
Docker Hub.
Crie uma conta em https://hub.docker.com/ e então digite no terminal:
E digite sua senha. Se o processo de cadastro funcionou, agora estamos autenticados para enviar nossas imagens para nossa
conta! Vamos enviar a imagem que acabamos de criar:
O que será que aconteceu? O Docker Hub rejeitou nossa imagem! Isso é porque as imagens do Docker com nomes simples
pertencem a uma conta especial do próprio Docker Hub, a library.
Por exemplo, a imagem alpine do Docker Hub tem o seguinte nome:
1 docker.io/library/alpine:latest
1 endereco/conta/imagem:tag
O binário do docker está preparado para adicionar todo o trecho docker.io/library quando não for especificado. Isso significa
que se possuir um registry privado na sua empresa, precisará referenciar o endereço completo, exemplo:
1 registry .4 linux.com.br/sysadmin/python:latest
No nosso caso precisaremos dizer que nossa imagem não pertence ao “library” e sim a nossa conta, e fazemos isso utilizando
o subcomando tag:
Vá até o Docker Hub e procure na sua conta pela sua imagem. Depois de alguns tempo ela aparecerá nas buscas. É possível
deixar uma imagem privada gratuitamente, acima disso é preciso pagar.
Qualquer um poderá baixar sua imagem, basta digitarem:
31
Exercício
Agora que já sabemos como criar contêineres um pouco mais atrativos e como enviar essa nossa imagem para um repositório
público vamos condensar as coisas um pouco.
Fomos contratados por uma empresa chamada ACME - A Company that Made Everything - para desenvolver um “script”
a fim de facilitar seu processo de ETL. As três principais exigências são que a aplicação seja escrita em Python, utilize
MongoDB e que rode em contêiner, já que futuramente utilizarão Kubernetes em sua infraestrutura.
O objetivo é puxar os dados presentes em https://raw.githubusercontent.com/hector-vido/flask-api/master/samples/
usuarios.csv e cadastrar dentro do MongoDB somente aqueles com salário maior ou igual a R$ 3000,00.
Nossos objetivos são:
1. Iniciar um contêiner do MongoDB versão 4 com as seguintes características:
1.1. - O nome do contêiner deverá ser “mongodb”
1.2. - O nome do usuário administrador deverá ser “acme”
1.3. - A senha do administrador deverá ser “!Abc123” 1.4. - O nome da base de dados deverá ser “acme”
1.5. - O nome da collection será usuarios - o python a criará durante o primeiro insert
1.6. - Utilizar um volume para persistir os dados do MongoDB
2. Criar uma imagem chamada “acme-etl” com as seguintes características:
2.1. - Basear a imagem em alpine puro
2.2. - Instalar o pacote py3-pip
2.3. - Instalar as dependências pelo pip3 e seu próprio “requirements.txt”
2.4. - Copiar os arquivos para /app
2.5. - Quando o contêiner for iniciado, ele executará o script e se encerrará
2.6. - Especificar o id como ”_id” para evitar que o MongoDB atribua seu próprio _id
2.7. - Opcional: O script não poderá inserir dados com “id” repetido - Procurar por upsert
3. Criar uma imagem chamada “acme-json” com as seguintes características:
3.1. - A imagem deverá contêr o código fornecido abaixo
3.2. - Basear a imagem em alpine puro
3.3. - Instalar o pacote py3-pip
3.4. - Instalar as dependências pelo pip3 e o “requirements.txt” fornecido abaixo
3.5. - Copiar os arquivos para /app
3.6. - Especificar que a porta exposta será a 5000
3.7. - O acesso ao MongoDB será feito através de variáveis de ambiente:
3.7.1. - MONGO_HOST - procurar pelo IP do MongoDB
3.7.2. - MONGO_USER
3.7.3. - MONGO_PASS
4. O contêiner baseado em “acme-etl” deverá se chamar “etl”
5. O contêiner baseado em “acme-json” deverá:
5.1 - Se chamar “flask”
5.2 - Escutar na porta 5000
acme-json
Veremos Flask mais adiante, por enquanto precisaremos apenas nos preocupar com o MongoDB.
O código abaixo pode ser encontrado em https://github.com/hector-vido/flask-api/tree/master/samples/acme-json:
app.py
32
9 client = MongoClient('mongodb ://{0}:{1}@{2}:27017/ admin '.format(environ['MONGO_USER '], environ['
MONGO_PASS '], environ['MONGO_HOST ']))
10 db = client.acme
11
12 @app.route('/')
13 def home ():
14 return jsonify ([u for u in db.usuarios.find ()])
15
16 app.run(host='0.0.0.0 ', port =5000 , debug=True)
requirements.txt
1 flask
2 pymongo
33
Capítulo 6
Docker API
Apesar de não parecer, o Docker funciona através de uma arquitetura cliente e servidor que interage através de uma API
REST. A documentação desta api pode ser encontrada em https://docs.docker.com/engine/api/latest/.
Inicialmente as chamadas a essa API estão disponíveis somente através de um unix socket, porém é possível fazer as
chamadas em portas TCP, desde que seja habilitado no serviço do Docker. Sempre que executamos o comando docker …
uma chamada a API é feita.
34
Unix Socket
Na máquina local podemos acessar a API sem muitas dificuldades, exatamente como o comando docker faz, porém com o
curl:
TCP
Mas se nossa intenção é acessá-la externamente, existem algumas formas de liberar o acesso através de um endereçoe uma
porta. Anteriormente podíamos modificar apenas o service do Docker adicionando a opção -H tcp://, mas nas versões mais
recentes podemos alterar ou criar o daemon.json:
O endereço 0.0.0.0 indica que todas as interfaces de rede da máquina vão aceitar conexões, e as portas que podemos utilizar
por padrão são 2375 - para conexões em texto comum - e 2376 para conexões criptografadas.
Remova as opções conflitantes do service:
Agora, além do curl, podemos acessar a API do Docker através do Postman ou de qualquer processo que enxergue a nossa
VM sem estar dentro dela.
Podemos pegar informações:
Listar os contêineres:
35
Python
Provavelmente, agora é simples de imaginar que podemos utilizar a biblioteca requests do Python para fazer esse tipo de
chamada, certo? Sim! Mas para o docker já existe uma biblioteca que facilita essa comunicação Docker SDK for Python.
Vamos instalá-la!
1 cd
2 source 521/ bin/activate
3 pip install docker
Listagem
Vamos testar a conexão do Python com Docker, crie um arquivo chamado container_list.py dentro do diretório 512:
1 cd ~/512
2 mkdir aula -02
3 cd aula -02
4 vim container_list.py
container_list.py
A API é bastante sugestiva, neste caso instanciamos um DockerClient que estabelece uma conexão com o docker daemon
através do unix socket. Depois listamos todos os contêineres - equivalente a opção -a - e escrevemos na tela os contêineres
encontrados.
Os métodos da classe DockerClient estão diretamente ligados aos endpoints da API do Docker, isso significa que cada
método trata de uma parte da api, por exemplo:
• containers -> client.containers.list()
• images -> client.images.pull()
• volumes -> cliente.volumes.prune()
É possível notar que o retorno de client.containers.list é uma lista com objetos da classe container. Vamos expandir um pouco
mais o código:
36
1 print(client.containers.get('redis ').id)
2 print(client.containers.get('cd1c11b4b5 ').name)
Exercício
1. Limpe todos os contêineres da máquina, sem exceção, utilizando o python
1.1 - É possível remoter todos os contêineres parados de uma vez, mas não os que estão rodando 1.2 - Precisaremos
percorrer todos os contêineres e removê-los um a um neste caso 1.3 - O método utilizado para remover um contêiner
é remove faz parte da classe Container. 1.4 - É possível utilizar um parâmetro para forçar a remoção
2. Execute o seguinte comando, para carregar alguns contêineres na máquina:
2.1 - curl -sL https://raw.githubusercontent.com/hector-vido/flask-api/master/samples/docker/create-containers.sh |
bash 2.2 - Procure pelos métodos stop e start na documentação da API sobre a classe Container 2.3 - Escreva um script
em python que pare todos os contêineres menos os baseados em apache, nginx e supermario
OBS: Se terminou o exercício, descubra o endereço do “contêiner do mario” e acesse pelo navegador na porta
8080. Utilize as setas e as teclas A e S.
Criação
Não foi dito durante o curso, mas o comando docker run é a junção de outros dois comandos, o create e o start. Na maioria
dos casos não precisamos nos preocupar isso, e aqui não é uma exceção.
Para criar um contêiner utilizando a API para o Python é muito simples. Crie um arquivo chamado container-create.py:
1 cd ~/512
2 mkdir aula -02
3 cd aula -02
4 vim container_create.py
container_create.py
O único detalhe diferente do que utilizamos na linha de comando é a ordem das portas, primeiro é a porta do contêiner
seguido pela porta da máqui.
OBS: Não se esqueça de utilizar o detach nos casos em que o contêiner ficará rodando.
Exercício
Criar um script em python que inicialize a infraestrutura do exercício da ACME.
1. O script deverá um parâmetro com o valor start ou stop
2. Utilizar sys.argv
3. Ao receber o parâmetro start os três contêineres deverão iniciar
4. Ao receber o parâmetro stop os três contêineres deverão parar
37
Capítulo 7
Git
Git é um sistema controlador de versão distribuído. Através de sua utilização é possível manter o histórico e a visualização
de todas as alterações em diversos tipos de documento de texto, incluindo, mas não limitando-se a códigos de linguagens
de programação. É possível obter detalhes de uma determinada alteração, como quem fez, quando fez o que o foi alterado
em relação a versão anterior. O git trabalha com branches, que são ramificações do repositório original. Essas ramificações
são modificadas pelas equipes e então geralmente são anexas a branch principal conhecida como master.
História
Foi criado em 2005 por Linus Torvalds, o criador do kernel do Linux, como substituto ao bitkeeper para versionar o código
do kernel. Na época, o bitkeeper passou a cobrar pela sua utilização e então a equipe resolveu criar seu próprio versionador.
Curiosamente, o resultado deste evento resultou na explosão da aceitação do git como ferramenta de versionamento e hoje
em dia, em empresas que trabalham com ferramentas opensource, git é praticamente sinônimo de versionamento de código.
Obs: Hoje em dia o bitkeeper passou a ser um projeto opensource como podemos ver em https://www.bitkeeper.org/.
Clientes
Devido a facilidade de utilização juntamente a um terminal - presente em praticamente qualquer editor hoje em dia - grande
parte dos desenvolvedores utilizam o próprio comando git para fazer todo o gerenciamento. Durante o curso utilizaremos
somente o comando git, mas para aqueles que preferem uma ferramenta visual de qualidade, open source e multiplataforma,
existe um projeto chamado Git Kraken.
Utilizando o Git
Vamos executar uma série de comandos para que possamos nos habituar com a manipulação do git e aproveitar para abordar
alguns casos mais comuns de uso.
Criando
Para criar um repositório do git, tudo o que precisamos fazer é entrar na pasta em que queremos versionar e executar o
seguinte comando:
1 git init
Você pode verificar que o repositório foi criado pela presença da pasta .git no diretório:
1 ls -la
38
A saída será semelhante a seguinte:
1 .
2 ..
3 .git
4 app.py
É muito comum começarmos criando um repositório em um dos serviços como GitHub, GitLab ou BitBucket, porém um
repositório é iniciado desta forma.
Clonando
Muitas vezes já temos um repositório de onde queremos obter o código fonte, ou criamos um repositório vazio em um dos
serviços online. Neste caso, não podemos iniciar um repositório, mas sim cloná-lo:
O comando clone, caso seja executado sem um parâmetro adicional depois do endereço, clonará o repositório em um
diretório com o mesmo nome do arquivo .git, neste caso cpython.
Gravando Alterações
Uma vez que seu repositório esteja pronto, ou que você tenha adicionado os arquivos desejados, é preciso confirmar - commit
- estas alterações. Muitas vezes a palavra commit é utilizada no português como o verbo commitar. O processo consiste em: -
Adicionar o arquivo novo ou alterado - Criar uma confirmação com uma mensagem
Verificando Alterações
Antes de gravar as alterações, é possível ver o que foi adicionado, o que foi criado e o que foi modificado com o seguinte
comando:
1 git status
Também é possível ver quais alterações foram feitas em determinados arquivos, desde que o comando seja executado antes
do commit:
É possível consultar o histórico de alterações de várias formas. A mais simples delas é obter uma lista com todos os commits
realizados até o momento, você pode sair do buffer com a tecla “q”:
1 git log
Uma forma mais detalhada é utilizar o comando blame - culpar - para analisar linha a linha o usuário que alterou e o código
do commit:
39
Subir alterações
Uma vez que tenhamos gravado essas alterações me nosso repositório local, podemos enviá-las para um repositório remoto,
garantindo o acesso através de outros computadores e locais. As vezes o repositório remoto não foi criado e portanto não
foi adicionado, neste caso adicionamos o projeto remoto dando um apelido para o endereço que geralmente é origin:
Uma vez configurado, podemos sincronizar as alterações com o subcomando push, passando o apelido do endereço remoto
e a branch que queremos enviar:
Baixar alterações
Imagine que você tenha trabalhado todo o dia anterior e ao final do expediente tenha enviado suas alterações para o
repositório remoto. Durante a noite outras pessoas trabalharam no código e também enviaram suas alterações. No início
do outro dia, para evitar conflitos, antes de começar a alterar o código novamente, o ideal é baixar todas as alterações. O
subcomando para isso se chama pull e como parâmetro passamos o apelido do endereço remoto e a branch que queremos
atualizar:
Conflitos
Quando estamos trabalhando sozinho em um repositório, raramente teremos problemas de conflito. Mas quando um
time inteiro está trabalhando, enviando e recebendo alterações constantemente, muitas vezes teremos que resolver alguns
conflitos que o git não conseguiu antes de podermos enviar nossas alterações.
No geral, o git tenta fazer o que chamamos de automatic merge e isso funciona na maioria das vezes.
Imagine dois usuários, João e Maria, que estão trabalhando no mesmo projeto, e fizeram o pull logo no início do dia.
Primeiro Cenário
Antes do almoço Maria alterou uma função qualquer e subiu suas alterações. Logo em seguida João alterou outra função e
tentou subir suas alterações:
1 git add .
2 git commit -m 'Função nuclear '
3 git push origin master
O git no entanto avisa ao João que antes de subir qualquer nova alteração, ele precisará baixar o que já foi feito.
40
Segundo Cenário
A tarde, ambos fizeram alterações na mesma seção do arquivo app.py e subiram suas alterações pelo git. O último a subir
suas alterações deverá baixar e corrigir o que já foi feito:
1 git add .
2 git commit -m 'Alterações na recursividade do arquétipo gerador '
3 git push origin master
Mas desta vez, o git não conseguirá resolver os conflitos e deixará a tarefa para o usuário:
Trocando de branch
As vezes, para não bagunçar a branch principal, criamos uma branch de desenvolvimento e subimos nossa alteração para
esta branch até que estejam suficientemente estáveis para serem mescladas a branch master.
O comando checkout é responsável pela troca de branches. Podemos verificar em qual branch estamos, através do comando:
1 git branch
1 git branch -a
Merge
Uma vez que tenhamos alcançado o estado aceitável em nossa branch, podemos mesclá-la com a master:
Pull
Uma outra forma de atualizar uma branch é utilizar-se de outra branch remota:
41
Capítulo 8
Gerenciadores do Git
O git é o software responsável por versionar nosso código localmente. Porém quando criamos repositórios remotos é
interessante facilitar a gerência de todos os aspectos. Não somente o versionamento, mas controlar usuários, autenticações
e permissões, e para isso utilizamos algum serviço ou instalamos um em nossa infraestrutura local.
Os gerenciadores como serviço mais conhecidos são:
• GitHub
• Bitbucket
• GitLab
Para o nosso curso precisaremos de um gerenciador instalado em nossa infraestrutura local, para isso podemos utilizar o
Gitlab ou o Gogs.
GitLab
Gitlab é um gerenciador de repositórios baseados em git. Surgiu em setembro de 2011 e hoje pode ser considerado como
o gerenciador mais conhecido dentro da comunidade de software livre. Além do gerenciamento de repositórios, o GitLab
possuí todas as ferramentas necessárias para um time que utilize metodologias ágeis, como KanBan, esteira de produção,
repositório de artefatos e deploy. A desvantagem da abrangência de serviços está no fato de precisarmos de no mínimo
4GB de memória RAM para operá-lo sem problemas inesperados. Possuí o serviço online https://gitlab.com/ semelhante ao
GitHub e uma versão que pode ser instalada em sua infraestrutura interna de forma privada. Possuí uma versão community
e uma versão enterprise.
Instalação
A forma de instalação do GitLab será através de um contêiner do Docker utilizando um compose-file. A documentação oficial
pode ser encontrada em https://docs.gitlab.com/omnibus/docker/.
Gogs
Gogs é um outro gerenciador de repositórios baseados em git. Surgiu em 2015 e limita-se somente a fornecer gerenciamento
dos repositórios. Seu foco é a simplicidade, baixa dependência e pouca utilização de recursos, podendo funcionar em uma
máquina baseada em Raspberry Pi.
42
Capítulo 9
Jenkins
Jenkins é uma ferramenta utilizada para integração contínua e entrega contínua, popularmente conhecido como CI/CD -
Continuous Integration e Continuous Delivery. Seu papel é integrar à esteira de produção do software outros programas
responsáveis por testes unitários, análise de código, testes de stress e qualidade para que então uma nova versão possa ser
disponibilizada em produção, ou em algum repositório de artefatos, com uma alta taxa de confiabilidade. O Jenkins é um
dos grandes nomes ao lado do Docker dentro do universo DevOps.
História
O Jenkins surgiu de um fork de seu antecessor conhecido como Hudson, desenvolvido dentro da Sun Microsystems.
A primeira versão do Hudson apareceu em meados de 2005, porém em 2009 a Oracle Corporation comprou a Sun e
consequentemente adquiriu direito sobre todos seus produtos. Após uma disputa pelo nome Hudson - por parte da
comunidade mantenedora e que a Oracle alegava ser proprietária - em 2011 uma votação dos contribuintes culminou no
fork do projeto para outro de nome Jenkins. O projeto do Hudson foi doado para a Apache Foundation em 2012, e em 2017
foi descontinuado e considerado obsoleto, concentrando todos os esforços no já consagrado Jenkins.
Instalação
A instalação do Jenkins será feita através de um contêiner do Docker utilizando um compose-file. A documentação pode ser
encontrada em https://jenkins.io/doc/book/installing/.
43
Capítulo 10
Preparação
1 sudo su
2 chown 1000:1000 /srv/jenkins
Adicione as entradas para cada contêiner dentro do arquivo /etc/hosts. Dessa forma a comunicação entre os contêineres e
com os contêineres ficará facilitada:
1 sudo su
2 echo '172.27.11.10 gitlab.example.com' >> /etc/hosts
3 echo '172.27.11.20 jenkins.example.com' >> /etc/hosts
1 version: '3.0'
2
3 services:
4 gitlab:
5 image: 'gitlab/gitlab -ce:latest '
6 hostname: 'gitlab.example.com '
7 restart: always
8 ports:
9 - '22:22'
10 - '80:80'
11 - '443:443 '
12 volumes:
13 - '/srv/gitlab/config :/etc/gitlab '
14 - '/srv/gitlab/data :/var/opt/gitlab '
15 extra_hosts:
16 - 'jenkins.example.com :172.27.11.20 '
17 networks:
18 interna:
19 ipv4_address: '172.27.11.10 '
20 jenkins:
21 image: 'jenkins/jenkins:lts '
22 hostname: 'jenkins.example.com '
23 restart: always
44
24 ports:
25 - '8080:8080 '
26 volumes:
27 - '/srv/jenkins /:/ var/jenkins_home '
28 extra_hosts:
29 - 'gitlab.example.com :172.27.11.10 '
30 networks:
31 interna:
32 ipv4_address: '172.27.11.20 '
33
34 networks:
35 interna:
36 driver: bridge
37 ipam:
38 config:
39 - subnet: '172.27.11.0/24 '
Gitlab
O Gitlab estará acessível através do endereço gitlab.example.com. Defina a nova senha para Gitlab como 4linux123. O usuário
padrão para fazer o login é o root.
A documentação para a API do Gitlab é muito bem detalhada e pode ser encontrada em https://docs.gitlab.com/ee/api/.
Existe um módulo do Python responsável para comunicação com o GitLab, mas neste caso utilizaremos o próprio requests.
Jenkins
O Jenkins estará acessível através do endereço jenkins.example.com:8080. Para o Jenkins você precisará utilizar o docker logs
ou acessar o conteúdo do arquivo indicado na página de instalação para desbloqueá-la. Instale os plugins recomendados.
Defina o usuário como admin e a senha como 4linux123.
A documentação do Jenkins pode ser visualizada no canto inferior de suas páginas ou em https://wiki.jenkins.io/display/
JENKINS/Remote+access+API.
Também utilizaremos requests para nos comunicar com o Jenkins.
45
Capítulo 11
Flask
Flask é um micro-framework para aplicações web desenvolvido em Python. O “micro” é devido a sua leveza, pois é um
framework bem enxuto, onde o desenvolvedor escolhe quais bibliotecas irá incorporar ao projeto de acordo com as
necessidades da sua aplicação. O Flask foi desenhado justamente para tornar fácil e rápido o início do desenvolvimento,
mas com capacidade de expandir o nível de complexidade da aplicação.
Flask é um dos frameworks que rodam em WSGI (acrônimo de Web Server Gateway Interface), que é uma convenção/especificação
de comunicação entre servidores web e aplicações python mediante chamadas simples.
Aplicação Simples
Uma exemplo de uma aplicação bem simples - retornando apenas um json ao acessar o endereço raíz - poderia ser feito da
seguinte maneira:
flask-01.py
Blueprints
Blueprints são pequenos módulos do Flask em que separamos nossas aplicações para manter a estrutura do projeto mais
organizada. Caso nossa aplicação cresça, o arquivo principal ficará muito grande. Neste caso, separamos a aplicação em
pedaços menores colocando, por exemplo, as rotas referentes a usuários em um arquivo blueprints/usuarios.py
blueprints/usuarios.py
46
5 def home ():
6 return jsonify ([{"id" : 1, "nome" : "Dennis Ritchie"}, {"id" : 2, "nome" : "Guido van Rossum"}])
O arquivo principal, responsável por adicionar o blueprint poderia ser da seguinte forma - vamos aproveitar tornar a “/” final
opcional desavitando strict_slashes:
47
Capítulo 12
Jinja
Jinja é uma linguagem de template para Python, baseada nos templates do Django. É bastante intuitiva e sua sintaxe é
utilizada em vários outros lugares. Talvez o melhor exemplo seja os arquivos de template do Ansible. Com o Jinja é possível
escrever condições, repetições e váriavés dentro do HTML que serão mais tardes substituídas pelo Python.
Básico
Um template simples de Jinja pode ser definido da seguinte forma:
Os valores entre duas chaves - {{ nome }} - são considerados variáveis e substituídas pelo Python caso uma variável tenha sido
enviada pelo Flask, do contrário, receberá um valor vazio.
Já os trechos entre {% %} são considerados blocos e podem controlar a lógica de exibição ou mesmo uma estrutura de
controle/repetição.
Variáveis
1 @app.route('/')
2 def home ():
3 return render_template('flask -01. html ', titulo='Flask site!')
Filtros
O Jinja suporta alguns filtros - ou modificadores - do lado do template, simplicando o código do lado do backend e separando
melhor a lógica de exibição:
48
1 <! DOCTYPE html >
2 <html lang="en">
3 <head >
4 <title >Flask </title >
5 </head >
6 <body >
7 <h1>{{ conteudo|upper }}</h1>
8 <body >
9 </html >
Neste caso a variável conteudo será transformada em caixa alta. Existem outros modificadores interessantes:
• safe - Não remove caracteres especiais como HTML, JavaScript e etc.
• lower - Transforma todas as letras em caixa baixa.
• join - Unifica uma lista em uma string.
A lista completa de filtros padrão pode ser vista em https://jinja.palletsprojects.com/en/2.11.x/templates/#builtin-filters.
Blocos
Blocos no Flask podem ser definidos de várias formas. Podem exitir blocos que herdam conteúdo de outros templates, blocos
exibidos dentro de condições e blocos dentro de loops de repetição.
Condições
Uma aplicação que envie para o método render_template uma variável indicando true ou false pode exibir ou esconder um
determinado bloco HTML:
flask-03.py
1 <h1>Flask!</h1>
2 <p>Aqui um pequeno trecho de texto que sempre deve aparecer ...</p>
3 {% if exibir %}
4 <h2>Segredo </h2>
5 <p>E aqui um trecho secreto que só aparecerá ao mudar a varíavel <b>exibir </b>.</p>
6 {% endif %}
Repetições
Uma pequena rota no Flask que envia uma variavel chamada usuarios com uma lista de usuários do banco para o método
render_template:
1 @app.route('/usuarios ')
2 def usuarios ():
3 usuarios = db.usuarios.find ()
4 return render_template('usuarios.html ', usuarios=usuarios)
49
O método poderia receber os usuários da seguinte forma, repetindo na página resultante um bloco para cada usuário:
1 <ul>
2 {% for u in usuarios %}
3 <li><a href="#{{ u.id }}">{{ u.nome }}</a></li>
4 {% endfor %}
5 </ul>
50
Capítulo 13
LDAP
Para simplificar ao máximo, podemos dizer que o LDAP é um protocolo utilizado para autenticação de usuários e consulta
de seus registros. Existem muitos softwares que implementam LDAP, dentro eles o OpenLDAP, o 389 dentro do FreeIPA ou
mesmo o Active Directory da Microsoft.
Mas e o banco?
É muito comum existirem dúvidas sobre a utilidade do LDAP, principalmente em relação a autenticações controladas por
bancos de dados convencionais como MySQL, PostgreSQL, Firebird ou MongoDB.
Mas é importante lembrar que existem integrações com o LDAP na maioria dos softwares desenvolvidos, o que facilita muito
sua adoção. Ainda por um lado mais técnico, as autenticações no LDAP podem acontecer sem um usuário intermediário - o
usuário do banco - eliminando uma etapa e facilitando o arquivamento desses acessos:
OpenLDAP
O OpenLDAP é uma das implementações do LDAP mais conhecidas dentro do Linux, existem várias formas de instalá-lo e
a instalação difere entre as distribuições. Para este curso utilizaremos um contâiner com uma instalação configurada do
OpenLDAP. Modifique o compose file adicionando o contâiner do OpenLDAP:
1 version: '3.0'
2
3 services:
51
4 gitlab:
5 image: 'gitlab/gitlab -ce:latest '
6 hostname: 'gitlab.example.com '
7 restart: always
8 ports:
9 - '22:22'
10 - '80:80'
11 - '443:443 '
12 volumes:
13 - '/srv/gitlab/config :/etc/gitlab '
14 - '/srv/gitlab/data :/var/opt/gitlab '
15 extra_hosts:
16 - 'jenkins.example.com :172.27.11.20 '
17 networks:
18 interna:
19 ipv4_address: '172.27.11.10 '
20 jenkins:
21 image: 'jenkins/jenkins:lts '
22 hostname: 'jenkins.example.com '
23 restart: always
24 ports:
25 - '8080:8080 '
26 volumes:
27 - '/srv/jenkins /:/ var/jenkins_home '
28 extra_hosts:
29 - 'gitlab.example.com :172.27.11.10 '
30 networks:
31 interna:
32 ipv4_address: '172.27.11.20 '
33 ldap:
34 image: osixia/openldap
35 hostname: 'ldap.example.com '
36 restart: always
37 environment:
38 LDAP_DOMAIN: 'ldap.example.com '
39 LDAP_ADMIN_PASSWORD : 4linux
40 ports:
41 - '3386:386 '
42 - '6636:636 '
43 volumes:
44 - '/srv/ldap/data :/var/lib/ldap '
45 - '/srv/ldap/conf :/etc/ldap/slapd.d'
46 networks:
47 interna:
48 ipv4_address: '172.27.11.30 '
49
50 networks:
51 interna:
52 driver: bridge
53 ipam:
54 config:
55 - subnet: '172.27.11.0/24 '
Verifque se a conexão com o servidor LDAP está funcionando. Você pode entrar no contêiner ou executar o comando por
fora diretamente. Demonstrarei acessando o contêiner:
Buscar Entradas
E então, dentro do contêiner execute:
1 ldapsearch -D 'cn=admin ,dc=ldap ,dc=example ,dc=com' -w '4linux ' -b 'dc=ldap ,dc=example ,dc=com'
52
Adicionar Usuário
A adição de usuários no LDAP, ou de qualquer tipo de registro é feita através de arquivos LDIF, por exemplo:
user.ldif
ldap3
O ldap3 é um módulo escrito puramente em Python para a versão 3 do protocolo LDAP. Pode ser utilizado a partir da versão
2.6 ou qualquer versão 3 do Python.
Instale o módulo em sua máquina:
53
13 }
14
15 server = Server('127.0.0.1 ', use_ssl=False)
16 ldap = Connection(server , user='cn=admin ,dc=ldap ,dc=example ,dc=com', password='4linux ')
17
18 if not ldap.bind ():
19 print('Problemas ao se autenticar ')
20 exit (1)
21
22 object_classes = ['top', 'posixAccount ', 'person ', 'inetOrgPerson ']
23 ldap.add('uid=larry.wall ,dc=ldap ,dc=example ,dc=com', object_classes , ldif)
54
Capítulo 14
Apache
Copiar aplicação
1 sudo cp -r dashboard /var/www
Criar WSGI
Criar o arquivo dashboard.wsgi em /var/www/dashboard:
1 import sys
2 sys.path.insert(0, '/var/www/dashboard/')
3
4 from app import app as application
Configuração do Site
Editar o arquivo /etc/apache2/sites-enabled/000-default.conf :
1 <VirtualHost *:80>
2
3 WSGIDaemonProcess dashboard user=www -data group=www -data threads =5
4 WSGIScriptAlias / /var/www/dashboard/dashboard.wsgi
5
6 <Directory /var/www/dashboard >
7 WSGIProcessGroup dashboard
8 WSGIApplicationGroup %{ GLOBAL}
9 Order deny ,allow
10 Allow from all
11 </Directory >
12 </VirtualHost >
55
Capítulo 15
Logs
Log é o registro de uma determinada ação em um determinado tempo. Praticamente qualquer aplicação dentro de uma
sistema operacional grava log. É através dos logs que podemos verificar o porque alguma aplicação apresentou problema,
se estamos sofrendo sobrecarga em algum serviço ou até mesmo algum tipo de invasão.
logging
O Python na versão 3 já possuí embutido em sí uma classe e um objeto para capturar e gerenciar esses logs. O Flask, por sua
vez, utiliza este objeto e o adiciona dentro da variável app para fazer suas próprias modificações. Ao invés de destruir o que
o Flask já fez, vamos utilizar o logging da aplicação, ao invés de escrever na tela, vamos criar arquivos que rotacionam a cada
1MB:
Este trecho de código deve ser definido antes da instanciação da variável app, do contrário teremos que remover o logging
definido e então aplicar nossas configurações:
Uma vez que tenhamos configurado o log ao nosso modo, podemos escrever mensagens através dos métodos info, error,
warning e etc:
56
1 app.logger.info('Log de info ')
2 app.logger.error('Log de erro ')
3 app.logger.debug('Debugando ...')
57
Capítulo 16
Paramiko
Paramiko é um módulo que implementa conexões SSH escrito puramente em Python. Isso significa que não há utilização
de bibliotecas externas.
Instalação
1 apt -get install -y python3 -paramiko
2 #pip3 install paramiko
A utilização do Paramiko é muito simples. Importamos o módulo, e então instanciamos um objeto do SSHClient.
1 import paramiko
2
3 client = paramiko.client.SSHClient ()
Depois carregamos as chaves conhecidas pelo computador, sem nenhum parâmetro o arquivo know-hosts é carregado por
padrão.
1 client. load_system_host_keys ()
E então, nos conectamos a um computador, podemos utilizar um usuário com senha ou chave privada, vamos utilizar a
chave:
Uma vez conectado, podemos executar comandos na máquina remota. Ao definir as três variáves em forma de tupla
podemos trabalhar com input de dados - mas não é tão simples como o restante, capturar os dados da saída comum e de
erros. O retorno é como um texto de um arquivo qualquer:
Com a conexão feita, enviar e puxar arquivos torna-se uma tarefa trivial. Os métodos get e put fazem todo o trabalho. É
preciso instanciar um objeto sftp, e fazê-lo sem ajuda da conexão já estabelecida é um trabalho detalhista, ainda bem que
o método open_sftp() do client facilita essa inicialização. O método put especifica primeiro um arquivo local e então seu
destino remoto, ambos incluindo o nome. Já o método get se comporta de forma oposta, especificando primeiro um arquivo
remoto e então seu destino local.
58
1 sftp = client.open_sftp ()
2 sftp.put('ssh.py', 'ssh.py')
3 sftp.get('/etc/os -release ', 'os -release ')
59
Capítulo 17
AWS
AWS ou Amazon Web Services é um serviço de cloud disponibilizado pela Amazon. Neste curso, veremos apenas uma
pequena fração específica do universo que é a AWS, o EC2.
EC2
EC2 significa Elastic Cloud Compute - todos os serviços da AWS com letras repetidas consecutivamente recebem um número
depois da primeira letra. Representam as máquinas virtuais que podemos criar dentro da cloud.
Para facilitar a criação de instâncias é mais fácil criar um Security Group para utilizarmos nos códigos em python que
escrevermos. Mas o mais importante é permitir que nosso script se conecte na AWS, criando uma permissão através do
IAM.
awscli
O awscli - command line interface - nos permite instanciar e gerenciar serviços na AWS. Mas também serve para configurar
os arquivos necessários para a conexão, seja através do cli ou do python. Estes arquivos estão localizados na home do usuário
atual e podem ser criados manualmente:
1 .aws/���
2 config���
3 credentials
config
1 [default]
2 region = us -east
credentials
1 [default]
2 aws_access_key_id = 123
3 aws_secret_access_key = abc
No nosso caso, vamos utilizar o comando aws para facilitar a criação e evitar problemas:
60
Uma vez instalado, execute o subcomando configure para criar os arquivos mencionados com os valores extraídos da sua
conta:
1 aws configure
boto3
Para nos conectar a AWS utilizaremos um módulo do python chamado boto3. O nome boto foi inspirado no boto da
Amazônia que consegue se mover rapidamente pelo rio Amazonas, fazendo referência ao nome Amazon. Para instalar o
boto3
O boto3 trabalha com praticamente todos os serviços da AWS, então a inicialização da instância trabalha em um design
pattern parecido com o Fabric, ou seja, eu digo o recurso que quero, e o método me retorna - fabrica - um recurso daquele
tipo.
1 resource = boto3.resource('ec2')
Dessa forma trabalharemos somente com o que é pertinente ao ec2. Caso precisássemos trabalhar com o s3 bastaria
especificar este nome dentro do parênteses.
Feito isso, podemos criar nossa instância. Para criar uma instância precisamos obrigatóriamente de um ami - amazon
images - que é a imagem do sistema operacional que queremos instalar na máquina. Existem milhares deles disponíveis.
Também precisamos especificar o tipo da máquina com InstanceType e a quantidade mínima e máxima de instâncias - para
criar um pool. Outra configuração obrigatória é a chave que vamos utilizar para acessar a máquina, neste caso python, uma
chave que já criamos anteriormente dentro da AWS.
O boto.resource faz todo o trabalho de gerenciar os recursos, mas para procurar e listar nosso serviços o client é muito mais
cômodo:
1 client = boto3.client('ec2')
2 response = client.describe_instances ()
Podemos então unir os dois e terminar - remover - todas instâncias EC2 da nossa conta:
61