Attach serial number host name in Ansible etc.

クックパッドの新オフィスでitamaeによる寿司の無限プロビジョニングを体験して、Ansibleのお悩み相談してきた #infra_sushi

I saw an article called.

お悩みの詳細はスライドを見てもらうとして、一つのツールですべて賄おう
として頑張ってしまうと、構成に矛盾が出てしまうので、
適材適所で組み合わせて使わないといけないというのは、完全に正論。

I fully agree with that.

Actually, however, these two problems can be solved even with ansible. (I'm not listening to LT, so I'm sorry if I'm out of your mind)

1. Variable setting for EC2 instance creation -------------------------------------------------------------------------------------------- -------------

[webservers]
prod-web01
prod-web02
prod-web03

[webservers:vars]
ami=ami-785bae10
group_tag=web

When there is already an inventory file called

---
- hosts: webservers
  gather_facts: no  # noにしておくと捗る
  tasks:
    - local_action:
        module: ec2
        (パラメータは一部略しています)
        instance_type: t2.micro
        image: "{{ ami }}"  # inventory
        exact_count: 3
        instance_tags:
          role: "{{group_tag }}" # ここちゃんと使えます
        region: us-east-1
      run_once: true  # 1.7以降で使えます
      register: ec2

local_action so is the host to run the ansible-playbook command, no matter alone is what is written in the hosts, it will be executed in the localhost.

However, if you specify a group that contains multiple hosts, the number of modules specified by local_action will also be executed.

For this reason, introduced from 1.7 run_once use. Run_once is a parameter to make it run only on the host defined at the head of the group. Since it is local_action this time, it sounds to be executed only once on the local host.

Host name automatic number assignment

Although it is automatic numbering, I interpret it as shaking consecutive numbers here.

Numbering is with_indexed_items With, {{ item.0 }} to the index number is, {{ item.1 }} to contains the contents of the list.

- debug: msg="{{ item.1 }} at {{ item.0 }}"
  with_indexed_items: some_list

I will use this.

At first I tried this,

- hostname: name="{{ host_prefix }}-{{ item.0 }}"
  with_indexed_items: play_hosts

If this is the case, for example, if there are 3 units, it will be executed 9 times in total, 3 times for each 3 units.

So, the above-described run_once combine with. However, if it is simply run_once, it can only be set by one unit. Here delegate_to use.

- hostname: name="{{ host_prefix }}-{{ item.0 }}"
  run_once: yes
  delegate_to: "{{ item.1 }}"
  with_indexed_items: play_hosts

By the way, play_hosts has entered the list of hosts to be in this play, is a pre-defined variable from the beginning.

Digression

I hate to start with 0? It's luxury.

- hostname: name="{{ host_prefix }}-{{ item.0 + 1}}"

Summary

So I showed that it can be solved ansible for two problems.

However, as you can see, it is quite tricky as you can see, so we agree that it is better to combine at the right place.

Publicity

ツキノワ In, we are planning a paid seminar of ansible (with hands-on).

If you are interested please contact us from the web page.

How to use sango - Ruby edition

I will explain how to use sango from Ruby.

To use sango in Ruby, follow the procedure below.

  1. Installation of gem
  2. Client implementation

Confirmed environment

  • Ruby 2.0.0
  • Gem 2.0.14
  • Ruby-mqtt 0.3.0

1. Installation of gem

gem install mqtt

As a result, ruby-mqtt it will be installed.

2. Client implementation

MQTT::Client.new(Hostname, ...) ...) `` to create an instance of the MQTT client, to connect if you run connect.

After connect the get or perform Subscribe in, publish or you can go to Publish in.

Connect

The connect part is common to both Pub / Sub.

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

require 'rubygems'
require 'mqtt'

MQTTHOST = "free.mqtt.shiguredo.jp"
USERNAME = "example@github"
PASSWORD = "<password>"

# MQTTに接続するためのクライアントを作成します
client = MQTT::Client.new(
  MQTTHOST,
  :username => USERNAME,
  :password => PASSWORD
)

Subscribe

# 接続します
client.connect do |c|
  # Subscribeします
  TOPIC = "shirou@github/#"
  c.get(TOPIC) do |topic, message|
    puts "#{topic}: #{message}"
  end
end

Publish

# 接続します
client.connect do |c|
  # Publishします
  TOPIC = "shirou@github/a/b"
  c.publish(TOPIC, "message from ruby")
end

reference

Rubydoc
http://rubydoc.info/gems/mqtt

