Skip to content
This repository has been archived by the owner on Dec 16, 2024. It is now read-only.

Commit

Permalink
feat: add argo api integration
Browse files Browse the repository at this point in the history
Argo API Integration
  • Loading branch information
LindseySaari authored Mar 9, 2022
2 parents 0f2bc64 + a3206c6 commit 01edee8
Show file tree
Hide file tree
Showing 43 changed files with 1,570 additions and 14 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ GITHUB_ACCESS_TOKEN=~
GITHUB_CLIENT_ID=~
GITHUB_CLIENT_SECRET=~
GITHUB_REDIRECT_URI=~
ARGO_USER=test_user
ARGO_PWD=password
1 change: 1 addition & 0 deletions .github/workflows/code_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
DATABASE_URL: "postgres://postgres:[email protected]:5432/platform_console_test?pool=4"
REDIS_URL: redis://localhost:6379/0
TERM: xterm-256color
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
runs-on: ubuntu-20.04

services:
Expand Down
6 changes: 5 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ gem 'flipper', '~> 0.24' # Feature flipper for ANYTHING
gem 'flipper-redis', '~> 0.24' # Redis adapter for Flipper
gem 'flipper-ui', '~> 0.24' # UI for the Flipper gem
gem 'jbuilder', '~> 2.11' # Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem 'omniauth-keycloak', '~> 1.4' # Keycloack SSO Oauth Strategy
gem 'jwt', '~> 2.3' # Ruby implementation of the JWT standard
gem 'net-http', '~> 0.2' # HTTP client api for Ruby
gem 'omniauth-keycloak', '~> 1.4' # Keycloack SSO Oauth Strategy
gem 'omniauth-rails_csrf_protection'
gem 'pagy', '~> 5.10' # Agnostic pagination in plain ruby
gem 'paper_trail', '~> 12.2' # Track changes to your models, for auditing or versioning
Expand Down Expand Up @@ -48,5 +50,7 @@ group :test do
gem 'minitest-ci' # Minitest Junit XML results for GHA
gem 'selenium-webdriver' # Capybara system testing with Chrome
gem 'simplecov' # Code coverage for Ruby
gem 'vcr', github: 'vcr/vcr' # Edge version for Ruby 3.1 support. Record/replay HTTP interactions
gem 'webdrivers' # Easy installation and use of web drivers to run system tests with browsers
gem 'webmock' # Stubbing and setting expectations in HTTP requests
end
28 changes: 27 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
GIT
remote: https://github.com/vcr/vcr.git
revision: 7ac8292c289ca98dcb4254b59e1ee29e2205d8b3
specs:
vcr (6.0.0)

