2016年1月28日 星期四

Ansible 筆記 - 解決 selectattr('field_name','equalto','field_value') - TemplateRuntimeError: no test named 'equalto' @ Ubuntu 14.04

最近又再調整 Ansible 的使用架構,想要更多的彈性,勢必就會碰到抽資料出來的問題,接著就會踩到想要用 Jinja2 裡的 test equalto 用法。

目前環境:

$ ansible --version
ansible 2.0.0.2
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
$ pip show jinja2
---
Name: Jinja2
Version: 2.7.2
Location: /usr/lib/python2.7/dist-packages
Requires: markupsafe


而 equalto 的用法是 Jinja2 2.8 之後才支援的 Orz

只好硬解一下:

$ sudo pip install jinja2 --upgrade
$ pip show jinja2
---
Name: Jinja2
Version: 2.8
Location: /usr/local/lib/python2.7/dist-packages
Requires: MarkupSafe


接著,就沒事了 :P 來一個完整範例紀錄:


- hosts: localhost
  vars:
    rpm_list:
      - name: "my-service-package-1"
        install_dir: "/opt/my-service-package-1/"
      - name: "my-service-package-2"
        install_dir: "/opt/my-service-package-2/"

  task:
    - set_fact: x="{{rpm_list | selectattr('name','equalto','my-service-package-2') | map(attribute='install_dir') |list}}"
    - debug: var={{x}}


執行:

TASK [set_fact] ****************************************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "/opt/my-service-package-2/": "VARIABLE IS NOT DEFINED!"
}


---
更新:

$ cat echo.sh
#!/bin/sh
echo '{"all":["127.0.0.1"]}'

$ cat test.xml
---

- hosts: all 
  vars:
    rpm_list:
      - name: "my-service-package-1"
        install_dir: "/opt/my-service-package-1/"
      - name: "my-service-package-2"
        install_dir: "/opt/my-service-package-2/"
  tasks:
    - set_fact: x="{{rpm_list | selectattr('name','equalto','my-service-package-2') | map(attribute='install_dir') |list}}"
    - debug: var=x

$ ansible-playbook -i echo.sh test.xml 
PLAY [all] ***********************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [127.0.0.1]

TASK [set_fact] ******************************************************************************************************************************************
ok: [127.0.0.1]

TASK [debug] *********************************************************************************************************************************************
ok: [127.0.0.1] => {
    "x": [

        "/opt/my-service-package-2/"
    ]
}

PLAY RECAP ***********************************************************************************************************************************************
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


其他參考資料:

2016年1月26日 星期二

使用微軟翻譯 API (Translator API - Microsoft Translator)

有個工作拖了很久,最後請同事協助處理了一下,順手筆記 :) 由於 App 撒出去世界各地,所以總會有好心人士留留言給予鼓勵,無奈很多語言都看不懂 XD 人工用 Google 翻譯當然夠用,但量大的時候,就希望能夠自動翻譯一下。

同事研究後,發現微軟翻譯 API 有免費使用額度(一個月200萬個字),所以就挑這來做了!

首先,註冊一下帳號:https://datamarket.azure.com/account ,填一下基本資料即可,一開始就會得到一組主要帳戶金鑰跟客戶識別碼,這組可以用來測試一些 API。

當要正式使用時,請至開發人員頁面,註冊一個應用程式(重導網址隨便輸入即可,在此不會用到),用新註冊到的金鑰跟客戶識別碼來工作即可。不然會收到類似的訊息:

TranslateApiExceptionMethod: Translate()Message: Cannot find an active Azure Market Place Translator Subscription associated with the request credentials.message

整個微軟翻譯 API 的使用流程:

Step 1: 透過 client_id 和 client_secret 換得 token

<?php

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13/');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
'grant_type' => 'client_credentials',
'scope' => 'http://api.microsofttranslator.com'
'client_id' => 'YourAppID',
'client_secret' => 'YourAppSecretKey'
)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$ret = curl_exec($ch);
curl_close($ch);
$token = json_decode($ret)->access_token;


Step 2: 帶著 token 跟待查的資料去問微軟翻譯 API

<?php

// https://msdn.microsoft.com/en-us/library/ff512421.aspx
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://api.microsofttranslator.com/v2/Http.svc/Translate?'.http_build_query(array(
'text' => '第二十四個夏天後',
'from' => null,
'to' => 'en',
)));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer '.$token,
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$ret = curl_exec($ch);
curl_close($ch);
echo strip_tags($ret)."\n";


收工。

2016年1月23日 星期六

老片情懷:飲食男女

晚上不知幹嘛,就看了個老片:飲食男女。有興趣可以在 LiTV.tv 找免費的電影,有數位復修版。

這部片感觸真深,例如令人想睡的化學課、排球課、電腦遊戲(很像軒轅劍貳系列)以及慢跑的台北街場,細細述說著每個年代的情懷憂愁,說也說不盡,更別說片尾又來個驚喜,還真的沒料到結局啊。

台灣彷彿也剛經歷個改朝換代,只是過了一夜的激情後,那然後呢?其實什麼都沒有改變,股市隨著大環境起起落落,油價供電需求亦是如此。同輩之間又再次風水輪流轉,各人有個人的情懷,這大概是資訊圈的常態吧!看著學弟從中國回來後,在台灣又找不到合適落腳處,或許,就像 1994 年的飲食男女,原來這樣的狀態在 n 年前依舊一模一樣,戀愛的戀愛,工作的工作,惆悵的依然香煙渺渺,我想,堅持的還是自己的信念吧 :)

持續積極正面生活吧!如同柯p所言,人的終點是死亡,但死亡絕對不是人生的目的啊,生活也好、做事也罷,別老想著負面跟自己過不去,衝刺吧,熱情還在就好,傻裡傻氣也沒什麼不好。

2016年1月22日 星期五

DevOps 筆記 - Jenkins 處理 Git Submodule Authentication/Credential 問題

已經很習慣用 Bitbucket 做 git service,然後有個 project 裡有個 sub-project 一樣有存取控管,而 Jenkins 預設只有第一層存取時,可以正確透過 Credentials 來解決,但是 submodule 就會失敗。

依照原理解法有兩招:

  1. 直接在 Jenkins 執行者的 $HOME/.ssh/ 去撰寫底層 ssh 連線認證方式
  2. 使用 Jenkins plugin - SSH Agent Plugin

為了管理維護方便,當然就用 SSH Agent Plugin 啦,安裝完後,每一個 Project 就會多一個 SSH Agent 的設定選項,只需設定好即可。

另外,有一派會建議把原先 Jenkins Project 裡的 Git Credentials 去掉,一律都用 SSH Agent Plugin 的設定,但這招會導致後續要做 Git Publisher 要做 git tag 時產生問題。

2016年1月21日 星期四

[PHP] 處理 =?gb2312? MIME 字串轉碼,轉成 UTF-8 字串

最近在處理信件聯絡人,偷偷找一封信是有寄給全集團的人,接著取出清單即可。然後又發現一堆 gb2312 的編碼,找了一下解法:

<?php
mb_internal_encoding('UTF-8');
echo mb_decode_mimeheader('=?gb2312?B?RVJQz7XNs82o1qo=?=')."\n";

即可輸出成 "ERP系统通知"