How to use sango - Python

I will explain how to use sango from Python.

To use sango in Ruby, follow the procedure below.

  1. Install libraries with pip
  2. Client implementation

Confirmed environment

  • Python 2.7.8
  • Paho-mqtt 1.0

1. Install libraries with pip

In python paho-mqtt use. It should be noted that, mosquitto but there is also the library, so we already have development finished, please note.

pip install paho-mqtt

2. Client implementation

mqtt.Client() in to create an instance of the MQTT client, and connect if run connect. Since the default is to be connected at 3.1 MQTT, protocol giving the argument that will be connected in the 3.1.1.

After connect the get or perform Subscribe in, publish or you can go to Publish in.

Connect

The Connect part is common to both Pub / Sub.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import paho.mqtt.client as mqtt

MQTTHOST = "free.mqtt.shiguredo.jp"
USERNAME = "example@github"
PASSWORD = "password"

# 3.1.1用のClientを作成します
client = mqtt.Client(protocol=mqtt.MQTTv311)
# ユーザー名とパスワードを設定します
client.username_pw_set(USERNAME, PASSWORD)

# 接続します
client.connect(MQTTHOST)

Subscribe

TOPIC = "shirou@github/a/b"
# Subscribeします
client.subscribe(TOPIC)

# メッセージを待ち受けるループに入ります
client.loop_forever()

Publish

TOPIC = "shirou@github/a/b"
# Publishします
client.publish(TOPIC, "message from python")

# そのままだとすぐにプロセスが終了してしまいますので、Publishし終わるまで待ちます
import time
time.sleep(0.05)

How to use sango - JavaScript WebSocket editing

I will explain how to use sango from browser's JavaScript.

To use sango using JavaScript from the browser, use WebSocket.

When opening MQTT connection information on sango's dashboard, information on "WebSocket connection destination" is described.

WebSocket接続先 : ws://example.shiguredo.jp:8080/mqtt

Let's make a note of this.

1. Implement JavaScript

from Paho mqttws31.js download, to read Leave aside.

2. Client implementation

The Connect part is common to both Pub / Sub.

In other languages, if you do not specify ClientID, most of them generate random character strings, but in JavaScript it is necessary to specify them yourself. Math.random() to use, etc., I think whether it is better to have a function that generates a random string.

Connect

var client; // MQTTのクライアントです
var clientId = "clientid-test"; // ClientIDを指定します。

function connect(){
    var user_name = "example@github";
    var pass = "<password>";
    var wsurl = "ws://example.shiguredo.jp:8080/mqtt";

    // WebSocketURLとClientIDからMQTT Clientを作成します
    client = new Paho.MQTT.Client(wsurl, clientId);

    // connectします
    client.connect({userName: user_name, password: pass, onSuccess:onConnect, onFailure: failConnect});
}

// 接続が失敗したら呼び出されます
function failConnect(e) {
    console.log("connect failed");
    console.log(e);
}

// 接続に成功したら呼び出されます
function onConnect() {
    console.log("onConnect");
}

Subscribe

client of onMessageArrived to register a callback function, subscribe you.

 // メッセージが到着したら呼び出されるコールバック関数
 function onMessageArrived(message) {
     console.log("onMessageArrived:"+message.payloadString);
 }

function subscribe(){
    // コールバック関数を登録します
    client.onMessageArrived = onMessageArrived;

    var topic = "example@github/a/b";
    // Subscribeします
    client.subscribe(topic);
}

Publish

Paho.MQTT.Message to create a message in, of Client send calls the method.

function publish(){
    var topic = "example@github/a/b";
    message = new Paho.MQTT.Message("Hello");
    message.destinationName = topic;
    client.send(message);
}

How to use sango - Java

I will explain how to use sango from Java.

Follow the procedure below.

  1. Get Java library
  2. Implement client

Confirmed environment

  • Java 1.8 SE
  • Mqtt-client 0.4.0

1. Get Java library

Pahoのリリースディレクトリ to download the mqtt-client-0.4.0.jar from.

Alternatively, describe pom.xml as follows.

<project>
<repositories>
    <repository>
        <id>Eclipse Paho Repo</id>
        <url>https://repo.eclipse.org/content/repositories/paho-releases/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>org.eclipse.paho</groupId>
        <artifactId>mqtt-client</artifactId>
        <version>0.4.0</version>
    </dependency>
</dependencies>
</project>

2. Client implementation

Connect

The Connect part is common to both Pub / Sub.

