Introdução editar

Finalidade editar

Com base nesse sistema, a finalidade é disponibilizar uma automatização de um ambiente de desenvolvimento para o radar parlamentar, onde já se tenha as dependências necessárias para execução do sistema e assim o desenvolvedor já iniciar sua contribuição com o desenvolvimento no projeto.

Escopo editar

O Radar Parlamentar é um sistema que determina "semelhanças" entre partidos políticos baseado na análise matemática dos dados de votações de projetos de lei na casa legislativa brasileira. Essas semelhanças são apresentadas em um gráfico bi-dimensional, em que os círculos representam partidos e a distância entre esses círculos representa o quão parecido esses partidos votam. Este sistema se utiliza de dados abertos para analisar os votos de parlamentares em diferentes casas legislativas do Brasil.

Visão Geral editar

Ferramentas, Ambiente e Infra-Estrutura editar

Ferramenta Descrição
VirtualBox Ferramenta de criação de máquinas virtuais para emulação de sistemas operacionais.
Vagrant Ferramenta para gerenciar máquinas virtuais e criação de ambientes de teste, desenvolvimento e provisionamento.
Puppet Framework opensource e um conjunto de ferramentas e soluções

destinado à gerência de configurações para automatização de servidores e serviços.

O ambiente adotado é o sistema operacional ubuntu 14.04 32 bits, chamado de ubuntu/trusty32. Assim, as instalações e configurações das dependências para o sistema do radar vão ser direcionadas utilizando-se deste ambiente.

Para o ambiente de instalação das ferramentas utilizadas para virtualização, no caso o virtualbox e vagrant, será utiliazado o sistema operacional ubuntu 16.04 64 bits.

VirtualBox editar

Instalação
Para se instalar o virtualbox será necessário fazer o download do virtualbox, para isso abra o terminal e execute o comando:
$ wget http://download.virtualbox.org/virtualbox/5.0.20/VirtualBox-5.0.20-106931-Linux_amd64.run -O virtualbox.run
O próximo passo é tornar o arquivo baixado executável, execute o comando:
$ chmod +x virtualbox.run
Depois instale com:
$ sudo ./virtualbox.run
O VirtualBox é um programa de virtualização da Oracle que permite instalar e executar diferentes sistemas operacionais em um único computador sem complicações. Com ele, o usuário pode executar por exemplo o Linux dentro do Windows, o Windows dentro do Mac, o Mac dentro do Windows e até mesmo todos os sistema suportados dentro de um. Também pode instalar o Android em outras máquinas.
A única limitação para as combinações são a sua criatividade e o hardware de seu computador. Ele basicamente pode ser instalado no Windows, Linux (Ubuntu), Soláris e Mac. Depois de instalar o software em qualquer um desses sistemas operacionais, o usuário pode instalar outros dentro dele, criando uma máquina virtual.

Vagrant editar

Instalação
O Vagrant usa o VirtualBox da Oracle ou VMware para criar dinamicamente máquinas virtuais configuráveis, leves e portáteis. Desenvolvedores web usam ambientes virtuais todo dia com suas aplicações web. Desde o EC2 e Rackspace Cloud até soluções especializadas como o EngineYard e o Heroku, a virtualização é a ferramenta preferida para facilitar a implantação e o gerenciamento de infraestrutura. O Vagrant visa usar esses mesmos princípios e colocá-los para trabalhar na parte principal do ciclo de vida da aplicação. Por meio do fornecimento de máquinas virtuais fáceis de configurar, leves, reproduzíveis e portáteis, direcionadas para ambientes de desenvolvimento, o Vagrant ajuda a maximizar a produtividade e a flexibilidade da equipe.
Para instalação do vagrant há duas maneiras, a primeira é:
$ sudo apt-get install vagrant
A segunda maneira é fazendo o download do vagrant a partir do site https://www.vagrantup.com/downloads.html e poteriormente instalar o pacote .deb baixado com o comando:
$ sudo dpkg -i vagrant_1.8.4_x86_64.deb
Para testar o vagrant, execute o comando a seguir e verifique se ele criou um arquivo chamado vagrantfile no diretório onde foi executado o comando:
$ vagant init
Utilização
Um vez instalado ele está disponível para uso, basta abrir o console e digitar:
$ vagant
Será disponibilizado os comandos do vagrant.
Para iniciar o trabalho com o vagrant, crie e acesse um diretório de preferência. Esse diretório que o vagrant utilizará para criar o arquivo de configuração e compartilhar os arquivos com o sistema operacional da sua máquina virtual.
$ mkdir nome_da_sua_pasta
$ cd nome_da_sua_pasta
O vagrant usa o conceito chamado box, que são imagens de sistemas operacionais pré-configurados que vão servir como base para a construção de nossas vms. Basicamente,

