hbstudy#82 に遅刻参加してきました

hbstudy#82 とは

詳しくは下記リンクより。

hbstudy.connpass.com

このエントリについて

正直短くなります。
途中参加だったこともあり、全てを聞け無かったこと。各種技術について知らないことも多かったので、まずは備忘録まで。

k8s, Rancher の話について

私が聞けたのは最後のこの発表だけだった。開発に至る経緯からモニタリングまでのお話を聞くことが出来た。

Ranche 導入のきっかけ

Docker を導入したら、あまりにもコンテナが乱立した > 統合管理環境が欲しかった > Rancher 導入へ

Docker on Docker について

Docker on Docker を導入しているとのこと。
メリット * コンソールやSSHなどが分離されている。アプリケーションの動いているコンテナがお亡くなりなってもコンソールはとれる デメリット * 特に言及は無かった

Docker on Docker と言う使い方を考えたことも無かったので新しい刺激になってうれしかった。

管理系(サービスとして表に出ているサーバを管理するサーバ)について

これに使われているサービスも Docker を使っている。と言う事は、Rancher も使っている。とのこと。

Docker & Rancher すごい!

オンプレミスの強み

Blue, Green デプロイや Immutable Infrastructure なんかを実施するとき、1世代前のコンテナを時期リリースまでおなかの中で抱えておく事が出来る。その為のリソースはちゃんと確保している。その為切り戻しが一瞬で出来るようになっている。
AWSなどで実施しようとするといくら請求が来るか恐ろしい。

ShellScript 乱立

数えた結果100以上のShellScriptが出来上がったらしい。その辺をそのままにしておくと秘伝のたれになりかねないので、envsubstを使って共通化を謀ったらしい。

通化はいいことですね。

データについて

結局データの永続化は外部に出していた。

今はまだそうならざるを得ないのだなと感じた。Docker でデータの永続化が出来る時代はもう少し先???

DevOps な話について

出てきた。具体的な話は忘れたが、開発者も運用に入るようにしていた様だ。

SRE について

話が出てこなかったように思う。
個人的には SRE 大全 とあったのでもう少しシステムから離れた話が聞けるのではと思っていた。

会社内で Vision を定義して、それに沿って SREDevOps を定義していく必要がある。と個人的に解釈した。

Vision 大事!

サービスが大きくなりすぎて結局運用部隊を分けたくならないかについて

その為のマイクロサービスです。

なるほど。

一つの公開しているサービスを持っているチームがあって、それがスケールするとサービス内のマイクロサービスが大きくなってしまい、結局運用分離が発生するのでは無いかについては聞くことが出来無かった。

総じて

サービスのシステムや技術の話はすごく面白かった。ただ、個人的には SRE の SLI やエラーバジェットとってるとかその辺の事をもう少し突っ込んで聞きたかった。

以上。

NetOpsCoding#5 Mini Report

NetOpsCoding Report

I went to NetOpsCoding#5 in Japan at 10th of October in 2017.

スポンサー

Food: Cisco Drink: CTC America

自動化と監視の推進奮闘記

Presented by 安藤格也(ヤフー株式会社)

自動化

自動化はどこでも課題になっているようだ
古い機器も扱っているのでAPIが無いなど問題もある

マルチベンダーを利用している > 抽象化 > 自動化 で取り組んだ

Python からNW_Library があり、それを利用

NETCONF でとれるデータ != 構造化されたデータ

CLI で抽象化を試すことに

OSSを利用することで、コマンドでのOSの意識を消す事も抽象化により可能になった

CLI の結果を解析するライブラリ
google/textfsm 便利らしい

今回は、設定の自動化は fabric(python) でオペレーションを関数化したようだ

結果として、抽象化はうまく出来た用でした

Q & A

  1. CLI ベースで抽象化しているので、OSのバージョンアップにどう対応しているのか?
  2. ユニットテストをしっかり作ったので、OSのバージョンアップに追従出来るようになっている

  3. Ansible ではないのはなぜ?

  4. 用件を定義する中で、Ansible は駄目だと出てきた。(詳しい話は忘れた) (CLIベースで抽象化すると決まったのに、API経由しか無かったりなど)

  5. 誰がメンテするんですか問題

  6. 勉強会とドキュメント