In Java, a class that implements the MqttCallback interface and message arrival setCallback specified in. This time, MQTT class implemented MqttCallback, but it is also possible to implement it in another class.

The MqttCallback interface must implement the following three methods.

  • ConnectionLost
  • DeliveryComplete
  • MessageArrived

In other languages, ClientId is randomly set in some languages, but in the Java language library you need to explicitly specify ClientId. In the sample of this time we made it a fixed value, but I think whether it is better to actually set a random character string.

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;

public class MQTT implements MqttCallback{
    // MQTT Clientをクラスに持たせています
    MqttClient client;

    public void Connect(String hostname, int port, String userName, String password) throws MqttException{
        // 接続先をURIとして設定します
        String brokerURI = "tcp://" + hostname + ":" + port;

        // クライアントIDを設定します。
        String clientId = "test-client";

        // MQTT Clientのインスタンスを作成します。
        client = new MqttClient(brokerURI, clientId);

        // 接続設定をします
        MqttConnectOptions opts = new MqttConnectOptions();
        opts.setUserName(userName);
        opts.setPassword(password.toCharArray());

        // MqttCallbackを設定します。今回はこのクラス自身が実装しています
        client.setCallback(this);

        // Connectします
        client.connect(opts);
    }

Subscribe

subscribe calls.

// メッセージが到着するとこのCallbackメソッドが呼ばれます
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
    System.out.println(message);
}

public void Subscribe(String topic, int qos) throws MqttException{
     client.subscribe(topic, qos);
}

Since you have to specify the MqttCallback at the location of the Connect at setCallback, when a message arrives in the Subscribe Topic, messageArrived method is called.

Publish

publish call the.

public void Publish(String topic, String payload, int qos) throws MqttPersistenceException, MqttException{
    MqttMessage message = new MqttMessage(payload.getBytes());
    message.setQos(qos);
    client.publish(topic, message);
}

How to use sango - Golang

I will explain how to use sango from Go language.

To use sango in the Go language, follow the procedure below.

  1. Get library with go get
  2. Client implementation

Confirmed environment

  • Go 1.3
  • Mqtt-golang 4572889 cc 6 f 741 a 6 10 a 3 b b 544 c 90 c 0 3 b f b 763 f

1. Get library with go get

the golang library of Paho Eclipse go get to get in.

go get git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git

2. Client implementation

Connect

The Connect part is common to both Pub / Sub.

package main

import (
    "fmt"
    "log"
    "time"

    MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
)
func main() {
    host := "free.mqtt.shiguredo.jp"
    port := 1883
    user := "example@github"
    password := "<password>"

    // 接続用の設定を作成します
    opts := MQTT.NewClientOptions()
    opts.SetUsername(user)
    opts.SetPassword(password)

    // golangではURIで接続先を指定します。
    brokerUri := fmt.Sprintf("tcp://%s:%d", host, port)
    opts.AddBroker(brokerUri)

    // 設定を元にクライアントを作成します
    client := MQTT.NewClient(opts)

    // Connectします
    _, err := client.Start()
    if err != nil {
        log.Fatal(err)
    }
}

Subscribe

Subscribe is StartSubscription and passes a callback function to a function called.

func onMessageReceived(client *MQTT.MqttClient, message MQTT.Message) {
    fmt.Printf("Received message on topic: %s\n", message.Topic())
    fmt.Printf("Message: %s\n", message.Payload())
}

func Subscribe(client *MQTT.MqttClient) error {
    topic := "example@github/a/b"
    qos := 0

    // Subscribeするtopicを設定します
    topicFilter, err := MQTT.NewTopicFilter(topic, byte(qos))
    if err != nil {
        return err
    }

    // Subscribeします
    // onMessageReceived はメッセージが届いたら呼び出されるコールバックです
    _, err = client.StartSubscription(onMessageReceived, topicFilter)
    if err != nil {
        return err
    }

    // そのままではプロセスが終わってしまいますので、待ち受けます
    for {
        time.Sleep(1 * time.Second)
    }
}

Publish

The Publish Publish use. Alternatively, use the MQTT.Message PublishMessage There is also a function called.

func Publish(client *MQTT.MqttClient) error {
    topic := "example@github/a/b"
    qos := 0
    message := "MQTT from golang"

    receipt := client.Publish(MQTT.QoS(qos), topic, message)
    <-receipt  // Publish成功を待ち受ける

    return nil
}

Make MicroService that uses MQTT in sango and mqttcli