existem 3 bases onde podem ser baixadas as boxes para que o vagrant instale no virtualbox ou vmware, sendo a primeira uma base de contribuição para uma diversidade de boxes, a segunda uma base de contribuição específica do PuppetLabs e a terceira uma base pública do próprio vagrant:

Depois de selecionado a box, utilize o vagrant para instalá-la. Caso a seleção seja da base pública do vagrant, instale da seguinte forma:
$ vagant box add "nome_da_box_selecionada" "url"
Verifique se ela foi instalada:
$ vagant box list
Crie o arquivo de configuração do vagrant com:
$ vagant init
Você pode verificar o arquivo, criado em sua pasta, chamado de vagrantfile.
Depois de criado o arquivo de configuração, inicialize sua máquina virtual (VM) com:
$ vagant up
Caso seja de uma das bases de contribuição, instale da seguinte forma:
$ vagrant init "nome_da_box_selecionada"
$ vagrant up --provider "nome_da_ferramenta_virtualbox_ou_vmware"
Para acessar sua máquina virtual, execute:
$ vagrant ssh
Manipulação
Para manipulação do vagrant, alguns comandos são necessários se conhecer.
Para iniciar a configuração de uma VM:
$ vagrant init
Para iniciar uma VM:
$ vagrant up
Para desligar a VM:
$ vagrant halt
Para recarregar uma VM (reboot):
$ vagrant reload
Para suspender uma VM:
$ vagrant suspend
Para fazer resumo de uma vm suspensa:
$ vagrant resume
Para verificar o status de uma VM:
$ vagrant status
Para acessar sua vm:
$ vagrant ssh
Para destruir a VM, apagando ela do seu disco:
$ vagrant destroy
Para outros comandos e ajuda:
$ vagrant help
Arquivo de Configuração
Feito esses procedimentos, poderá perceber algumas configurações já definidas por padrão no seu arquivo de configuração, o vagrantfile. Assim poderá adicionar mais algumas configurações que o vagrant fará perante sua VM.
Aqui, temos um exemplo de configuração para uma VM, uma configuração que cria uma máquina virtual baseada no box centos6x84, configura um encaminhamento de portas da porta 80 no guest (VM) para porta 8080 em um host local (UBUNTU), isto significa que você poderá acessar a aplicação da VM como se estivesse rodando localmente na porta 8080.
Além disto, é criada uma segunda interface de rede, em modo rede privada com o endereço IP 192.168.50.20 para comunicação futura com outra máquina.
Também nesse exemplo mostra sendo setado a quantidade processadores e a quantidade de memória destinada para sua VM.
Além destas configurações, existem uma infinidade de configurações que pode ser destinada para sua VM. Pode-se verificar essas configurações na documentação oficial do vagrant:
https://www.vagrantup.com/docs/
Abaixo temos o exemplo de configuração do vagrant citado acima para uma VM:
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

      config.vm.hostname = "apache.hacklab"
      config.vm.box = "centos6x64"
      config.vm.network "forwarded_port", guest: 80, host: 8080
      config.vm.network "private_network", ip: "192.168.50.20"

      config.vm.provider "virtualbox" do |virtualbox|
          virtualbox.customize [ "modifyvm", :id, "--cpus", "1" ]
          virtualbox.customize [ "modifyvm", :id, "--memory", "600" ]
      end
end

Puppet editar