監視

  • Prometheus

prometheus.io

  • Alertmanager

github.com

  • Grafana

github.com

Prometheus は集約できる
拠点ごとに置いた Prometheus を中央の Prometheus に集約するなど

Ansible x NAPALM x NSO 解説・比較パネルディスカッション

運用自動化ツールが続々リリース
これは!
ネットワーク運用変革時代!!!

横地 晃(株式会社エーピーコミュニケーションズ)

  • NAPALM は Python のライブラリ
  • Ansible 構成管理ツール

Ansible

モジュールの対応状況がベンダーやOSによってまちまち

簡単な Ansible でのネットワーク設定などの紹介

Ansible 2.4 新モジュールから抽象化するような機能が出てきた
- net_* モジュール

NAPALM

多機能で暑い抽象化 Python ライブラリ

github.com

情報取得メソッドはよく見ておこう。バージョンが上がるときに変わることが多々ある

NAPALM は show コマンドの結果を parse してくれる

NAPALM は Validate 機能がある
たとえば、YAML で Traceroute の path を定義しておいて、その通りになるかどうかテストできる

岩本 彰 (Cisco Systems)

TAC です。値段聞かれても答えれませんw

Network Service Orchestrator
略して、NSO
全てのコンフィグはモデルベース

果たして、古い IOS でも NSO は対応しているのだろうか

NSO は、CDB に設定情報を突っ込んでいる。それを、Yang ベースにNEDがデバイス用の設定をつくって、実機に反映させる流れ。その為、設定情報がすでにCDBに存在していればデバイスに対して何もしない

ディスカッション

記事から削除

最後に

公開が遅れてしまったこと、大変後悔している。個人的な重いとしては勉強会なりセミナーなりが終わった次の日にはアップしていたいのだが、今回は出来なかった。今更ながらでは在るが、個人的備忘録として公開させて頂く。

my vimrc

my vimrc

I want to recording my vimrc here.
I don't want to add comments.

I would like to update my vimrc!

" Configuration file for vim
set modelines=0     " CVE-2007-2438

" Normally we use vim-extensions. If you want true vi-compatibility
" remove change the following statements
set nocompatible    " Use Vim defaults instead of 100% vi compatibility
set backspace=2     " more powerful backspacing

" Don't write backup file if vim is being called by "crontab -e"
au BufWrite /private/tmp/crontab.* set nowritebackup nobackup
" Don't write backup file if vim is being called by "chpass"
au BufWrite /private/etc/pw.* set nowritebackup nobackup

" Basic settings

" タイトルをバッファ名に変更しない
set notitle
set shortmess+=I

" Too fast connect to the tarminal
set ttyfast

" Use 256 colors at the tarminal
set t_Co=256

if has ("viminfo")
  " フォールド設定(未使用)
  " set foldmethod=indent
  set foldmethod=manual
  " set foldopen=all
  " set foldclose=all
endif

" 複数ファイルの編集を可能にする
set hidden

" 内容が変更されたら自動的に再読み込み
set autoread

" Swapを作るまでの時間ms
set updatetime=0

" Unicodeで行末が変になる問題を解決
set ambiwidth=double

" カーソルを常に画面の中央に。
set scrolloff=1000

" C-vの矩形選択で行末より後ろもカーソルを置ける
set virtualedit=block

" コマンド、検索パターンを50まで保存
set history=100

" ------ SEARCH -------
" インクリメンタルサーチを有効に
set incsearch

" 大文字小文字を区別しない
set ignorecase

" 大文字で検索されたら対象を大文字限定にする
set smartcase

" 行末まで検索したら行頭に戻る
set wrapscan

" ----- Format -----
" 自動インデントを有効に
set smartindent
set autoindent

" フォーマット揃えをコメント以外有効にする
set formatoptions-=c

" 括弧の対応をハイライト
set showmatch

" ターミナルの上から貼り付けを許可
" set paste

set shiftwidth=4
set softtabstop=4
set expandtab
set autoindent
set smartindent

