Using service accounts to automate deployments is failing - openshift

We are trying to automate the build and deployment of containers to projects created in openshift v3.3. From the documentation I can see that we will need to leverage service accounts to do this but the documentation is hard to follow and the examples I have found in the blogs don't complete the task. My workflow is as follows with examples oc commands I use:
BUILDER_TOKEN='xxx'
DEPLOYER_TOKEN='xxx'
# build and push the image works as expected
docker build -t registry.xyz.com/want/want:latest .
docker login --username=<someuser> --password=${BUILDER_TOKEN} registry.xyz.com
docker push registry.xyz.com/<repo>/<image>:<tag>
# This fails with error
oc login https://api.xyz.com --token=${DEPLOYER_TOKEN}
oc project <someproject>
oc new-app registry.xyz.com/<repo>/<image>:<tag>
Notice I login into the rest api interface, select the project and create the app but this fails with the following errors:
error: User "system:serviceaccount:want:deployer" cannot create deploymentconfigs in project "default"
error: User "system:serviceaccount:want:deployer" cannot create services in project "default"
Any ideas?

Service accounts only have permission in their owning project by default. You would need to grant deployer access to deploy in other projects.

OK so it seems that using a service account to accomplish this is not the best way to go about things. This is not helped by the documentation. The use case above is very common and the correct approach is to simply evoke the new-app with the image name and corresponding tag:
oc new-app ${APP}:${TAG}
There is no need to mess around with service accounts.

Related

Error while deployment of Gitlab on OpenShift pipeline