Instalação
O puppet necessitará de sua instalação no sistema operacional de sua máquina virtual e não na máquina local. Dependendo da box utilizada com o vagrant, ela já virá com o puppet já instalado, não necessitando sua instalação. Caso não venha com o puppet instalado então pode proceder com os procedimentos de instalação do puppet agent.
Primeiramente, é necessário verificar qual versão do sistema operacional baseado em debian utiliazado, para fazer o download da versão correta. Assim verifique a versão no site oficial do puppet:
https://apt.puppetlabs.com/?_ga=1.210616021.1176554451.1460494622.
Depois disso, uma vez na máquina virtual, baixe a versão correta e proceda com a instalação com os comandos:
$ wget https://apt.puppetlabs.com/puppetlabs-nome_da_release.deb
$ sudo dpkg -i puppetlabs-nome_da_release.deb
Como exemplo para uma versão ubuntu 14.04 precise 32 bits o comando será:
$ wget https://apt.puppetlabs.com/puppetlabs-release-pc1-precise.deb
$ sudo dpkg -i puppetlabs-release-pc1-precise.deb
$ sudo apt-get update
Utilização
O puppet faz parte de uma nova geração de sistemas para automatização de servidores e serviços, ele nos permite tratar infraestrutura como código.
No puppet ao invés de se descrever as configurações de forma imperativa, você descreve usando uma forma declarativa que nos permite expressar as configurações que os nossos servidores, sistemas e serviços devem ter, fazendo isto através de uma sintaxe simples e prática.
Ele nos oferece duas formas de funcionamento, a primeira podemos chamar de autônoma, neste modo nós criamos e executamos nossas configurações localmente. Além do modo autônomo, o puppet também funciona no modelo cliente (agent) e servidor (master) para distribuir estas configurações para todo o parque de servidores através da rede.
o puppet é composto por um conjunto de recursos (resources), são através destes recursos que construiremos nossas configurações.
Um usuário, um arquivo, um pacote, um serviço que está rodando, uma rotina do cron, um alias de correio e até mesmo a execução de um comando pode ser considerado um recurso para o puppet.
Cada recurso em sua essência é similar a uma classe com seus atributos, por exemplo, um arquivo tem um caminho no filesystem (path), um dono (owner), um dono de grupo (group) e permissões (mode), já um usuário tem nome, id de usuário (uid), id de grupo (gid), acesso shell e diretório home.
O Puppet usa o RAL tanto para ler quanto para modificar o estado de recursos em um sistema. O RAL é a camada de abstração de recursos (Resource Abstraction Layer) do puppet que possui duas características (agrupar e abstrair).
O RAL divide recursos em tipos (resource types), sendo que cada tipo tem seus parâmetros e meta-parâmetros, e provedores (providers). Com isto, o puppet nos permite descrever configurações de uma forma abrangente, possibilitando que tais configurações sejam aplicadas em praticamente qualquer sistema operacional.
Como já mencionado cada recurso é uma instância de algum tipo, e cada tipo de recurso tem um título e seus atributos, os atributos podem ser parâmetros, meta-parâmetros, funções e provedores. Para um tipo de resource, temos o seguinte exemplo:
tipo { 'título':
  param1     => 'valor',
  param2     => 'valor',
  param3     => 'valor',
  metaparam1 => 'valor',
  metaparam2 => 'valor',
  function1  => 'valor',
  function2  => 'valor',
}
Exemplo de resource do tipo usuário (user):
user { 'fagner':
  ensure           => 'present',
  gid              => '500',
  home             => '/home/fagner',
  password         => '$6$BE6a/5SJ$7mSGRgRZBPVRv5p7OkClaTUwx.hwTLzrpVNEbqvyjFy5yFUdGZeL41b76VC6DXV/eFUG.zFS.wkjTpsO.KfCy0',
  password_max_age => '99999',
  password_min_age => '0',
  shell            => '/bin/bash',
  uid              => '500',
  }