GEM
remote: https://rubygems.org/
specs:
Expand Down Expand Up @@ -93,11 +99,13 @@ GEM
coderay (1.1.3)
concurrent-ruby (1.1.9)
connection_pool (2.2.5)
crack (0.4.5)
rexml
crass (1.0.6)
digest (3.1.0)
docile (1.4.0)
erubi (1.10.0)
faraday (1.9.3)
faraday (1.10.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
Expand Down Expand Up @@ -132,6 +140,7 @@ GEM
sanitize (< 7)
globalid (1.0.0)
activesupport (>= 5.0)
hashdiff (1.0.1)
hashie (5.0.0)
i18n (1.10.0)
concurrent-ruby (~> 1.0)
Expand Down Expand Up @@ -164,6 +173,9 @@ GEM
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
net-http (0.2.0)
net-protocol
uri
net-imap (0.2.3)
digest
net-protocol
Expand All @@ -185,6 +197,8 @@ GEM
racc (~> 1.4)
nokogiri (1.13.3-arm64-darwin)
racc (~> 1.4)
nokogiri (1.13.3-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.13.3-x86_64-linux)
racc (~> 1.4)
oauth2 (1.4.7)
Expand Down Expand Up @@ -320,6 +334,8 @@ GEM
railties (>= 6.0.0)
tailwindcss-rails (2.0.7-arm64-darwin)
railties (>= 6.0.0)
tailwindcss-rails (2.0.7-x86_64-darwin)
railties (>= 6.0.0)
tailwindcss-rails (2.0.7-x86_64-linux)
railties (>= 6.0.0)
thor (1.2.1)
Expand All @@ -330,10 +346,15 @@ GEM
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
unicode-display_width (2.1.0)
uri (0.11.0)
webdrivers (5.0.0)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0)
webmock (3.14.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
Expand All @@ -345,6 +366,7 @@ PLATFORMS
arm64-darwin-20
arm64-darwin-21
ruby
x86_64-darwin
x86_64-linux

DEPENDENCIES
Expand All @@ -358,7 +380,9 @@ DEPENDENCIES
flipper-ui (~> 0.24)
importmap-rails (~> 1.0)
jbuilder (~> 2.11)
jwt (~> 2.3)
minitest-ci
net-http (~> 0.2)
omniauth-keycloak (~> 1.4)
omniauth-rails_csrf_protection
pagy (~> 5.10)
Expand All @@ -381,7 +405,9 @@ DEPENDENCIES
strong_migrations (~> 0.8)
tailwindcss-rails (~> 2.0)
turbo-rails (~> 1.0)
vcr!
webdrivers
webmock

RUBY VERSION
ruby 3.1.0p0
Expand Down
1 change: 1 addition & 0 deletions app/assets/config/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js
//= link_tree ../builds

95 changes: 95 additions & 0 deletions app/controllers/deployments_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# frozen_string_literal: true

require 'argo_cd/client'

# Handles creating deployments which are owned by an app
class DeploymentsController < ApplicationController
before_action :authorize_session!
before_action :set_app, :set_team
before_action :set_deployment, only: %i[show edit update destroy]

# GET /apps or /apps.json
def index
@deployments = @app.deployments
@pagy, @deployments = pagy @deployments
end

# GET /apps/1 or /apps/1.json
def show
argo_client = ArgoCd::Client.new(@app.id, @deployment.name, @current_user.id)
@response = argo_client.app_info
end

# GET /apps/new
def new
@deployment = @app.deployments.build
end

# GET /apps/1/edit
def edit; end

# POST /apps or /apps.json
def create
@deployment = @app.deployments.build(deployment_params)

respond_to do |format|
if @app.save
format.html do
redirect_to team_app_deployment_url(@team, @app, @deployment), notice: 'Deployment was successfully created.'
end
format.json { render :show, status: :created, location: @deployment }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @deployment.errors, status: :unprocessable_entity }
end
end
end

# PATCH/PUT /apps/1 or /apps/1.json
def update
respond_to do |format|
if @deployment.update(deployment_params)
format.html do
redirect_to team_app_deployment_url(@team, @app, @deployment), notice: 'Deployment was successfully updated.'
end
format.json { render :show, status: :ok, location: @deployment }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @deployment.errors, status: :unprocessable_entity }
end
end
end

# DELETE /apps/1 or /apps/1.json
def destroy
@deployment.destroy

respond_to do |format|
format.html do
redirect_to team_app_deployments_url(@team, @app), notice: 'Deployment was successfully destroyed.'
end
format.json { head :no_content }
end
end

private

# Use callbacks to share common setup or constraints between actions.
def set_team
@team = Team.find(params[:team_id])
end

def set_app
@app = App.find(params[:app_id])
end

# Find the app deployment
def set_deployment
@deployment = @app.deployments.find(params[:id])
end

# Only allow a list of trusted parameters through.
def deployment_params
params.require(:deployment).permit(:name, :app_id)
end
end
1 change: 1 addition & 0 deletions app/models/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class App < ApplicationRecord
belongs_to :team
has_many :deployments, dependent: :destroy
has_paper_trail
validates :name, presence: true
end
7 changes: 7 additions & 0 deletions app/models/deployment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class Deployment < ApplicationRecord
belongs_to :app
has_paper_trail
validates :name, presence: true
end
18 changes: 18 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# The User Model
class User < ApplicationRecord
encrypts :argo_token
has_paper_trail
has_secure_password
before_validation :downcase_email
Expand All @@ -21,6 +22,23 @@ def self.from_omniauth(auth_hash)
# roles = auth_hash['extra']['raw_info']['resource_access']['account']['roles']
end

def argo_token_invalid?
begin
decoded_token = JWT.decode(argo_token, nil, false)
rescue StandardError
return true
end

decoded_token_info = decoded_token[0]

if decoded_token_info.keys.include?('exp')
expiration = Time.zone.at(decoded_token_info['exp'])
(expiration + 24.hours) < DateTime.now # token has expired
else
false
end
end

private