MicroService but is where subtly becoming Bazuri, here sango and mqttcli in MQTT Let's make a MicroService with.

  • (Note 1 : MicroService of the definition does not know well)
  • (Note 2 : Since a place often beat and mqttcli Wawari, please look in mind a wide even if every other problem)

Preparation

A small preparation is necessary beforehand.

1. Create sango account

First sango to create an account from. You can create it immediately if you have a GitHub account.

When you open the dashboard,

  • Destination : Mqtt: // <MQTT server address>: 1883
  • Access destination topic : shirou Atto github / #
  • Username : shirou Atto github
  • Password : secret <- appears when you click

So I will remember these.

2. Download mqttcli

https://github.com/shirou/mqttcli traced from drone.io to Because it is binary for various architecture is put , I will download it.

If necessary, chmod ugo+x please with the execution authority, and the like.

3. Describe the configuration file

~/.mqttcli.cfg to create, and then described the following contents.

{
  "host": "mqtt.shiguredo.jp", <--- MQTT server address
  "username": "shirou@github",  <--- user name
  "password": "<password>"
}

That's all there is to it. Let's test the connection.

4. Connection test

mqttcli sub -t "shirou@github/#" -d

Beat it,

INFO[0000] Broker URI: tcp://mqtt.shiguredo.jp:1883
INFO[0000] Connecting...
INFO[0000] Connected
INFO[0000] Topic: shirou@github/#

And if it comes out OK.

Make a MircoService

Let's create a MicroService.

$ tail -f /var/nginx/access.log | mqttcli pub -t "shirou@github/nginx/log" -s

sending nginx log to "shirou@github/nginx/log" topic is ready to serve MicroService.

Please input as follows on another terminal. The log of nginx is described in LTSV. Please change other people as appropriate

$ mqttcli sub -t "shirou@github/nginx/log" | \
  grep "status:500" --line-buffered | \
  mqttcli pub -t "shirou@github/nginx/log/500" -s

Yes, this send request to "shirou@github/nginx/log/500" only status is 500 were MicroService is finished. ( --line-bufferd not put and do not know immediately is buffered)

As you like the rest. For example, you can write it to a file.

$ mqttcli sub -t "shirou@github/nginx/log/500" > /var/log/error.log

Of course, all of these can be executed on the same host, or they can be different hosts.

further

Currently sango can only have up to six connections. However, more connections can be made in the paid version that is planned in the future (currently 50 plans).

Then,

  • We handle other status codes as well as 400
  • Send multiple server logs to the same topic and put together
  • It not only exports to a file, but also mails it and sends it to slack

You can create a MicroService such as. Topics also nginx/log/4/400 400`` and nginx/log/4/400 400`` leave sent as a separate that, nginx/log/4/# summarized to subscribe , And so on.

These MicroService topic against and Topic Pub/Sub , and # and + the when combined in various forms, I think in many more things can be.

Summary

This time using sango and mqttcli

  1. Send log of nginx
  2. Retrieve only the request with the status 500 and resubmit it
  3. Receive and write to file

We have created three MicroServices.

Since it is standard input and output, various applications work well. Of course there is no problem separating the hosts. Moreover, the response is very fast with lightweight MQTT.

Please use sango and try out various things!

Digression

In this way, MQTT seems to be compatible with streaming processing, is not it? spark streaming Toka?

Try using vultr

But was using DigitalOcean until now, vultr to know while too late that that place is moving from about six months ago in the Tokyo region, try It is.