augroup fileTypeIndent
  autocmd!
  autocmd BufNewFile,BufRead *.py setlocal tabstop=4 softtabstop=4 shiftwidth=4
  autocmd BufNewFile,BufRead *.html setlocal tabstop=4 softtabstop=4 shiftwidth=4
  autocmd BufNewFile,BufRead *.rb setlocal tabstop=2 softtabstop=2 shiftwidth=2
  autocmd BufNewFile,BufRead *.erb setlocal tabstop=2 softtabstop=2 shiftwidth=2
augroup END

" ----- Look&Feel -----
" TAB可視化
set list
set listchars=tab:>_,trail:-,eol:$
" extends:>>,precedes:<<,nb:%,

" 検索結果をハイライト
set hlsearch

" ルーラー、番号
set ruler
set number

" コマンドラインの高さ
set cmdheight=2

" カーソルラインを表示する
"set cursorline

" ウインドウタイトルを設定する
set title

"自動文字数カウント
augroup WordCount
    autocmd!
    autocmd BufWinEnter,InsertLeave,CursorHold * call WordCount('char')
augroup END
let s:WordCountStr = ''
let s:WordCountDict = {'word': 2, 'char': 3, 'byte': 4}
function! WordCount(...)
    if a:0 == 0
        return s:WordCountStr
    endif
    let cidx = 3
    silent! let cidx = s:WordCountDict[a:1]
    let s:WordCountStr = ''
    let s:saved_status = v:statusmsg
    exec "silent normal! g\<c-g>"
    if v:statusmsg !~ '^--'
        let str = ''
        silent! let str = split(v:statusmsg, ';')[cidx]
        let cur = str2nr(matchstr(str, '\d\+'))
        let end = str2nr(matchstr(str, '\d\+\s*$'))
        if a:1 == 'char'
            " ここで(改行コード数*改行コードサイズ)を'g<C-g>'の文字数から引く
            let cr = &ff == 'dos' ? 2 : 1
            let cur -= cr * (line('.') - 1)
            let end -= cr * line('$')
        endif
        let s:WordCountStr = printf('%d/%d', cur, end)
    endif
    let v:statusmsg = s:saved_status
    return s:WordCountStr
endfunction