def downcase_email
Expand Down
74 changes: 74 additions & 0 deletions app/views/apps/_app_deployments.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<div class="flex justify-between">
<h3 class="text-lg leading-7 text-gray-900 sm:text-lg sm:truncate mt-4">
Deployments
</h3>
<%= link_to new_team_app_deployment_path(@team, @app), class: 'place-self-center inline-flex items-center mt-4 px-2 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-900 hover:bg-blue-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-900' do %>
<span class="sr-only">New app</span>
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd" />
</svg>
<% end %>
</div>

<br>

<% if @app.deployments.present? %>
<div class="flex flex-col">
<div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div class="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table class="table-fixed min-w-full divide-y divide-gray-200" id="apps">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase w-full">
Name
</th>
<th scope="col" class="relative px-6 py-3">
<span class="sr-only">Edit</span>
</th>
</tr>
</thead>
<tbody>
<% @app.deployments.each do |deployment| %>
<tr class="<%= cycle 'bg-white', 'bg-gray-50' %>">
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
<%= link_to deployment.name, [@team, @app, deployment], class: 'text-blue-900 hover:text-blue-800' %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<div class="flex space-x-2">
<%= link_to 'Edit', edit_team_app_deployment_path(@team, @app, deployment), class: 'inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-900 hover:bg-blue-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500' %>
<%= button_to 'Destroy', [@team, @app, deployment], method: :delete, form: { data: { turbo_confirm: 'Are you sure?' } }, class: 'inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-white bg-red-900 hover:bg-red-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-900 sm:text-sm' %>
</div>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
</div>

<% if @pagy %>
<div class="md:flex justify-between text-center mt-6 md:mt-0">
<%== pagy_info @pagy %>
<%== pagy_nav @pagy %>
</div>
<% end %>
<% else %>
<div class="text-center border-dashed border-gray-300 hover:border-gray-400 border-2 rounded-lg p-6 max-w-lg m-auto">
<svg width="96" height="96" fill="none" class="mx-auto mb-6 text-gray-900"><path d="M36 28.024A18.05 18.05 0 0025.022 39M59.999 28.024A18.05 18.05 0 0170.975 39" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><ellipse cx="37.5" cy="43.5" rx="4.5" ry="7.5" fill="currentColor"></ellipse><ellipse cx="58.5" cy="43.5" rx="4.5" ry="7.5" fill="currentColor"></ellipse><path d="M24.673 75.42a9.003 9.003 0 008.879 5.563m-8.88-5.562A8.973 8.973 0 0124 72c0-7.97 9-18 9-18s9 10.03 9 18a9 9 0 01-8.448 8.983m-8.88-5.562C16.919 68.817 12 58.983 12 48c0-19.882 16.118-36 36-36s36 16.118 36 36-16.118 36-36 36a35.877 35.877 0 01-14.448-3.017" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M41.997 71.75A14.94 14.94 0 0148 70.5c2.399 0 4.658.56 6.661 1.556a3 3 0 003.999-4.066 12 12 0 00-10.662-6.49 11.955 11.955 0 00-7.974 3.032c1.11 2.37 1.917 4.876 1.972 7.217z" fill="currentColor"></path></svg>
<h3 class="mt-2 text-sm font-medium text-gray-900">No Deployments for <%= @app.name %></h3>
<p class="mt-1 text-sm text-gray-500">
Get started by creating a new deployment.
</p>
<div class="mt-6">
<%= link_to new_team_app_deployment_path(@team, @app), class: 'inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-900 hover:bg-blue-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-900' do %>
<svg class="-ml-1 mr-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd" />
</svg>
New Deployment
<% end %>
</div>
</div>
<% end %>
5 changes: 4 additions & 1 deletion app/views/apps/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@

<%= link_to 'Edit this app', edit_team_app_path(@team, @app), class: 'inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-900 hover:bg-blue-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-900' %>

<%= button_to 'Destroy this app', [@team, @app], method: :delete, form: { data: { turbo_confirm: 'Are you sure?' } }, class: 'inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-white bg-red-900 hover:bg-red-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-800 sm:text-sm' %>
<%= button_to 'Destroy this app', [@team, @app], method: :delete, form: { data: { turbo_confirm: 'Are you sure?' } }, class: 'inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-white bg-red-900 hover:bg-red-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-800 sm:text-sm' %>
</div>


<%= render "apps/app_deployments" %>
Loading

0 comments on commit 01edee8

Please sign in to comment.