In contrast to OpenShift 2 where one would use git
to push up the code for your application into OpenShift, with that triggering a new build and deployment, OpenShift 3 will instead pull your code from your source code repository. This difference means that under OpenShift 3, pushing changes up to your code repository will not by default automatically trigger a new build and deployment.
To enable automatic builds when code changes are pushed up to your code repository, it is necessary to link your source code repository and OpenShift using a webhook integration.
If you were for example using GitHub to host the code repository for your application, you would configure GitHub to trigger a GitHub webhook on a push, where the target URL is a special URL exposed by the OpenShift cluster where your application is hosted. That way when a push is performed, OpenShift will be notified by GitHub and a new build triggered automatically.
Veer Muchandi has demonstrated how to do this previously in a video on this blog and further information can be found in our documentation about using the GitHub webhook mechanism.
What though if you didn't want to trigger a new build immediately after code was pushed to GitHub and instead you wished to have the code passed through a service such as Travis-CI which would run code tests first.
For this case you would need to use a Generic webhook. In this blog post I am going to walk you through setting up this scenario using a webhook proxy service to mediate between Travis-CI and OpenShift.
The problem of interoperability
A webhook in web development is a method of augmenting or altering the behaviour of a web application, through the use of custom callbacks. The idea behind a webhook is that when you update some resource on a web site or via a web service, it can trigger some further action by initiating a HTTP request against a special URL of yet another web service.
Great in concept, but one downside of webhooks are that their uses are so varied that it is hard to develop standards as to what information may be carried by the URL for the request, in request headers, or the payload of the request itself.
What tends to happen is that the producers of the webhook callback, define their own specification as to the data they will send. If you as a consumer want to allow for maximum interoperability, you have two choices. You either try and support all the different formats for webhook producers you may want to interoperate with, or you define your own format for what you expect and then rely on others to use that format or create a webhook proxy which translates callbacks from one format to another.
In the case of OpenShift it takes the middle ground. It provides builtin support for the most popular webhook producers it would need to deal with, such as GitHub, accepting the GitHub webhook format, but also defines its own format for a Generic webhook.
Linking OpenShift with Travis-CI
If you are not familiar with Travis-CI, it is a continuous integration service used to build and test software projects hosted at GitHub. It is especially popular due to its free tier offering for projects which are released as Open Source.
Whether you are running a web site related to an Open Source project, or are a commercial organisation using its paid service, you may wish to use it to run tests on your application code and only deploy the updated code if it passes all your tests.
For OpenShift 2, the Travis-CI system had a special provider plugin for OpenShift. As explained above, the way that source code is deployed is different between OpenShift 2 and 3 and so that existing plugin will not work with OpenShift 3.
The alternative for OpenShift 3 is to make use of the webhook notification support in Travis-CI. This is where we hit the interoperability problem raised above as Travis-CI defines its own format for the webhook callback which is generated and that doesn't match what OpenShift is expecting to receive.
Comparing webhook callback formats
The format of the webhook callback that Travis-CI generates is documented on the Travis-CI site. You can check out the full format there, but a couple of key points about the format are:
- The authorization secret it generates so that a consumer can validate the source of a webhook callback is sent in the HTTP
Authorization
request header. - The content of the request is sent as
application/x-www-form-urlencoded
, but where the information of interest is actually sent as URL encoded JSON data stored in thepayload
field of the format data.
The Generic webhook that OpenShift expects uses its own different format. The notable differences compared to what Travis-CI generates are:
- The authorization secret needs to be sent as part of the URL, the
Authorization
header would therefore be ignored. - The content of the request is expected to be
application/json
and not as form data. - The layout of the data within the JSON part of the payload is different.
For the Generic webhook in OpenShift, the payload sent in the request content is actually optional and a build can be deployed purely based on a request sent to the correct URL. We could therefore technically still point the Travis-CI webhook notification at OpenShift and get it to work. Unfortunately though, the URL that Travis-CI triggers the webhook request against, is defined in the .travis.yml
file.
The problem with this if you haven't worked it out, is that this means the authorization secret would need to be included in the URL listed in the .travis.yml
file. For an Open Source project this would mean it is publicly visible to everyone, which isn't what you would want.
In addition to this issue, when a payload isn't provided to OpenShift with the details of the Git repository branch and commit corresponding to the test run, then OpenShift can only assume that it should run a build against the last commit on the branch it is linked to. This may not correspond to what the test was run against.
It is therefore important to be able to properly pass across some of the details generated in the Travis-CI webhook callback into the OpenShift Generic webhook format to ensure everything works correctly.
The only way to connect two different webhook request formats together when differences exist, is to use a webhook proxy service.
Although there are webhook proxy services out there which offer a general format translation and proxying service, I decided to create my own webhook proxy service and run it in OpenShift to act as the required bridge, so you can see what is involved and how you could also do it yourself for any third party service you may need to work with.
Using a webhook proxy service
The webhook proxy service I have implemented to bridge between Travis-CI and OpenShift, can be found at:
It consists of a small Python web application implemented using the Flask web framework. You can see the actual code in the app.py
file on the repository on GitHub. I have also included a Python pip requirements.txt
file with the list of Python packages which are required by the application.
This is all that is required to host the webhook proxy service on OpenShift using the default S2I builder for Python supplied with OpenShift. All you would need to do is add a new python:2.7
application to your project using the OpenShift web console and give it the appropriate URL for the Git repository.
An easier way is to add the application using the oc
command line tool by running:
oc create -f https://raw.githubusercontent.com/GrahamDumpleton/openshift-webhook-proxy/master/openshift.json
This will add the webhook proxy service, including exposing it via both HTTP and HTTPS. The name of the application will be webhook-proxy
.
With the webhook proxy service running, the next steps are to configure the build configuration for the application you want to link with Travis-CI, with the authorization secret that Travis-CI will use, and update your Travis-CI configuration to generate the webhook notification when a test succeeds.
Setting the authorization secret
As mentioned above, when Travis-CI runs the webhook callback, it will send an authorization secret in the HTTP Authorization
header. The webhook proxy service when translating the request, will move that into the URL as required by OpenShift. As it is Travis-CI which dictates what the authorization secret is, we need to add it to the build configuration for the target application.
To update the build configuration you can either edit it though the OpenShift web console or using oc edit
on the command line. For example, if your web application is called myapp
, you would run:
oc edit bc/myapp
You then need to find the triggers
section and the subsection for the generic
webhook configuration.
triggers:
- generic:
secret: replace-this-with-authorization-secret
type: Generic
The details of how to generate the authorization secret are described on the Travis-CI site. The snippet of Python code they provide for doing this is:
from hashlib import sha256
sha256('username/repository' + TRAVIS_TOKEN).hexdigest()
The TRAVIS_TOKEN
would be found, as explained in their documentation, in your account profile on the Travis-CI site.
Enabling notifications in Travis-CI
The prior step sets up the OpenShift side, next is to configure Travis-CI through the .travis.yml
file which is a part of the source code repository for the application you are using for your deployment in OpenShift and in Travis-CI for testing.
For this you need to add a notifications
section containing a webhooks
sub section. Details of setting up this type of notification can be found in the Travis-CI documentation.
The important part of this is what URL to use. Because we need to proxy this webhook via the proxy service we need to use the URL of the webhook proxy service we just deployed.
language: python
python:
- "2.7"
install:
- pip install -r requirements.txt
script:
- python manage.py test
notifications:
webhooks:
urls:
- https://webhook-proxy-notifications.a123.apps.example.com/travis-ci/api.example.com/myproject/myapp
on_success: always
on_failure: never
on_start: never
The format of the URL is:
https://<webhook-proxy-host>/travis-ci/<openshift-api-host>/<project>/<application>
To determine the external host name allocated to the webhook proxy service, you can use the oc describe route
command.
$ oc describe route/webhook-proxy | grep Host
Requested Host: webhook-proxy-notifications.a123.apps.example.com
The OpenShift API host should be the host name of the OpenShift cluster displayed when you originally logged in using the oc login
command.
Once the .travis.yml
file has been updated, commit the change and push your change to your code repository. When Travis-CI picks up that a push has occurred, once the tests are run the webhook should be triggered. This will go to the webhook proxy service, which will translate the webhook format to that expected by OpenShift and pass it through to OpenShift. OpenShift will then start a new build and deployment of your application based on the code that passed testing under Travis-CI.
Other webhook notification types
The webhook proxy service I implemented only supports Travis-CI. It should be relatively straight forward to adapt to other third party services used in continuous integration pipelines and which use webhook notifications. If you do use it and add support for other commonly used services, do let me know via the project issues tracker on GitHub and we can see about adding in the additional support.
As to Travis-CI in particular, they do provide default integrations for many services for triggering deployments. As noted above they have provided an integration in the past for OpenShift 2. In time hopefully we will get a builtin integration for OpenShift 3, but in the interim something like this webhook proxy service does the job.
저자 소개
채널별 검색
오토메이션
기술, 팀, 인프라를 위한 IT 자동화 최신 동향
인공지능
고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트
오픈 하이브리드 클라우드
하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요
보안
환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보
엣지 컴퓨팅
엣지에서의 운영을 단순화하는 플랫폼 업데이트
인프라
세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보
애플리케이션
복잡한 애플리케이션에 대한 솔루션 더 보기
오리지널 쇼
엔터프라이즈 기술 분야의 제작자와 리더가 전하는 흥미로운 스토리
제품
- Red Hat Enterprise Linux
- Red Hat OpenShift Enterprise
- Red Hat Ansible Automation Platform
- 클라우드 서비스
- 모든 제품 보기
툴
체험, 구매 & 영업
커뮤니케이션
Red Hat 소개
Red Hat은 Linux, 클라우드, 컨테이너, 쿠버네티스 등을 포함한 글로벌 엔터프라이즈 오픈소스 솔루션 공급업체입니다. Red Hat은 코어 데이터센터에서 네트워크 엣지에 이르기까지 다양한 플랫폼과 환경에서 기업의 업무 편의성을 높여 주는 강화된 기능의 솔루션을 제공합니다.