Created
August 7, 2018 14:33
-
-
Save alzabo/499930d8fbde44fb61c1c7ff9483f511 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
require 'octokit' | |
require 'faraday' | |
ORG_FILTER = ARGV[0] || /GSI.*/ | |
HOOK_URL = ENV['JIRA_WEBHOOK_URL'] | |
ACCESS_TOKEN = ENV['GITHUB_ACCESS_TOKEN'] | |
TEAM_NAME = 'AUTO: Service Account Read Access' | |
TEAM_MEMBERS = ['github-ls-jira-svc'].freeze | |
TEAM_DESCRIPTION = <<~DESC | |
Provides read access to all org repos for service accounts. | |
Integrations include: the service account for the JIRA | |
to GHE integration. | |
Membership managed by automation. Unmanaged members will be | |
removed | |
DESC | |
if ACCESS_TOKEN.nil? | |
puts <<~ERRMSG.tr("\n", ' ') | |
Cannot authenticate to GitHub unless `GITHUB_ACCESS_TOKEN` environment | |
variable is set | |
ERRMSG | |
exit 1 | |
end | |
# For whatever reason, API calls to ghe.eng.fireeye.com occasionally | |
# fail. The Faraday retry middleware should salve this. The following | |
# stolen from http://snags88.github.io/implementing-faraday-retry-in-rails | |
Octokit.configure do |c| | |
c.auto_paginate = true | |
c.middleware = Faraday::RackBuilder.new do |builder| | |
builder.use Faraday::Request::Retry | |
# add the default Octokit middlewares | |
builder.use Octokit::Middleware::FollowRedirects | |
builder.use Octokit::Response::RaiseError | |
builder.use Octokit::Response::FeedParser | |
builder.adapter Faraday.default_adapter | |
end | |
end | |
client = Octokit::Client.new( | |
auto_traversal: true, | |
access_token: ACCESS_TOKEN, | |
api_endpoint: 'https://ghe.eng.fireeye.com/api/v3/' | |
) | |
puts "Running #{$PROGRAM_NAME} with org filter: #{ORG_FILTER.inspect}" | |
orgs = client.all_orgs.select { |org| org.login.match(Regexp.new(ORG_FILTER)) } | |
orgs.each do |org| | |
org = client.org(org.login) | |
if !client.org_member?(org.login, client.user.login) | |
puts <<~NONMEMBER.tr("\n", ' ') | |
[#{org.login}] Skipping #{org.login}: API user #{client.user.login} is not a member | |
of this org. The API user must be an admin to configure orgs. Add the user at | |
#{org.html_url}/people/ | |
NONMEMBER | |
next | |
elsif client.org_membership(org.login, user: client.user.login).role != 'admin' | |
puts <<~NONADMIN.tr("\n", ' ') | |
[#{org.login}] Skipping #{org.login}: API user #{client.user.login} is | |
not an admin of #{org.login}. Change roles at | |
#{org.html_url}/people/#{client.user.login} | |
NONADMIN | |
next | |
end | |
# Get the existing team by name or create it | |
team = client.org_teams(org.login).detect { |t| t.name == TEAM_NAME } | |
# If the team needs to be created, batch creation is faster than iterating | |
# through each repo (the only option when the team already exists) | |
team ||= begin | |
all_repos = client.org_repos(org.login).collect(&:full_name) | |
new_team = client.create_team(org.login, | |
name: TEAM_NAME, | |
description: TEAM_DESCRIPTION, | |
repo_names: all_repos) | |
puts <<~ADDTEAM.tr("\n", ' ') | |
[#{org.login}] Created team "#{org.login}/#{TEAM_NAME}" and | |
added #{all_repos.length} repos | |
ADDTEAM | |
new_team | |
end | |
# Add members, if they don't already exist | |
TEAM_MEMBERS.each do |member| | |
next if client.team_member?(team.id, member) | |
client.add_team_membership(team.id, member, role: 'member') | |
end | |
# Remove any members that aren't listed in `TEAM_MEMBERS` | |
current_members = client.team_members(team.id).collect(&:login) | |
(current_members - TEAM_MEMBERS).each do |member| | |
client.remove_team_membership(team.id, member) | |
puts "[#{org.login}] Removed #{member} from #{org.login}/#{TEAM_NAME}" | |
end | |
# Add repos | |
all_org_repos = client.org_repos(org.login).collect(&:full_name) | |
current_team_repos = client.team_repos(team.id).collect(&:full_name) | |
(all_org_repos - current_team_repos).each do |repo_name| | |
client.add_team_repository(team.id, repo_name, permission: 'pull') | |
puts "[#{org.login}] Added #{repo_name} to #{org.login}/#{TEAM_NAME}" | |
end | |
# Add the webhook URL, if provided and it isn't already configured | |
unless HOOK_URL.nil? || client.org_hooks(org.login) | |
.collect { |h| h.config.url } | |
.member?(HOOK_URL) | |
client.create_org_hook(org.login, | |
{ url: HOOK_URL, content_type: 'form' }, | |
events: ['push'], | |
active: true) | |
end | |
puts "[#{org.login}] Finished configuring #{org.login}" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment