動かざることバグの如し

近づきたいよ 君の理想に

Gitlab APIを使って一括でユーザー全員を特定のグループに所属させる

環境

  • Gitlab 11

背景

全員が使えるプロジェクトが作れるグループがほしかった。

しかしGitlabの仕様上、グループ自体の権限を「internal」または「private」にしても、全員が閲覧プロジェクトにはなるが、結局そのグループに所属していないとそのグループ上に新規にプロジェクトを作成したりMasterにマージ等ができない

つまり、何でもありのオープンワールド的なグループを作るには全員をそのグループのメンテナーとして追加するしかない。

人数的に画面上で追加していくのはツラみがあったのでAPI経由でできないか試してみた。

前準備

GitlabのAPIのアクセスにはプライベートトークンというのが必要である。これは管理画面のプロフィールから取得できる。

手順

まずはGitlabに登録されている既存のユーザーのID一覧を取得する active=trueで停止されたユーザーは除外される

curl -H "Private-Token: xxx" https://gitlab.example.com/api/v4/users?active=true

次に追加したいグループのIDを調べるためにグループ一覧を取得

curl -H "Private-Token: xxxx" https://gitlab.example.com/api/v4/groups

最後に/groups/:id/members で追加 以下は一例

curl -X POST --header 'Private-Token: xxxx' --data 'user_id=17&access_level=40' https://gitlab.example.com/api/v4/groups/52/members

RubyでSelenium+Capybaraで簡単スクレイピング

環境

  • Ruby 2.x
  • Capybara 3.28.0

やりたいこと

Selenium構文ツラいからCapybara使いたい人生だった(使った

require "selenium-webdriver"
require "capybara"
require "capybara/dsl"
include Capybara::DSL

Capybara.configure do |capybara_config|
  capybara_config.default_driver = :selenium_chrome
  capybara_config.default_max_wait_time = 10
end

ua = "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
Capybara.register_driver :selenium_chrome do |app|
  options = Selenium::WebDriver::Chrome::Options.new(
    binary: "/Applications/Chromium.app/Contents/MacOS/Chromium",
    args: ["--headless", "--disable-gpu", "window-size=1280x800"],
  )
  Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end

Capybara.javascript_driver = :selenium_chrome

# Yahooで検索してスクリーンショットを取得
visit "https://www.yahoo.co.jp"
find("#srchtxt").set("ruby")
find("#srchbtn").click
page.save_screenshot("ss.png", full: true)

RubyでHeadless Chromeを操作してスクレイピング

環境

概要

RubyスクレイピングするならMechanize一択だが、昨今のサイトではJavascriptが動かないとデータが取れないサイトも多い。

PhantomJSが死んでしまった今、Headless Chromeが1番いいのだが、Puppeteerはちょっと、、て時にRubyでやりたいて時にselenium-webdriverを使ってスクレイピングをしてみたメモ

インストール

必要なものは以下

Chrome

先に動かすサーバーにChrome、ないしはChromiumが必要

ChromeDriver

Chromeを操作するのに必要

https://sites.google.com/a/chromium.org/chromedriver/

selenium-webdriver

これはGemなのでbundle init して bundle add selenium-webdriver でおk

コード

Yahooにアクセスしてスクリーンショットを取るだけのシンプルなサンプルコードは以下

require "selenium-webdriver"

ua = "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
options = Selenium::WebDriver::Chrome::Options.new(
  binary: "/Applications/Chromium.app/Contents/MacOS/Chromium",
  args: ["--headless", "--disable-gpu", "window-size=1280x800"],
)
driver = Selenium::WebDriver.for :chrome, options: options
driver.navigate.to "https://www.yahoo.co.jp"
puts driver.title
driver.save_screenshot("ss.png")

で実行するとスクリーンショットが取れているはず

f:id:thr3a:20190810142622p:plain

AWSを使ったRspecテストにはモックを使うと簡単

環境

やりたいこと

Rubyを使ってS3とか扱うこと全然あると思う。例えば以下はバケット一覧を取得して表示するコード

require 'aws-sdk-s3'

client = Aws::S3::Client.new(
  region: 'ap-northeast-1'
)

bucket_data = client.list_buckets.buckets
bucket_data.each do |b|
  p b.name
end

が、S3ないしはAWSクラウドサービスなのでネットワークが入る。外部サービスをまたぐサービスを組み込んだコードのテストは結構厄介である。

これをなんとかしたい

方法1 非公式のモックライブラリを使う

例えばS3に限定した話だが、fake-s3というライブラリを使うとS3を振る舞うエンドポイントを作ることができる。

github.com

方法2localstack

もともとAtlassianが開発していたAWSのモックフレームワーク こっちは1と違ってフルスタックなので安心できる

github.com

懸念点としては今回みたいにピンポイントなモックを作るためだけにDockerを上げるべきなのかという点と引き継ぎ募集中!と書いてあって今後の開発が怪しいところ。。

方法3

公式が出しているモック機能を使う いわゆるstub

やり方

わりと簡単で手順は以下

  • 同じクラスをstub_responses: trueとして生成する
  • stub_responsesで振る舞いを定義

あとは実際のレスポンス同様にクラスが振る舞ってくれる。以下はさっきのをstubで書き換えたバージョン

require 'aws-sdk-s3'

client = Aws::S3::Client.new(stub_responses: true)
client.stub_responses(:list_buckets, buckets: [{name:'hoge'}, {name:'piyo'}])


bucket_data = client.list_buckets.buckets
bucket_data.each do |b|
  p b.name
end

しゅごい

取得にはエラーがつきもの 実はstub_responsesには例外も渡すことができる

require 'aws-sdk-s3'

client = Aws::S3::Client.new(stub_responses: true)
client.stub_responses(:list_buckets, Aws::Sigv4::Errors::MissingCredentialsError)

begin
  bucket_data = client.list_buckets.buckets
  bucket_data.each do |b|
    p b.name
  end
rescue => e
  puts "#{e.class} #{e.message}"
end

実行結果

Aws::Sigv4::Errors::MissingCredentialsError missing credentials, provide credentials with one of the following options:
  - :access_key_id and :secret_access_key
  - :credentials
  - :credentials_provider

当然オリジナルエラーも投げることができる

client = Aws::S3::Client.new(stub_responses: true)
client.stub_responses(:list_buckets, StandardError.new("custom error"))

これ他のSESとかAWSサービスでもstub使えるっていうだから設計すごいなぁというお気持ち

Github.comをブロッキングする方法

GitHubとは

Wikipediaで調べてみました!

それによると、

GitHub(ギットハブ)は、ソフトウェア開発のプラットフォームであり、ソースコードホスティングする。コードのバージョン管理システムにはGitを使用する。Ruby on RailsおよびErlangで記述されており、アメリカのカリフォルニア州サンフランシスコ市に拠点を置くGitHub社によって保守されている。主な開発者はChris Wanstrath、PJ Hyett、Tom Preston-Wernerである[4]。

どうやらギットハブと読み方の設計図共有サイトだそうです。

また、現在はマイクロソフトに買収されたそうです。

やり方

ブロッキングする方法は簡単で、以下のコマンドを実行するだけです!

echo 127.0.0.1 github.com > /etc/hosts

まとめ

いかがでしたか?Github.comに流出してしまうのは怖いですが、適切に扱えば良いサイトです。あとGithubじゃなくてGitHub