2016年2月18日 星期四

AWS 筆記 - Godaddy 續約憑證 (HTTPS/SSL) 以及 Load Balancer 憑證更新方式

AWS ELB Certificate

購買了每兩年更新一次的憑證服務,然而,憑證更新的原理是所有機器的憑證都會替換掉的。所幸更新憑證時,新舊憑證都會共存的,而 Godaddy 給予 90 天的區間來處理。

官方文件:https://tw.godaddy.com/help/ssl-864
您需要執行幾個步驟後方能續約 SSL,續約操作視憑證類型及網站託管地點而定。 即使您的 SSL 是自動續約,您也需要套用續約積分,並透過帳戶完成續約請求。
您可以在 90 天續約窗口期內購買及套用 SSL 續約: 過期前 60 天至過期後 30 天內。
例如,若您的憑證在 6 月 15 日過期,則您必須在 4 月 15 日至 7 月 15 日間購買並套用續約積分。
在您購買續約積分或您的 SSL 自動續約後,您必須將積分套用至即將過期的 SSL,並完成續約請求。 倘 SSL 過期且您沒有在 90 天續約窗口期內完成續約請求,則之前正常的網站會出現錯誤訊息。
先走一輪 Godaddy 設定:
  1. 在 https://certs.godaddy.com/cert 挑選要續約的憑證,可以看有效日期 
  2. 檢視狀態
  3. 狀態: 續約憑證 -> 點擊後則是一些簡易流程、送單
  4. 接著就只需等待,大概10分鐘內,可以在 https://certs.godaddy.com/cert 看到有效日期被拉長了
  5. 進去檢視憑證,接著下載新的憑證資料(以 Apache 來說,內容物就 gd_bundle-g2-g1.crt 和 yourdomain.crt 兩個檔案)
接著 AWS ELB 的設定:
  1. 在 EC2 -> Load Balancers -> 挑選指定 ELB
  2. 切換至 Listeners 分頁 -> SSL Certificate -> 點選 Change 就可以上傳新的憑證資料
若有其他 ELB ,則直接 Change 到新設定的即可。

2016年2月11日 星期四

How Much Did They Pay You To Give Up On Your Dreams?


最近這一兩年,同儕不外乎追求著數字上的卓越,彼此分享的資訊大概都補足了台灣、大陸和美商的價碼,就是一張冷冰冰的薪資年資梯度表罷了,然而,這段影片就常常出現在我的耳邊:他們到底付了多少錢,讓你放棄夢想?

幾天前和學弟聊了幾句,有的夢想只剩下到國外掙更多的數字,有些人接近了資方,除了替自己的福利爭取時才會轉換勞方心態外,冰冷冷的心態還是沒啥兩樣。到底人是為了熱情工作呢?還是為了未來?還是,就單純的數字?就像玩世紀帝國,不斷地挖礦、搶礦,砍樹種田等,結果從頭到尾就只是數字一直爬昇著,接著就 Game Over 了?

想想未來,想想最初的那一刻吧 :) 這世上一定有更多有趣的事可以追隨的,想不起當年的夢想也沒關係,再找下一個夢想吧!新年快樂!

2016年1月28日 星期四

Nginx 支援多網域 Access-Control-Allow-Origin 設定方式

原先 Access-Control-Allow-Origin 只能支援一個指定網域或 "*" 的設定,想要支持多網域設定時,就來用一下 nginx 的變數吧!

set $access_control_allow_origin "www.changyy.org";
if ($http_host ~ ^(.*\.changyy\.org)$ ) {
set $access_control_allow_origin $1;
}
if ($http_referer ~ ^(https*\:\/\/.*\.changyy\.org)\/ ) {
set $access_control_allow_origin $1;
}
add_header Access-Control-Allow-Origin $access_control_allow_origin;
add_header Access-Control-Allow-Methods "GET, OPTIONS, POST, HEAD, DELETE, PUT";
add_header Access-Control-Allow-Headers "Authorization, X-Requested-With, Content-Type, Origin, Accept";
add_header Access-Control-Allow-Credentials "true";
add_header Access-Control-Max-Age: 86400;


如此一來,只要是 *.changyy.org 的都可以支援啦!同理就可以用在多網域得設置。

若需要支援不同網域以及非預設的 web port ,則要把規則改成:

set $access_control_allow_origin "www.changyy.org";
if ($http_host ~ ^(.*\.changyy\.org(:[0-9]+)*)$ ) {
set $access_control_allow_origin $1;
}
if ($http_referer ~ ^(https*\:\/\/.*\.changyy\.org(:[0-9]+)*)\/ ) {
set $access_control_allow_origin $1;
}

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";


收工。