" ステータスラインにコマンドを表示
set showcmd
" ステータスラインを常に表示
set laststatus=2
" ファイルナンバー表示
set statusline=[%n]
" ホスト名表示
set statusline+=%{matchstr(hostname(),'__w__+')}@
" ファイル名表示
set statusline+=%<%F
" 変更チェックの表示
set statusline+=%m
" 読み込み専用かどうか表示
set statusline+=%r
" ヘルプページなら[HELP]と表示
set statusline+=%h
" プレビューウィンドウなら[Preview]と表示
set statusline+=%w
" ファイルフォーマット表示
set statusline+=[%{&fileformat}]
" 文字コード表示
set statusline+=[%{has('multi_byte')&&\&fileencoding!=''?&fileencoding:&encoding}]
" ファイルタイプ表示
set statusline+=%y
" ここからツールバー右側
set statusline+=%=
" skk.vimの状態
set statusline+=%{exists('*SkkGetModeStr')?SkkGetModeStr():''}
" 文字バイト数/カラム番号
set statusline+=[%{col('.')-1}=ASCII=%B,HEX=%c
" 現在文字列/全体列表示
set statusline+=[C=%c/%{col('$')-1}]
" 現在文字行/全体文字行
set statusline+=[L=%l/%L]
" 現在のファイルの文字数をカウント
set statusline+=[WC=%{exists('*WordCount')?WordCount():[]}]
" 現在行が全体行の何%目か表示
set statusline+=[%p%%]

"-------エンコード------
"エンコード設定
if has('unix')
    set fileformat=unix
    set fileformats=unix,dos,mac
    set fileencoding=utf-8
    set fileencodings=utf-8,iso-2022-jp,cp932,euc-jp
    set termencoding=
elseif has('win32')
    set fileformat=dos
    set fileformats=dos,unix,mac
    set fileencoding=utf-8
    set fileencodings=iso-2022-jp,utf-8,euc-jp,cp932
    set termencoding=
endif

"ファイルタイプに応じて挙動,色を変える
syntax on
filetype plugin on
filetype indent on

" ----- key setting -----
" nmap <UP> k
" nmap <DOWN> j
" vmap <UP> k
" vmap <DOWN> j

" ほかのvimにviminfoを送る
" http://nanasi.jp/articles/howto/editing/rviminfo.html
nmap ,vw :vw<CR>
nmap ,vr :vr<CR>

" 保存
" map jj :w<CR>

" ESC
inoremap jj <ESC>

" 括弧を補完
inoremap ( ()<left>
inoremap [ []<left>
inoremap { {}<left>
inoremap < <><left>

" 挿入モードでのカーソル移動
inoremap <C-j> <Down>
inoremap <C-k> <UP>
inoremap <C-h> <Left>
inoremap <C-l> <Right>

" シングルコーテーション補完
inoremap ' '' <left>

" yanktmpの設定
" vim to vim でコピペ出きるようになる。
" map <silent> sy :call YanktmpYank()<CR>
" map <silent> sp :call YanktmpPaste_p()<CR>
" map <silent> sP :call YanktmpPaste_P()<CR>
" if has("win32")
"       let g:yanktmp_file = TEMP. '/vimyanktmp'
" end

たのしいRuby 読書memo 1.1

たのしいRuby の備忘録

www.amazon.co.jp

1.1 Ruby の実行方法

Ruby を実行するには、Rubyコマンドを使います。
ユーザのホームディレクトリにhello.rbというRubyのプログラムがあった場合、以下のように実行します。

$ ruby hello.rb

これだけです。
hello.rb
の中身は今は特に気にしなくて良いです。

ついでに、irb も押さえておきます。
irb とは、 Interactive Rubyの略です。
ここに書いています。

library irb (Ruby 2.4.0)

どこの場所にいても、irb で起動します。
大きなプログラムの実行にはあまり向いていないです。
小さなプログラムをちょっと試すのに良いです。

ここは以上です。

tmux memo

tmux memo

Boot tmux

$ tmux

Prefix key (Default)

C-b

Window customize short cut

key sub command meaning
c new window open new window
n next-window move next window
p previous-window move previous window
, rename-window rename window
0-9 select-window move to 0-9 window number
l last-window move to last window
w choose-window display the window list then select one
& kill-window kill the present window

Pane operation key (Push below keys after prefix key)

key sub command meaning
split-window split window up/down
% split-window -h split window left/right
x kill-pane delete present pain
q display-panes display pain number
o select-pane -t :.+ move next pain
; last-pane move last pain
cursor select-pain -[U|D|L|R] move [above|below|left|light] pain
{ swap-pain -U swap pane
} swap-pain -D swap pane
C-(cursor) resize-pane -[U|D|L|R] change pane size

How to use the Rails API

目的

  • Rails API の勉強
  • 備忘録
  • 本当は API Client を Ruby で作ってみたかった

Vagrant up

環境をまっさらに戻せるように Vagrant up で作っていく。
Vagrant up が出来る環境を作るのは、機種依存もあるので、割愛します。

とはいえ参考情報として、私の環境を晒すと、、、

$ cat /etc/issue
Ubuntu 14.04.5 LTS \n \l

$ uname -a
Linux takashi-desktop 3.13.0-123-generic #172-Ubuntu SMP Mon Jun 26 18:04:35 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ vagrant -v
Vagrant 1.9.5

$ git --version
git version 2.13.0

$ VBoxManage -v
5.1.22r115126

立ち上げよう

参考

app.vagrantup.com

vagrant init ubuntu/xenial64

出来上がった、 Vagrantfile を編集して、 public network が使えるようにしよう。
下記一文をコメントイン

config.vm.network "public_network"

で、起動

vagrant up

Ruby をインストール

Ruby をインストールしていく

ホストにログイン

vagrant ssh

しなくてもいいが、バージョン確認

ubuntu@ubuntu-xenial:~$ cat /etc/issue
Ubuntu 16.04.3 LTS \n \l

ubuntu@ubuntu-xenial:~$ git --version
git version 2.7.4
ubuntu@ubuntu-xenial:~$ 
# Fix バージョンぽい

Git 脆弱性対応情報
USN-3387-1: Git vulnerability | Ubuntu

rbenv をインストール

ここを参考

https://github.com/rbenv/rbenv#installation

ubuntu@ubuntu-xenial:~$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
ubuntu@ubuntu-xenial:~$ cd ~/.rbenv && src/configure && make -C src
ubuntu@ubuntu-xenial:~/.rbenv$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
ubuntu@ubuntu-xenial:~/.rbenv$ source ~/.bash_profile 
ubuntu@ubuntu-xenial:~/.rbenv$ ~/.rbenv/bin/rbenv init
# Load rbenv automatically by appending
# the following to ~/.bash_profile:

eval "$(rbenv init -)"

ubuntu@ubuntu-xenial:~/.rbenv$ 
ubuntu@ubuntu-xenial:~/.rbenv$ type rbenv
rbenv is /home/ubuntu/.rbenv/bin/rbenv
ubuntu@ubuntu-xenial:~/.rbenv$ 

ruby-build をインストール

ubuntu@ubuntu-xenial:~/.rbenv$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
ubuntu@ubuntu-xenial:~/.rbenv$ rbenv 
rbenv 1.1.1-2-g615f844
Usage: rbenv <command> [<args>]

Some useful rbenv commands are:
   commands    List all available rbenv commands
   local       Set or show the local application-specific Ruby version
   global      Set or show the global Ruby version
   shell       Set or show the shell-specific Ruby version
   install     Install a Ruby version using ruby-build
   uninstall   Uninstall a specific Ruby version
   rehash      Rehash rbenv shims (run this after installing executables)
   version     Show the current Ruby version and its origin
   versions    List all Ruby versions available to rbenv
   which       Display the full path to an executable
   whence      List all Ruby versions that contain the given executable

See `rbenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/rbenv/rbenv#readme
ubuntu@ubuntu-xenial:~/.rbenv$ 

これで、rbenv install コマンドが使えるようになった。

Ruby 2.3.1 をインストール

ubuntu@ubuntu-xenial:~/.rbenv$ rbenv install -l | grep 2.3.1
  2.3.1
ubuntu@ubuntu-xenial:~/.rbenv$ rbenv install 2.3.1
Downloading ruby-2.3.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.bz2
Installing ruby-2.3.1...

BUILD FAILED (Ubuntu 16.04 using ruby-build 20170726-2-g254728e)

Inspect or clean up the working tree at /tmp/ruby-build.20170821144450.9867
Results logged to /tmp/ruby-build.20170821144450.9867.log

Last 10 log lines:
The Ruby openssl extension was not compiled.
The Ruby readline extension was not compiled.
The Ruby zlib extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `apt-get install -y libssl-dev libreadline-dev zlib1g-dev` to fetch missing dependencies.

Configure options used:
  --prefix=/home/ubuntu/.rbenv/versions/2.3.1
  LDFLAGS=-L/home/ubuntu/.rbenv/versions/2.3.1/lib 
  CPPFLAGS=-I/home/ubuntu/.rbenv/versions/2.3.1/include 
ubuntu@ubuntu-xenial:~/.rbenv$ 

# error が出てビルドが止まった。
# Try running を実施してみる。

ubuntu@ubuntu-xenial:~/.rbenv$ sudo apt-get install -y libssl-dev libreadline-dev zlib1g-dev
ubuntu@ubuntu-xenial:~/.rbenv$ rbenv install 2.3.1
Downloading ruby-2.3.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.bz2
Installing ruby-2.3.1...
Installed ruby-2.3.1 to /home/ubuntu/.rbenv/versions/2.3.1

ubuntu@ubuntu-xenial:~/.rbenv$ 
ubuntu@ubuntu-xenial:~/.rbenv$ ruby -v
The program 'ruby' is currently not installed. You can install it by typing:
sudo apt install ruby
ubuntu@ubuntu-xenial:~/.rbenv$ rbenv which ruby
/home/ubuntu/.rbenv/versions/2.3.1/bin/ruby
ubuntu@ubuntu-xenial:~/.rbenv$ vim ~/.bash_profile 
ubuntu@ubuntu-xenial:~$ cat ~/.bash_profile 
ruby="$HOME/.rbenv/versions/2.3.1/bin/"
export PATH="$HOME/.rbenv/bin:${ruby}:$PATH"
ubuntu@ubuntu-xenial:~$ 
ubuntu@ubuntu-xenial:~/.rbenv$ source ~/.bash_profile
ubuntu@ubuntu-xenial:~$ echo $PATH
/home/ubuntu/.rbenv/bin:/home/ubuntu/.rbenv/versions/2.3.1/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ubuntu@ubuntu-xenial:~$ 
ubuntu@ubuntu-xenial:~$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
ubuntu@ubuntu-xenial:~$ 

あまりイケてないけど、Ruby が使えるようになった。

RailsAPI モードで動かす

Rails をインストールして、API モードでアプリを作る。

インストール

gem update --system
gem install rails

これで、Rails のインストール完了

API モードでアプリケーションを作る

ubuntu@ubuntu-xenial:~$ rails new railsapimode --api
...
checking for sqlite3.h... no
sqlite3.h is missing. Try 'brew install sqlite3',
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
and check your shared library search path (the
location where your sqlite3 shared library is located).
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

どうやら、sqlite3.h が無い様子。
書いてあるとおり、コマンドを実行する。

ubuntu@ubuntu-xenial:~$ sudo apt-get install libsqlite3-dev
ubuntu@ubuntu-xenial:~$ rails new railsapimode --api
ubuntu@ubuntu-xenial:~$ rails -v
Rails 5.1.3
ubuntu@ubuntu-xenial:~$ 

上手くインストールできたようだ。

API の作成

ubuntu@ubuntu-xenial:~$ cd railsapimode/
ubuntu@ubuntu-xenial:~/railsapimode$ rails g scaffold Users name:string age:integer org:string sex:string
Running via Spring preloader in process 24106
[WARNING] The model name 'Users' was recognized as a plural, using the singular 'User' instead. Override with --force-plural or setup custom inflection rules for this noun before running the generator.
      invoke  active_record
      create    db/migrate/20170821162126_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      invoke  resource_route
       route    resources :users
      invoke  scaffold_controller
      create    app/controllers/users_controller.rb
      invoke    test_unit
      create      test/controllers/users_controller_test.rb
ubuntu@ubuntu-xenial:~/railsapimode$ 

作れた。

users_controller.rb を確認する

ubuntu@ubuntu-xenial:~/railsapimode$ cat app/controllers/users_controller.rb 
class UsersController < ApplicationController
  before_action :set_user, only: [:show, :update, :destroy]

  # GET /users
  def index
    @users = User.all

    render json: @users
  end

  # GET /users/1
  def show
    render json: @user
  end

  # POST /users
  def create
    @user = User.new(user_params)

    if @user.save
      render json: @user, status: :created, location: @user
    else
      render json: @user.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /users/1
  def update
    if @user.update(user_params)
      render json: @user
    else
      render json: @user.errors, status: :unprocessable_entity
    end
  end

  # DELETE /users/1
  def destroy
    @user.destroy
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_user
      @user = User.find(params[:id])
    end

    # Only allow a trusted parameter "white list" through.
    def user_params
      params.require(:user).permit(:name, :age, :org, :sex)
    end
end
ubuntu@ubuntu-xenial:~/railsapimode$ 

見てわかるとおり、GET や POST など、メソッドおよびアクセスするときの解説付きて展開される。

seed ファイルに、サンプルデータを入れる

ubuntu@ubuntu-xenial:~/railsapimode$ vim db/seeds.rb 
ubuntu@ubuntu-xenial:~/railsapimode$ cat db/seeds.rb 
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
#
# Examples:
#
#   movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
#   Character.create(name: 'Luke', movie: movies.first)
User.create(name: 'user1', age: 21, org: 'section 1', sex: 'man')
User.create(name: 'user2', age: 22, org: 'section 2', sex: 'man')
User.create(name: 'user3', age: 23, org: 'section 3', sex: 'woman')
User.create(name: 'user4', age: 21, org: 'section 1', sex: 'woman')

ubuntu@ubuntu-xenial:~/railsapimode$ 

migrate とか

rails db:migrate
rails db:seed
rails s

curl で動作確認

別端末を起動して、vagrant sshで中に入る。

curl でテスト。

# User 一覧の取得
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type' http://localhost:3000/users -X GET -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /users HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< ETag: W/"718134f3ca6a612c64c9c16753883eb6"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: 8f0511f4-f726-44d6-a993-0d0765bd5d71
< X-Runtime: 0.263571
< Transfer-Encoding: chunked
< 
* Connection #0 to host localhost left intact
[{"id":1,"name":"user1","age":21,"org":"section 1","sex":"man","created_at":"2017-08-21T16:27:44.054Z","updated_at":"2017-08-21T16:27:44.054Z"},{"id":2,"name":"user2","age":22,"org":"section 2","sex":"man","created_at":"2017-08-21T16:27:44.061Z","updated_at":"2017-08-21T16:27:44.061Z"},{"id":3,"name":"user3","age":23,"org":"section 3","sex":"woman","created_at":"2017-08-21T16:27:44.065Z","updated_at":"2017-08-21T16:27:44.065Z"},{"id":4,"name":"user4","age":21,"org":"section 1","sex":"woman","created_at":"2017-08-21T16:27:44.070Z","updated_at":"2017-08-21T16:27:44.070Z"}]

ubuntu@ubuntu-xenial:~$ 

# User の情報を取得
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type' http://localhost:3000/users/1 -X GET -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /users/1 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< ETag: W/"bfda4451a19a000f8bd9e150b9d23aa1"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: 9e51b1e8-5ba7-4b81-a8c3-761c94dd41f8
< X-Runtime: 0.015374
< Transfer-Encoding: chunked
< 
* Connection #0 to host localhost left intact
{"id":1,"name":"user1","age":21,"org":"section 1","sex":"man","created_at":"2017-08-21T16:27:44.054Z","updated_at":"2017-08-21T16:27:44.054Z"}

ubuntu@ubuntu-xenial:~$ 

# User を作成
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type: application/json' -d '{ "user" : { "name": "user5", "age":25, "org":"section2", "sex":"woman" } }' http://localhost:3000/users -X POST -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST /users HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 75
> 
* upload completely sent off: 75 out of 75 bytes
< HTTP/1.1 201 Created
< Location: http://localhost:3000/users/5
< Content-Type: application/json; charset=utf-8
< ETag: W/"e8248c5cbf259acf172667196f403545"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: 33be92f3-532d-40f2-84a8-ceb5c7e39467
< X-Runtime: 0.017082
< Transfer-Encoding: chunked
< 
* Connection #0 to host localhost left intact
{"id":5,"name":"user5","age":25,"org":"section2","sex":"woman","created_at":"2017-08-21T16:40:20.840Z","updated_at":"2017-08-21T16:40:20.840Z"}

ubuntu@ubuntu-xenial:~$ 

# User を更新
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type: application/json' -d '{ "user" : { "org":"section 4" } }' http://localhost:3000/users/5 -X PUT -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> PUT /users/5 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 34
> 
* upload completely sent off: 34 out of 34 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< ETag: W/"3d2c91c68c4e49004e3cbb79f62d2dea"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: 576329f0-7792-402c-a950-5de647ee22a0
< X-Runtime: 0.011775
< Transfer-Encoding: chunked
< 
* Connection #0 to host localhost left intact
{"id":5,"org":"section 4","name":"user5","age":25,"sex":"woman","created_at":"2017-08-21T16:40:20.840Z","updated_at":"2017-08-21T16:43:29.569Z"}

ubuntu@ubuntu-xenial:~$ 

# User を削除
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type: application/json' http://localhost:3000/users/5 -X DELETE -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> DELETE /users/5 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Type: application/json
> 
< HTTP/1.1 204 No Content
< Cache-Control: no-cache
< X-Request-Id: 3b51886b-3d78-40d4-8d0e-b7eb676259e2
< X-Runtime: 0.015196
< 
* Connection #0 to host localhost left intact


ubuntu@ubuntu-xenial:~$ 

# 存在しないUserを取得
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type: application/json' http://localhost:3000/users/0 -X GET -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /users/0 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Type: application/json
> 
< HTTP/1.1 404 Not Found
< Content-Type: application/json; charset=UTF-8
< X-Request-Id: b1d90e0b-61e2-4e14-827a-aa3fc6dc4d76
< X-Runtime: 0.037391
< Content-Length: 10812
< 
{"status":404,"error":"Not Found"
...



次回は、このAPI modeを利用して、API Clientを作ってみたいと思います。
(基礎すっ飛ばしているから、もう一度復習しよう)

以上。