I am trying to deploy Gitlab source code OpenShift. But I am facing an issue. Though in Gitlab pipeline it is successful. It keeps talking about the unauthorized error.
My expected output is to have deployment on OpenShift [Error message] (https://i.stack.imgur.com/CBBzO.png)
The error indicates that the Deployment Pod is unable to pull the specified image.
It appears your Deployment is in the namespace roks-test-demo-project while the image your are trying to pull is in the oc-custom-dev namespace. In order for a Deployment in one namespace to pull an image from another, the Deployment's service account must be authorized to do so.
See the OpenShift documentation for how to achieve this.
In your case, assuming your Deployment is running as the default service account:
$ oc policy add-role-to-user \
system:image-puller system:serviceaccount:roks-test-demo-project:default \
--namespace=oc-custom-dev
If your Deployment is running as a non-default service account, replace default with that service account name in the above command.

Openshift - API to get ARTIFACT_URL parameter of a pod or the version of its deployed app

What I want to do is to make a web app that lists in one single view the version of every application deployed in our Openshift (a fast view of versions). At this moment, the only way I have seen to locate the version of an app deployed in a pod is the ARTIFACT_URL parameter in the envirorment view, that's why I ask for that parameter, but if there's another way to get a pod and the version of its current app deployed, I'm also open to that option as long as I can get it through an API. Maybe I'd eventually also need an endpoint that retrieves the list of the current pods.
I've looked into the Openshift API and the only thing I've found that may help me is this GET but if the parameter :id is what I think, it changes with every deploy, so I would need to be modifying it constantly and that's not practical. Obviously, I'd also need an endpoint to get the list of IDs or whatever that let me identify the pod when I ask for the ARTIFACT_URL
Thanks!
There is a way to do that. See https://docs.openshift.com/enterprise/3.0/dev_guide/environment_variables.html
List Environment Variables
To list environment variables in pods or pod templates:
$ oc env <object-selection> --list [<common-options>]
This example lists all environment variables for pod p1:
$ oc env pod/p1 --list
I suggest redesigning builds and deployments if you don't have persistent app versioning information outside of Openshift.
If app versions need to be obtained from running pods (e.g. with oc rsh or oc env as suggested elsewhere), then you have a serious reproducibility problem. Git should be used for app versioning, and all app builds and deployments, even in dev and test environments should be fully automated.
Within Openshift you can achieve full automation with Webhook Triggers in your Build Configs and Image Change Triggers in your Deployment Configs.
Outside of Openshift, this can be done at no extra cost using Jenkins (which can even be run in a container if you have persistent storage available to preserve its settings).
As a quick workaround you may also consider:
oc describe pods | grep ARTIFACT_URL
to get the list of values of your environment variable (here: ARTIFACT_URL) from all pods.
The corresponding list of pod names can be obtained either simply using 'oc get pods' or a second call to oc describe:
oc describe pods | grep "Name: "
(notice the 8 spaces needed to filter out other Names:)

Openshift deployment strategy delegation through sa

We have a tool that provisions the ci/cd workflow for all the teams in our company. As part of the tool chain provisioning we are also creating openshift project automatically.
I am trying to figure out a best automated athorization strategy for invidual team's deployment process
Here is what we are doing currently
Create a project (eg: testproject)
Create a service account(oc create sa testuser)
Add user to admin role for the project (oc policy add-role-to-user admin system:serviceaccount:testproject:testuser)
Now we retrieve the api token for sa account testuser
oc describe sa testuser (Get the predefined token of testuser)
oc describe secret testuser-token-gd9sl (Get the session token)
Through describe secret command, we can retrieve the api token. We give these api tokens to individual teams.
oc login https://192.219.152.34.nip.io –token=adfasdfsdaf23423
Teams Once logged in as using their token , they are able to peform any api oerations in the scope of testproject.
eg: oc create -f testproject-deploymentconfig.yml
oc create -f testproject-service.yml
Is this approach correct ? does it have any draw back ? is there a better approach to this? Can anyone suggest
Here is my suggestion which become better your automatic object processing (I hope it).
Above process (create project and sa) should be executed when new project is created, then you can use the task via project template - Modifying the Template for New Projects.
For instance, you can include your serviceaccount yaml definition in the template.
We do it mostly the same way.
Within a Jenkins pipeline we create a project via a template yaml file.
This includes project metadata and annotations, an named user (LDAP login of the requester) associated as admin and some predefined pull secrets.
Login to Openshift is secured by Keycloak with MFA. And afterwards the admin account himself can edit membership and add serviceaccounts as needed.
We also didn't modify the default project template.

How to create app with credentials in OpenShift?

Try to create Node.js app in OpenShift in terminal, like this:
./oc new-app https://j4nos#bitbucket.org/j4nos/nodejs.git
Source code in BitBucket in a private account, how to set credentials? Once it asked for password, but not again. How can I set credentials?
Added annotated secret from GUI: repo-at-bitbucket
I have read Private Git Repositories: Part 2A tutorial, strange that for HTTPD app there is a Source Secret filed to select secret, but not when Node.js + MongoDB combo is selected. Why?
Ahh .. need to select pure Node.js app.
You need to authenticate to the private git repository. This can be done a few different ways. I would suggest taking a few a minutes and reading this blog series which outlines the different methods you can take.
https://blog.openshift.com/private-git-repositories-part-1-best-practices/
After reading first through initial few posts explaining concepts and doing it with GitHub, only then look at the BitBucket example.
https://blog.openshift.com/private-git-repositories-part-5-hosting-repositories-bitbucket/
Those GitHub examples have more explanation which will then make BitBucket example easier to understand.
The likely reason you were prompted for the password when running oc new-app is that you used:
oc new-app https://j4nos#bitbucket.org/j4nos/nodejs.git
Specifically, you didn't specify a S2I builder to use. As a result, oc new-app will try and checkout the repo locally to analyse it to try and work out what language it uses. This is why it would prompt for the password separately.
It is better to specify the builder name on the command as:
oc new-app nodejs~https://j4nos#bitbucket.org/j4nos/nodejs.git
This is an abbreviated form of the command and is the same as running:
oc new-app --strategy=source --image-stream nodejs --code https://j4nos#bitbucket.org/j4nos/nodejs.git
If you specify the builder, it already knows what to use and doesn't analyse the code so will not prompt for the password, plus you wouldn't need user in the URI.
Either way, when building in OpenShift you still need the basicauth secret and should annotate it so it knows to use the secret for that build.

How do you create a deployment configuration in OpenShift? Is it automatic for new-app based on a docker image?

I'm creating a new-app based on an image stream that corresponds to a docker image in a private OpenShift docker registry. The command is:
oc new-app mynamespace/my-image:latest -n=my-project
Question 1: Does this command automatically create a deployment configuration (dc) that can be referrenced as dc/my-image? Is this deployment configuration associated with my-project?
Question 2: What is the oc command to create a deployment configuration? The OpenShift developer guide has a section titled Creating a Deployment Configuration, but surprisingly it does not say how to create a DC or give any examples. It just shows a JSON structure and says DCs can be managed with the oc command.
Yes, your command will create stuff in the specified project. You can check what objects are created using the oc get command. i.e. to check what DCs you have, you'd do oc get dc or oc get deploymentconfigs.
Other useful commands are oc describe - similar to get but more information. oc status -v - see more broad information about project including warnings and errors.
You create DC and any other resource types using the oc create command. e.g. you copy the example DC off the URL you link to and put it into a file. Finally you do oc create -f mydc.yaml. Both YAML and JSON are supported.
As you see some commands can create DCs by themselves without you providing them with YAML or JSON. You can later modify existing resources with oc edit service/my-app. There is the oc patch command suitable for scripting.
You can see existing resource YAML doing oc get dc/myds -o yaml. Same with any other resource. Keep in mind you are presently using the desired project or use the -n option as you are doing in your example.
Not that hard once you understand some basics and learn to use the oc describe and oc logs command to debug issues with your images/pods. e.g. oc describe pod/my-app-1-asdfg, oc logs my-app-1-asdfg, oc logs -f dc/my-app.
HTH