Veja que o tipo de recurso é user (usuário), o título é fagner e os atributos são os campos mais a esquerda: ensure, gid, home, password, password_max_age, password_min_age, shell e uid.
Os campos depois da seta (⇒) são os valores destes atributos.
Exemplo de resource do tipo arquivo (file):
file { '/etc/resolv.conf':
  ensure   => 'file',
  content  => '{md5}24ebe9c85187eb484686b5e835eb24ae',
  ctime    => 'Tue May 22 13:32:17 -0300 2016',
  group    => '0',
  mode     => '644',
  mtime    => 'Tue May 22 13:32:17 -0300 2016',
  owner    => '0',
  selrange => 's0',
  selrole  => 'object_r',
  seltype  => 'net_conf_t',
  seluser  => 'system_u',
  type     => 'file',
}
Abstração no Puppet
Com o Puppet nós podemos declarar o que precisamos através de sua sintaxe declarativa, e isto é uma tarefa muito simples.
Uma vez declarada a configuração, o puppet se encarrega de verificar os recursos envolvidos e aplica as mudanças necessárias.
Assim não precisamos dizer se ele tem que usar USERADD, ADDUSER, DELUSER ou USERMOD para criar, modificar ou remover usuários, nem dizer se ele tem que usar o APT, APTITUDE ou YUM para instalar ou remover os pacotes, ele simplesmente recebe o pedido e trata de acordo com os recursos que estão disponíveis. Dessa forma o Puppet nos dá condições de trabalhar em um nível mais alto, mais próximo do entendimento humano, declarando configurações sem especificar comandos com diversos parâmetros.
Dentre os recursos disponíveis no puppet, os principais TIPOS (core resource types) nativos do Puppet são:
  • User
  • Exec
  • Cron
  • File
  • Package
  • Service
  • Notify
  • Host
  • Mailalias
Na documentação do Puppet pode-se verificar 48 tipos de recursos nativos do Puppet disponíveis para o uso imediato: https://docs.puppet.com/puppet/latest/reference/type.html
O puppet também disponibiliza um guia rápido para consulta, com informações sobre os recursos e tipos nativos do puppet exemplificados: https://docs.puppet.com/puppet_core_types_cheatsheet.pdf
Manifests
O Puppet vai muito além destes recursos soltos, ele foi feito para gerenciar grandes parques de servidores com muitos serviços e sistemas rodando, e os manifests podem ser considerados as 'receitas de bolo', as mudanças são o reflexo destes manifests.
Os manifests são programas que escrevemos usando a linguagem do Puppet, e através destes manifests que aplicamos configurações em um node (servidor que roda o puppet agent). São configurações bastante elaborados e detalhadas na linguagem declarariva do Puppet.
Manifests podem ser criados e aplicados no modelo cliente-server (agent/master) ou no modo autônomo (agent).
Os programas escritos com a linguagem do puppet usam a extensão .pp, e para aplicar um manifest basta usar o seguinte comando:
$ puppet apply meu_manifest.pp
A aplicação de um ou vários manifests segue os seguinte passos:
  • O Puppet verifica os Manifests;
  • Os Manifests são compilados em um catálogo;
  • O Puppet processa e aplica o catálogo compilado;
  • O Puppet verifica o estado atual do sistema após aplicar processar e catálogo - se for necessário ele executa novas modificações;
  • O sistema passa a ter um novo estado - refletindo o manifest;
Módulos
Com o Puppet, também podemos trabalhar com módulos para os seus arquivos. Para entender a estrutura de um módulos, podemos observar a seguinte estrutura:
+ manifests
  - nodes.pp
  - site.pp
+ modules
  + module1
    + manifests
      - init.pp
    + files
  + module2
    + manifests
      - init.pp
    + files
Para que os arquivos contidos nos módulos possam ser chamados pelo puppet, é necessário o include no arquivo nodes.pp:
include module1
include module2
Para que seja iniciado pelo puppet, deve ser incluído no arquivo site.pp a importação dos nós, no caso nodes.pp:
import 'nodes.pp'
As classes dos arquivos devem ter o mesmo nome usado para os includes no arquivo nodes.pp e a pasta pode ser usado o mesmo nome da classe. Exemplo:
class ssh {

}
No arquivo nodes.pp:
include ssh
Para executar todos os arquivos contidos nos módulos criados, deve-se estabelecer o local onde foi criado seus módulos, por exemplo se foi no diretório /root/puppet/modules, o comando a ser executado é:
$ puppet apply --modulepath=/root/puppet/modules

