diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..63b508b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,14 @@ +name: Build example container + +on: + push: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + - name: Build example + run: docker build -t test-image . diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..4291353 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,28 @@ +name: Publish gem + +on: + release: + types: [published] + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.1' + bundler-cache: true + - name: Build gem + run: gem build kuberhealthy-client.gemspec + - name: Publish gem + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + mkdir -p ~/.gem + printf -- '---\n:github: Bearer ${GITHUB_TOKEN}\n' > ~/.gem/credentials + chmod 0600 ~/.gem/credentials + gem push --key github --host https://rubygems.pkg.github.com/${GITHUB_REPOSITORY_OWNER} kuberhealthy-client-*.gem diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eba47e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.gem +.bundle/ diff --git a/Dockerfile b/Dockerfile index 24915c0..8e3e43e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,14 @@ FROM ruby:3.2-alpine WORKDIR /app -COPY exampleCheck.rb /app/exampleCheck.rb + +# Build and install the kuberhealthy-client gem +COPY kuberhealthy-client.gemspec . +COPY lib ./lib +RUN gem build kuberhealthy-client.gemspec \ + && gem install kuberhealthy-client-*.gem \ + && rm kuberhealthy-client-*.gem + +# Copy the example check script +COPY exampleCheck.rb ./exampleCheck.rb + CMD ["ruby", "/app/exampleCheck.rb"] diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..fa75df1 --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gemspec diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..3ab6e02 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,18 @@ +PATH + remote: . + specs: + kuberhealthy-client (0.1.0) + +GEM + remote: https://rubygems.org/ + specs: + +PLATFORMS + ruby + x86_64-linux + +DEPENDENCIES + kuberhealthy-client! + +BUNDLED WITH + 2.6.7 diff --git a/README.md b/README.md index c673e89..7a1ae0d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,27 @@ # Ruby Client Example -This directory contains a minimal Ruby client for creating Kuberhealthy external checks. -The script reads the `KH_REPORTING_URL` and `KH_RUN_UUID` environment variables that -Kuberhealthy sets on checker pods and uses them to report status back to the -Kuberhealthy service. +This repository contains a minimal Ruby client for creating Kuberhealthy external checks. The reusable client library is packaged as the `kuberhealthy-client` gem. + +## Installing the client library + +Add the gem to your application. When using Bundler, reference GitHub Packages: + +```ruby +source 'https://rubygems.pkg.github.com/OWNER' do + gem 'kuberhealthy-client' +end +``` + +Replace `OWNER` with the GitHub organization or user that hosts this repository. + +In your check script: + +```ruby +require 'kuberhealthy/client' + +# perform check logic... +Kuberhealthy::Client.report_success +``` ## Using this example diff --git a/exampleCheck.rb b/exampleCheck.rb index 5ba6c17..6675662 100644 --- a/exampleCheck.rb +++ b/exampleCheck.rb @@ -1,48 +1,10 @@ #!/usr/bin/env ruby -require 'json' -require 'net/http' -require 'uri' - -# reporting_url fetches the Kuberhealthy reporting endpoint from the environment. -def reporting_url - url = ENV['KH_REPORTING_URL'] - return url if url && !url.empty? - raise 'KH_REPORTING_URL not set' -end - -# run_uuid fetches the unique run identifier from the environment. -def run_uuid - uuid = ENV['KH_RUN_UUID'] - return uuid if uuid && !uuid.empty? - raise 'KH_RUN_UUID not set' -end - -# post_status sends a status report back to Kuberhealthy. -def post_status(ok:, errors: []) - uri = URI(reporting_url) - req = Net::HTTP::Post.new(uri) - req['Content-Type'] = 'application/json' - req['kh-run-uuid'] = run_uuid - req.body = JSON.generate({ ok: ok, errors: errors }) - Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http| - http.request(req) - end -end - -# report_success tells Kuberhealthy the check passed. -def report_success - post_status(ok: true, errors: []) -end - -# report_failure tells Kuberhealthy the check failed with messages. -def report_failure(messages) - post_status(ok: false, errors: messages) -end +require 'kuberhealthy/client' begin # TODO: add check logic here. For now, always succeed. - report_success + Kuberhealthy::Client.report_success rescue StandardError => e - report_failure([e.message]) + Kuberhealthy::Client.report_failure([e.message]) end diff --git a/kuberhealthy-client.gemspec b/kuberhealthy-client.gemspec new file mode 100644 index 0000000..02b7663 --- /dev/null +++ b/kuberhealthy-client.gemspec @@ -0,0 +1,16 @@ +require_relative 'lib/kuberhealthy/version' + +Gem::Specification.new do |spec| + spec.name = 'kuberhealthy-client' + spec.version = Kuberhealthy::VERSION + spec.authors = ['Kuberhealthy Maintainers'] + spec.summary = 'Ruby client for reporting Kuberhealthy check results' + spec.description = 'A simple helper library for sending check results back to Kuberhealthy.' + spec.homepage = 'https://github.com/kuberhealthy/ruby' + spec.required_ruby_version = '>= 2.5' + + spec.files = Dir['lib/**/*.rb'] + spec.require_paths = ['lib'] + + spec.metadata['allowed_push_host'] = "https://rubygems.pkg.github.com/#{ENV['GITHUB_REPOSITORY_OWNER']}" +end diff --git a/lib/kuberhealthy-client.rb b/lib/kuberhealthy-client.rb new file mode 100644 index 0000000..406b28d --- /dev/null +++ b/lib/kuberhealthy-client.rb @@ -0,0 +1 @@ +require_relative 'kuberhealthy/client' diff --git a/lib/kuberhealthy/client.rb b/lib/kuberhealthy/client.rb new file mode 100644 index 0000000..9490041 --- /dev/null +++ b/lib/kuberhealthy/client.rb @@ -0,0 +1,45 @@ +require 'json' +require 'net/http' +require 'uri' + +module Kuberhealthy + module Client + module_function + + # Fetch the Kuberhealthy reporting endpoint from the environment. + def reporting_url + url = ENV['KH_REPORTING_URL'] + return url if url && !url.empty? + raise 'KH_REPORTING_URL not set' + end + + # Fetch the unique run identifier from the environment. + def run_uuid + uuid = ENV['KH_RUN_UUID'] + return uuid if uuid && !uuid.empty? + raise 'KH_RUN_UUID not set' + end + + # Send a status report back to Kuberhealthy. + def post_status(ok:, errors: []) + uri = URI(reporting_url) + req = Net::HTTP::Post.new(uri) + req['Content-Type'] = 'application/json' + req['kh-run-uuid'] = run_uuid + req.body = JSON.generate({ ok: ok, errors: errors }) + Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http| + http.request(req) + end + end + + # Report success to Kuberhealthy. + def report_success + post_status(ok: true, errors: []) + end + + # Report failure to Kuberhealthy with messages. + def report_failure(messages) + post_status(ok: false, errors: messages) + end + end +end diff --git a/lib/kuberhealthy/version.rb b/lib/kuberhealthy/version.rb new file mode 100644 index 0000000..6332639 --- /dev/null +++ b/lib/kuberhealthy/version.rb @@ -0,0 +1,3 @@ +module Kuberhealthy + VERSION = '0.1.0' +end