With the cheapest plan

  • $ 5 / month or $ 0.007 / hour
  • Memory : 768M
  • SSD : 15GB
  • Band : 1000GB (200GB it's Tokyo Region)

is. SSD is nice, is not it? Digital Ocean is SSD 20 GB, but instead memory is 512 MB. I do not need disk space, so I'm happy that more memory is available.

Tokyo Region

The result of ping is

round-trip min/avg/max/stddev = 13.621/14.480/15.430/0.556 ms

And average 14 msec! It is truly a Tokyo region.

In Digital Ocean's Singapore

round-trip min/avg/max/stddev = 83.428/89.205/129.731/12.856 ms

And an average of 89 msec. It is far from comparison with vultr.

Windows also supports

Vultr corresponds to the following image.

  • CentOS 7/6/5
  • Ubuntu 14.04 / 12.04
  • Debian 7
  • FreeBSD 10
  • Windows 2012 R2

In addition to that, it corresponds to Custom Image. Especially Windows image can be used is big.

Startup script

There is a "startup script" which runs the startup script specified at instance creation.

I am trying to create and use the following scripts. It is a flow to retrieve keys from github and register. I have confirmed the operation with ubuntu, but I think that it is different in CentOS etc.

With this you can set up the user immediately. It might be a good idea to try using ansible-pull.

Actually it would be nice if you could register keys in advance like Digital Ocean.

#!/bin/sh

USER=shirou
GITHUBUSER=shirou

useradd ${USER} -m
wget https://github.com/${GITHUBUSER}.keys -O /tmp/${GITHUBUSER}.keys
mkdir -p /home/${USER}/.ssh
chmod 700 /home/${USER}/.ssh
cat /tmp/${GITHUBUSER}.keys >> /home/${USER}/.ssh/authorized_keys
chmod 600 /home/${USER}/.ssh/authorized_keys
chown -R ${USER} /home/${USER}
rm -f /tmp/${GITHUBUSER}.keys

# =============
# SSH Support
# =============
echo "${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
echo "PermitRootLogin no" >> /etc/ssh/sshd_config
echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
/etc/init.d/ssh restart

So what?

It is cheap, IPv6 compliant, and it is fast in the Tokyo region no matter what. I have a web console, but this behavior is pretty crispy.

Furthermore, although it is still in beta, there is also a snapshot function, and the API is complete. There is also Two Factor Auth.

Although I am trying it, I think that it is quite attractive at the moment.

Is it difficult to start up? Of course it is so fast as SSD, but I will feel late when I get used to the speed of GCE. What about the key part above?

It should be noted that, こちら registered have just kicking and from, so you enter $ 10, thank you by all means from here ~.

As A Service MQTT : we help the Sango release of

From today August 29, 2014, the parent company of 時雨堂 began providing a "Sango", which is a service that you can easily use the MQTT on the Internet.

https://sango.shiguredo.jp

The dashboard looks something like this and it shows the connection information for MQTT.

2014/08/29/sango-dashboard.png

If you have a GitHub account, you can start using it immediately. Currently only free plan is offered, plus we plan to start the 500 yen plan in October. Free plans will be offered for a long time.

For more information プレスリリース as Business Partners will look at, but here are the lightly usage and contents.

How to use Sango

Sango can log in easily with GitHub account.

When you log MQTT接続情報 as,

- 接続先 : mqtt://<MQTTサーバーのアドレス>:1883
- WebSocket接続先:  ws://<MQTTサーバーのアドレス>:8080/mqtt
- アクセス先トピック: shirou@github/#
- ユーザー名: shirou@github
- パスワード: ひみつ  <-- クリックすると表示されます

Will come out. Please note that each topic is assigned to each user.

You can easily try it from the command line using mosquitto. (Please install mosquitto in advance)

mosquitto_sub \
    -h <MQTTサーバーのアドレス> \
    -u shirou@github \
    -t "shirou@github/#"
    -P <パスワード>

If you, shirou@github/# will receive the sent to the message. Please do not send it to anything other than the topic assigned to each user.

Execute sub, from another terminal

echo "MQTT is Cooooool" |
mosquitto_pub \
    -h <MQTTサーバーのアドレス> \
    -u shirou@github \
    -t "shirou@github/#"
    -P <パスワード> \
    -s

If you do, it will be displayed in the part you are sub in a while ago.

Inside of Sango

Sango

  • MQTT Server written in Erlang / OTP
  • Web application written in Go language

It consists of two functions. We ツキノワ was responsible for this Web app part.

What you're doing is a big deal, just hitting the API on the MQTT Server side. There was also a sample on OAuth revel's site, and I could implement it in a moment.

Composition of contents

The following libraries are used.

For revel revelの紹介 please refer to the article.

It is gorm, but it was quite easy to use. This time the table structure is simple, but still we could implement SQL without writing a line.

After that, at the part that makes the CLI

I used it. I hope this is easy to use as well.

Summary

"As A Service MQTT : it was to help release of Sango."

This article briefly introduced Sango's introduction, usage, and its contents.

I think MQTT is a protocol that can be used in various ways. How about using Sango to try out the idea easily?

the next deployment

Currently only free plans are available, but we plan to start a 500 yen plan in October.

The 500 yen plan is

  • The number of concurrent connections : Can be used up to 10 connection
  • QoS : corresponding to 1, 2
  • Security : TLS support
  • Monthly maximum number of messages : 100,000

It is planned to be used more practically, and so on. Please expect it.

Introduction of golang's web framework, revel

There are various web application frameworks in golang. Which among them is good is all that they are keenly developing, and new ones are coming out so I can not say anything.

Among them, revel that the framework is there from sintering構昔. This is a heavyweight framework that is comprehensive enough to compare with Rails.

If it is a thin framework, I feel like I can use the standard net / http, so I am currently using this revel to actually make it.

In addition, I have referred to the following pages.

Characteristic

Although there are various features, I will introduce the good part of revel which is not mentioned in the above site here.

  • Deployment zip file is completed with one command
  • I18n compatible
  • You can put hooks in various places
  • You can specify an execution environment such as dev / prod. Moreover, it is easy to write config

In addition to redis also session management and job execution and are also compatible with validation, I have a lot such as WebSocket support, there is マニュアル get a look at the I think whether it is easier to understand.

Deployment zip file is completed with one command

revel package When you run the command, you or tar.gz file is finished. When this is sent to the server and deployed,

.
|-- run.bat
|-- run.sh
|-- sample-app
|-- sample-app.log
|-- sample-app.tar.gz
`-- src
    `-- github.com
        |-- revel
        `-- tsukinowasha
             `-- sample-app

The file will be expanded to feel like. After the run.sh if you run, you can run immediately.

By the way, it is only revel and the application below src. Other than that is not included. Below revel there are conf files, template files, etc., not including binary and go files. All of the following applications, including go files, are included. Since revel builds at run time, I think that this is useless.

bindata might be better methods that package to one of the binary, where you think the problem Ikana in this method is. However, revel package because the system is also included source code, I think it is better to use the bindata if that bad.

I18n compatible

message/labes.ja and message/labes.ja to prepare the file you ECTS called, will return the message according to the language setting of the browser.

The messages.ja file is as follows. (It does not matter if it is unique even if it is not separated by.)

mode.dev.label=検証系
login.title=ログイン

In this way, with the template

<h3>{{msg . "login.title" }}</h3>

If you write, etc, you will see the contents of messages.ja and messages.en depending on the language.

Hook

revel is Interceptor that, there is a Hook that Shikome to various timing in the request.

For example, if you do the following, the checkUser function runs before processing the request.

func checkUser(c *revel.Controller) revel.Result {
    if user := connected(c); user == nil {
       c.Flash.Error("Please log in first")
       return c.Redirect(App.Index)
    }
  return nil
}

func init() {
   revel.InterceptFunc(checkUser, revel.BEFORE, &Users{})
}

revel.BEFORE is specified timing. Others include PANIC which is called at AFTER and panic.

Using this makes it possible to share the description and it is useful.

Execution environment control

revel run When you run the command dev rise in the mode, the log displays the hot reloading or become details or enabled, debug display will be in and out.

This area is conf/app.conf It's in the written.

[dev]
mode.dev=true
results.pretty=true
watch=true

db.host = localhost

[prod]
mode.dev=false
results.pretty=false
watch=false

db.host = prod-db.example.com

In this way, you can select execution environment by sectioning by section. [staging] You can also be added, and the like. This can change the behavior.

db.host part that is determined by adding your own. From within code

dbhost := revel.Config.StringDefault("db.host", "localhost")

As you can get it, you can say that if you use this you will connect to a different host for each environment. (In the above example, default is set to localhost)

By the way, the revel package When you create a package at the command, and the script has been created so as to rise in the prod environment. A little care is convenient.

Custom Functions in templates

Like this in the revel.TemplateFuncs Once you have defined the function to, you can use in the template.

func init() {
             revel.TemplateFuncs["eq"] = func(a, b interface{})
             bool { return a == b }
}

I am addicted to it

Lastly I will introduce you what I am into when using revel. Although there are only about one at the moment. I'll update it.

Init timing

When I tried to rewrite variables in package at startup, I did not change it properly. It was changed properly by specifying it with OnAppStart.

var DB = "localhost"

func init() {
   // これは期待通りに動かない
   // DB := revel.Config.StringDefault("db.host", "localhost")
   revel.OnAppStart(changeDBHostFunc)  // 関数を登録
}

Summary

In this article I introduced various functions of revel. Is not it quite convenient?

Revel is only called heavyweight and has abundant functions. For me, learning costs are not very high, I can start using it quite easily. Then, you do not have to implement the function yourself or add it later, you can develop it comfortably.

It should be noted that, as of the same position is beego There is, but this has not yet been tried.