Ambiente de Desenvolvimento editar

Primeiramente foi selecionado e baixado uma box para VM, a box selecionada foi a ubuntu/trusty32. Posteriormente, foi criado o vagrantfile e por fim os scripts para automatização da instalação e configuração das dependências para o radar funcionar.

Ambiente com vagrant
Para a criação do ambiente e preparação para o provisionamento, foi realizado o seguinte vagrantfile:
Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty32"
  config.vm.define :web do |web_config|
     web_config.vm.network "private_network", ip: "192.168.50.10"
  end
  config.vm.network "forwarded_port", guest: 8000, host: 8000

  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
  end

  config.vm.provision :shell do |shell|
      shell.inline = "mkdir -p /etc/puppet/modules;
      puppet module install puppetlabs-postgresql;
      puppet module install stankevich-python"
  end
  config.vm.provision :puppet do |puppet|
      puppet.manifests_path = "manifests"
      puppet.manifest_file = "web.pp"
  end
end
Com este vagrantfile, é gerado uma VM com o sistema operacional ubuntu 32 bits, com a definição de um ip para acesso ao localhost da VM pela máquina local, definição de porta para a máquina local, no caso a porta 8000. Também temos a inclusão do natdnshostresolver1 para resolução de conflitos com dns no virtualbox.
Para o provisionamento foram adicionados o provisionamento com shell para a instalação dos módulos do repositório do puppet que facilitam a automatização para determinadas instalações e configurações. Também o provisionamento com o próprio puppet com módulos para execução dos scripts criados:
Automatização com Puppet
Para a automatização, foram criados os seguintes scripts:
Para as instalações:
package { [ "curl", "rabbitmq-server", "libpq-dev", "postgresql-contrib", "postgresql-client-common", "sqlite3" ]:
   ensure => present,
}

class { 'python':
  version    => 'system',
  dev        => true,
  virtualenv => true,
  pip        => true,
}
Esse serve para a criação da pasta no diretório temporário:
file {'/tmp/django_cache':
      ensure => directory,
      mode   => 0755,
}
Para a criação do virtualenv e instalações das dependências do python e instalação do requirements:
python::virtualenv { '/vagrant/radar/radar-parlamentar':
  ensure       => present,
  version      => 'system',
  requirements => '/vagrant/radar/radar-parlamentar/requirements.txt',
  systempkgs   => true,
  distribute   => false,
  owner        => 'vagrant',
  group        => 'vagrant',
  cwd          => '/vagrant/radar/radar-parlamentar',
  timeout      => 0,
}

python::requirements { '/vagrant/radar/radar-parlamentar/requirements.txt':
  virtualenv => '/vagrant/radar/radar-parlamentar',
  owner      => 'vagrant',
  group      => 'vagrant',
}

Para a instalação do postgres e criação do banco com permissão de acesso:

class { 'postgresql::server': }

postgresql::server::db { 'radar':
  user     => 'radar',
  password => postgresql_password('radar', 'radar'),
}

postgresql::server::role { 'radar':
password_hash => postgresql_password('radar', 'radar'),
}

postgresql::server::database_grant { 'radar':
  privilege => 'ALL',
  db        => 'radar',
  role      => 'radar',
}
Execuções do manage.py:
exec { "managepy_syncdb":
  cwd => '/vagrant/radar/radar-parlamentar',
  command => "/usr/bin/python manage.py syncdb --noinput",
}

exec { "managepy_migratedb":
  cwd => '/vagrant/radar/radar-parlamentar',
  command => "/usr/bin/python manage.py migrate",
}

exec { "managepy_runserver":
  cwd => '/vagrant/radar/radar-parlamentar',
  command => "/usr/bin/python manage.py runserver",
}