オープンソース見本市 - スライド

# Submarine.js紹介
##### 構成管理に、単純な冪等性にかわる新しい哲学を

2019/09/24

[オープンソース見本市](https://opensource-tokyo.connpass.com/event/144299/)の発表スライドです

---


```messages.js
const TodaysMessages=[
  “インフラ構成管理の現状と問題 - Ansibleの場合",
  “Submarine.jsのアプローチ",
  “それだけじゃない Submarine.jsの強み",
];
```

---

## 構成管理とは

まずはこの文字列をご覧ください
uribamSen

---

## 構成管理とは

◯の中の文字は?
◯ri◯am◯en

---

## 構成管理とは

形あるものは、いずれ壊れる
直すためには、元の形を憶えておく必要がある

-> **構成を管理** しておきましょう

---

## インフラの構成管理の現状

AnsibleではYAMLで構成情報を管理 

```sample.yml
tasks:
  - name: Set host variables based on distribution
    include_vars: "{{ ansible_facts.distribution }}.yml"

handlers:
  - name: restart web service
    service:
      name: "{{ web_service_name | default('httpd') }}"
      state: restarted
```

(引用 : https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html)

---

## 冪等性とは

* 同じ操作を何回実行しても、同じ結果が得られること
* インフラの構成管理の世界では、何回同じコードを実行しても、同じサーバの状態が得られるという意味で使われる
* Webの世界ではHTTPのGETやPUTメソッドは冪等だけど、POSTは冪等ではないなどと言われる

**構築済みのサーバには、変更がかからない** ようになっている

---
## 冪等性の現実

* Ansibleでは、冪等性を保証するために膨大なモジュールを提供している
* ほしい機能がない(探せない)こともある
* ないときは、自分で冪等なコードを書く  
  -> これが **バグの温床** になりやすい

![2019-09-24 03.45.26 docs.ansible.com 916e0ba87951.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416178/0921b49b-492e-feb9-16d6-dfa766a9bd1e.png)

(引用 : https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html)

---

## そもそも冪等なコードとは?

1. 現在の状態の確認手段
2. 在るべき状態の定義
3. 状態を移行するための手段

**3つのことを同時にやる** 複雑なコード

---

## Submarine.jsのアプローチ

それぞれ別のものとして扱う

1. 現在の状態の確認手段 -> `query`
2. 在るべき状態の定義 -> `test`
3. 状態を移行するための手段 -> `command`

```Correct-server-state-with-ssh.js
const Submarine=require('Submarine');

const CorrectServerState=class extends Submarine {
  query(){
    return {
      file_content: String.raw`
        test -r /tmp/submarine/hogehoge \
          && cat /tmp/submarine/hogehoge \
          || echo 'File not readable' \
            >&2
      `,
    };
  }

  test(stats){
    return {
      file_content_is_hogehoge: stats.file_content === 'hogehoge',
    };
  }

  command(){
    return String.raw`
      mkdir -p /tmp/submarine \
        && echo 'hogehoge' \
          > /tmp/submarine/hogehoge
    `;
  }
 

}


const state=new CorrectServerState({
  conn: 'ssh',
  host: 'server1',
});


state.correct()
  .then(console.log);
```

---

## Submarine.jsのアプローチ

状態の `参照` と `変更` を分離する考え方は、他の分野にもある

* オブジェクト指向 -> CQS(コマンド・クエリの分離)  
  https://en.wikipedia.org/wiki/Command–query_separation
* データベース -> CRUD(Create, Read, Update, Delete)
* REST API -> (GET, PUT, DELETE, POST)

---

## Submarine.jsの強み

* コードに秩序が生まれる
* Shellで書いても、まあまあ見やすい  
  if文が少なくてすむ
* 膨大なモジュールを提供する必要がないのでコア機能の開発に注力できる  
  ユーザの学習コストも下がる
* queryだけ実行、testだけ実行も可能  
  Ansibleはサーバに変更がかかるか **コードを実行するまで分からない**
* バッチ実行前のテストに利用できる

## これだけじゃない Submarine.jsの強み

Node.jsで開発したことにより

* 変数、定数のスコープがつかえる  
  Ansibleでは、ほとんどの変数・定数はグローバル
* classと継承の概念によりDIが可能に
* フロントエンド、サーバサイド、インフラの全てがJavaScriptで開発可能
* TypeScriptと組み合わせて静的型付けも可能

---

## これだけじゃない Submarine.jsの強み

Submarine.jsにしかないユニークな機能も


* Remote-to-remoteのファイルコピー  
  Ansibleではremote-to-local, local-to-remoteと段階を踏む必要がある
* query, test, commandの実行をHTTPエンドポイント化  
  GUI化も検討中

---

## LOGO

![Submarine1.0-510.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416178/21995db3-b89d-8862-6de1-5acfff4559a8.png)

---

```Introduction.js
const Intro={
  name: 'Submarine.js',
  repository: 'https://gitlab.com/mjusui/submarine'
  catch_copy: 'From submarine, you could see a full of iceberg',
  advertisement: '試験導入いただける企業を募集中。DMください',
  twitter_account: '@Mjusui',
  history: [
    "大学ではWebクローラの研究開発",
    "新卒でデータセンターのインフラエンジニア",
    "アドテク業界に転職、インフラエンジニアは継続",
  ],
  likes: [
    'Programming',
    'Baremetal server',
    'Philosophy',
    'Inovation',
    'Linux mint',
    'Vivaldi browser',
  ],
};
```

---