Developer Tools CLI
The Cloud-Native Toolkit Command Line Interface (CLI)
The IBM Garage Cloud-Native Toolkit includes the IBM Garage for Cloud (IGC) Command Line Interface (CLI). The IGC CLI provides a set of helpful utilities that can be invoked from the command line. It was created to automate and simplify complicated and repetitive tasks, allowing developers to be more productive.
Use of the CLI is in no way required to work with the Cloud-Native Toolkit and everything done by the CLI can be done manually instead. For each of the commands, the equivalent manual steps are also given for the sake of full transparency and to take away any notion of “magic” that the CLI might be performing.
Some of the utilities provided by the CLI include:
- Register your application’s git repo into a CI pipeline (Jenkins, Tekton, etc.)
- List the ingress URLs and route URLs defined within the cluster
- List the connection information (endpoints, user names, and passwords) for the tools configured in the environment
- Help copy
config maps
andsecrets
into new projects/namespace - Enable existing Code Patterns with the necessary artifacts to be integrated easily into the Developer Environment
You can either install the CLI onto your computer or install the Cloud Shell Commands environment.
Follow the instructions in the cloud-shell-commands readme to install the Cloud Shell Commands.
Install the CLI:
npm i -g @ibmgaragecloud/cloud-native-toolkit-cliVerify the version:
igc --version
Invoking the CLI
When the CLI is installed, it adds an executable named
igc
to the PATH. Runningigc --help
will list the available commands.The output text will be similar to the following:
$ igc --helpIBM Garage Cloud Native Toolkit CLI (https://cloudnativetoolkit.dev)Usage: igc <command> [args]Commands:igc create-webhook Create a git webhook for a given Jenkins pipelineigc credentials Lists the urls and credentials for the tools deployedto the clusterThe IGC CLI will now install the commands as plugins to the
kubectl
andoc
CLIs.For example, all of the following are equivalent:
igc pipelinekubectl pipelineoc pipeline
Prerequisite tools
Log into your cluster
Most all of the commands provided by the IGC CLI interact with a cluster. It probably comes as no surprise then that you should be logged into the prior to running the commands.
- oc login --server=<url> --token=<apikey>
- ibmcloud ks cluster config --cluster <CLUSTER>
Log into your IBM Cloud account
Log into your IBM Cloud account with the correct region and resource group:
ibmcloud login -a cloud.ibm.com -r <region> -g <resource group>
Available commands
dashboard
Opens the Developer Dashboard in the default browser. If a default browser has not been configured, then the URL to the Dashboard will be printed out.
The dashboard displays the Cloud-Native Toolkit tools configured within the cluster along with links to activation content and links to Starter Kits to start a project quickly.
This command requires that the login context for the cluster has already been established.
Command flags
-n
: the namespace where the dashboard has been deployed; the default istools
Usage
The command is used in the following way:
igc dashboard
The following commands would have the same result on OpenShift:
HOST=$(oc get routes/dashboard -n tools -o jsonpath='{.spec.host}')open "https://$HOST"
The following commands would have the same result on Kubernetes:
HOST=$(kubectl get ingress/developer-dashboard -n tools -o jsonpath='{.spec.rules[0].host}')open "https://$HOST"
Related commands
- credentials: shows information about the same tools shown in the dashboard from the command-line
- tool-config: allows configuration for additional tools to be added to the cluster, making them
available to the dashboard and
credentials
command
credentials
Lists the endpoints, user names, and passwords for the tools configured in the environment. This is the easiest way to get the login credentials for each of the installed tools. Ideally all of the tools would be accessible via SSO at which point this command will be obsolete.
The command works by reading information available in the cluster. When each tool is installed by the toolkit, a
config map
and secret
are created to store the url and credential for the tool. That information is used in a
number of different ways within the environment:
- Provide configuration information to the pipelines
- Populate the tiles on the Developer Dashboard.
- Populate the results of the
credentials
command
This command requires that the login context for the cluster has already been established.
Command flags
-n
: the namespace where the tools have been deployed; the default istools
Usage
The command is used in the following way:
igc credentials
The credential output is JSON format like this
Credentials: {argocd: {user: 'admin',password: '12345678',url: 'https://argocd-tools.mycluster.us-east.containers.appdomain.cloud'},. . .dashboard: {url: 'https://dashboard-tools.mycluster.us-east.containers.appdomain.cloud'
The following commands have the same result (note the dependency on jq
):
# config mapskubectl get configmap -n tools -l grouping=garage-cloud-native-toolkit -o json | \jq '[.items[] | select(.metadata.name != "ibmcloud-config").data]'# secretskubectl get secret -n tools -l grouping=garage-cloud-native-toolkit -o json | \jq '[.items[] | select(.metadata.name != "ibmcloud-apikey").data | with_entries(.value |= @base64d)]'
Related commands
- dashboard: displays the url of the Developer Dashboard and launches the default browser
- tool-config: allows configuration for additional tools to be added to the cluster, making them
available to the dashboard and
credentials
command
endpoints
Lists the ingress and/or route URLs for the applications in a given namespace. An attempt will be made to get the
namespace from the current context if one is not provided as an argument. Results of the command are provided in an
interactive menu. If one of the endpoints is selected, it will display the URL and launch it in the default browser.
Selecting Exit
will print the full list of endpoints and exit.
This command requires that the login context for the cluster has already been established.
Command flags
-n
: the namespace from which the endpoints will be read; the value will be read from the current context if not provided
Usage
The command is used in the following way:
igc endpoints
The following commands list the route and ingress endpoints:
# routeskubectl get route -n tools# ingresskubectl get ingress -n tools
The following commands list the ingress endpoints:
kubectl get ingress -n tools
sync
Creates a Kubernetes namespace or OpenShift project (if it doesn’t already exist) and sets it up so that the namespace
can be used as a target for application deployments and/or to host the Developer Environment. The command performs two
major functions - 1) set up a service account in the namespace with the pull secret(s) for the IBM Container Registry
and 2) synchronize the ConfigMaps
and Secrets
from a template namespace to create a “development” namespace. After
the command has run successfully it will set the provided namespace in the current context
(e.g. equivalent to oc project X
)
The pull secret(s) are required in order for pods to pull images that are stored in the IBM Container Registry.
When the cluster is created in IBM Cloud, a pull secret is provided in the default
namespace. In order for a
pod in another namespace to use it, the secret must first be copied into the namespace. After that, the pod either
needs to reference the pull secret directly or the service account used by the resource needs to have a reference to
the secret. The CLI copies the pull secret over and adds it to the service account so the pod can take either
approach.
The other function this command performs is to copy relevant ConfigMaps
and Secrets
into the namespace that are
needed for development activities. Managing resources across namespaces (particularly ConfigMaps
and Secrets
) is a
common challenge in Kubernetes environments. We have provided the command at this time to simplify the steps required
to get everything ready. Ultimately, this problem seems like an ideal one for an Operator to solve and when one is
available (either from the Toolkit or elsewhere) this command will be retired or transitioned.
There are two different types of namespaces that the command will set up:
- “release” namespace where applications can be deployed (e.g. test, staging)
-OR-
- “development” namespace where DevOps pipelines can be run and where application components can be deployed (e.g. dev)
Both “release” and “development” namespaces will have the pull secret(s) created. However, only the “development”
namespace will also have the ConfigMaps
and Secrets
copied over.
Command flags
-t
: the template namespace that will be the source of theconfig maps
andsecrets
; the default istools
-z
: the name of the service account; the default isdefault
--dev
: flag indicating the namespace should be set for development--verbose
: flag indicating that the console output should persist on the screen
Usage
Create a test
namespace
igc sync test
Create a dev
namespace for development
igc sync dev --dev
The following commands will copy the pull secret(s) from the default
namespace and add them to the service account:
export NAMESPACE="NAMESPACE"export SERVICE_ACCOUNT="default"if [[ $(kubectl get secrets -n "${NAMESPACE}" -o jsonpath='{ range .items[*] }{ .metadata.name }{ "\n" }{ end }' | grep icr | wc -l | xargs) -eq 0 ]]; thenecho "*** Copying pull secrets from default namespace to ${NAMESPACE} namespace"kubectl get secrets -n default | grep icr | sed "s/\([A-Za-z-]*\) *.*/\1/g" | while read default_secret; dokubectl get secret ${default_secret} -n default -o yaml --export | sed "s/name: default-/name: /g" | kubectl -n ${NAMESPACE} create -f -done
The following steps will copy the ConfigMaps
and Secrets
from a template namespace to a target namespace:
export TEMPLATE_NAMESPACE="tools"export NAMESPACE="NAMESPACE"kubectl get configmap -l grouping=garage-cloud-native-toolkit -n ${TEMPLATE_NAMESPACE} -o jsonpath='{ range .items[*] }{ .metadata.name }{ "\n" }{ end }' | \while read cm; dokubectl get configmap ${cm} --namespace ${TEMPLATE_NAMESPACE} --export -o yaml | \kubectl apply --namespace $NAMESPACE -f -done
pipeline
Connects a branch in a Git repo to a either a Jenkins or Tekton CI pipeline in the Developer Environment and triggers an initial build. A webhook is also created so that when a new commit is added to the branch, the pipeline is triggered to start the process to rebuild and redeploy the app using the new code. The Git repo needs to be hosted using a site that supports triggers such as GitHub or GitLab.
This command requires that the terminal is already logged in to the cluster. It also requires that the terminal’s current directory is the repository directory for your local copy of the Git repo. The command uses the local Git repo’s configuration to find the server copy.
If Jenkins or Tekton are not specified when the command is invoked then you will be prompted for which CI tool to use. The command will also prompt for the username and personal access token to access the Git repository, unless those are provided as command-line parameters. It will also prompt you for the branch to use to trigger builds; the default is the current branch.
Command flags
-n
: the deployment namespace; if not provided the namespace from the current context will be used-u
: the username for accessing the Git repo-p
: the personal access token for accessing the Git repo--jenkins
: deploy using a Jenkins pipeline--tekton
: deploy using a Tekton pipeline
Usage
igc pipeline --jenkins
Create a Tekton pipeline in the my-dev
namespace, using the Git credentials gituser
and gitpat
igc pipeline -n my-dev -u gituser -p gitpat --tekton
The following is the list of steps required to manually configure a Tekton pipeline with your development cluster.
- Configure the service account
pipeline
if it doesn’t exist, on OpenShift 4 the operator takes care of this you can skip.oc create serviceaccount pipelineoc adm policy add-scc-to-user privileged -z pipelineoc adm policy add-role-to-user edit -z pipeline - Clone the tasks from the
tools
namespace into thenew-namespace
kubectl get tasks --export -o yaml -n tools | sed s/"namespace: tools/namespace: $(oc project -q)"/ | kubectl apply -f - - Clone the pipelines from the
tools
namespace into thenew-namespace
kubectl get pipelines --export -o yaml -n tools | sed s/"namespace: tools/namespace: $(oc project -q)"/ | kubectl apply -f -
Pipeline Resource
Create a Pipeline resource for the git repository, replace with the correct github url for your repository Use the
tkn
CLI to creategit
resource input the github repo url forurl
and branch forrevision
tkn resource createHere is the an example of the cli
tkn resource create? Enter a name for a pipeline resource : nodejs-typescript-git? Select a resource type to create : git? Enter a value for url : https://github.com/{user or org}/{app}? Enter a value for revision : masterNew git resource "nodejs-typescript-git" has been createdCreate a Pipeline resource for the docker image registry, you can use the internal registry in OpenShift or use an external registry like IBM Container Registry (credentials need setup) Use the
tkn
CLI to createimage
resourcetkn resource createSelect
image
for type.Enter the corresponding
url
for container registry, use the new-namespace} in the urlFor OCP 3 internal registry use
docker-registry.default.svc:5000/{new-namespace}/node-typescript:latest
For OCP 4 or CRC internal registry use
image-registry.openshift-image-registry.svc:5000/{new-namespace}/node-typescript:latest
For external registry like IBM Container registry based on region use
us.icr.io/{namespace}/node-typescript:latest
use an existing namespace in your IBM Cloudtkn resource create? Enter a name for a pipeline resource : nodejs-typescript-image? Select a resource type to create : image? Enter a value for url : docker-registry.default.svc:5000/dev/node-typescript:latest? Enter a value for digest :New image resource "nodejs-typescript-image" has been createdSelect the pipeline, to show the available pipeline run
tkn pipeline lsNAME AGE LAST RUN STARTED DURATION STATUSigc-java-gradle 33 minutes ago --- --- --- ---igc-nodejs 33 minutes ago --- --- --- ---In this case use
igc-java-gradle
for java origc-nodejs
for nodejs.Run the Pipeline using the
git
andimage
Pipeline resources. Set the following environment variable for convienience:export PIPELINE=igc-nodejsexport GIT=nodejs-typescript-gitexport IMAGE=nodejs-typescript-imageThen run the
tkn pipeline start
with the input arguments using the service accountpipeline
tkn pipeline start \${PIPELINE} \-r git-source=${GIT} \-r docker-image=${IMAGE} \-s pipeline
Create a Git Webhook
Open the Tekton Dashboard from the main Tools Dashboard or the ICPA landing page.
Create a Webhook in the Tekton Dashboard
- Click **Webhook** on the menu- Click **Add Webhook** and enter the information for the webhook- Name: **insert name**- Repository UR: **template git repo url**- Access Token: Create github access token with permission minimum write:repo_hook- Namespace: **insert namespace**- Pipeline: select **igc-java-gradle** or **igc-nodejs**- Service Account: **pipeline**- Docker Registry:
Check that Webhook is created on the Github repository (Settings-Webhooks)
Make a change to the git repo and push the change to remote git repository or click on Pipelines and manually kick of a pipeline build
1. Provision Jenkins ephemeral
Jenkins ephemeral provides a kubernetes native version of Jenkins that dynamically provisions build agents on-demand. It’s ephemeral meaning it doesn’t allocate any persistent storage in the cluster.
- Set the project/namespace
oc project {NAMESPACE}
where:
{NAMESPACE}
is the development namespace where the pipelines will run
- Run the following command to provision the Jenkins instance in your namespace
oc new-app jenkins-ephemeral
Open the OpenShift console as described in the login steps above
Select
Workloads -> Pods
from the left-hand menuAt the top of the page select your project/namespace from the drop-down list to see the Jenkins instance running
2. Give the jenkins
service account privileged
access
All of the Cloud-Native Toolkit pipelines use buildah
to build and push the container image to the registry.
Unfortunately, the buildah
container must run as root. By default, OpenShift does not allow containers to run as the
root user and special permission is required for the pipeline to run.
With the Jenkins build engine, all the build processes run as the jenkins
service account. In order for the pipeline
container to run as root on OpenShift we will need to give the privileged
security context constraint (scc) to
jenkins
service account with the following command:
oc project {NAMESPACE}oc adm policy add-scc-to-user privileged -z jenkins
where:
{NAMESPACE}
should be the name you claimed in the box note prefixed to-dev
(e.g. user01-dev)
3. Create a secret with git credentials
In order for Jenkins to have access to the git repository, particularly if it is a private repository, a Kubernetes secret needs to be added that contains the git credentials.
Create a personal access token (if you don’t already have one) using the prereq instructions - https://cloudnativetoolkit.dev/getting-started/prereqs#configure-github-personal-access-token
Copy the following into a file called
gitsecret.yaml
and update the {Git-Username}, and {Git-PAT}
apiVersion: v1kind: Secretmetadata:annotations:build.openshift.io/source-secret-match-uri-1: https://github.com/*labels:jenkins.io/credentials-type: usernamePasswordname: git-credentialstype: kubernetes.io/basic-auth
where:
Git-Username
is the username that has access to the git repoGit-PAT
is the personal access token of the git user
- After logging into the cluster, create the secret by running the following:
oc project {NAMESPACE}oc create -f gitsecret.yaml
where:
{NAMESPACE}
is the development namespace where the pipelines will run
3. Create the build config
On OpenShift 4.3, Jenkins is built into the OpenShift console and the build pipelines can be managed using Kubernetes custom resources. The following steps will create one by hand to create the build pipeline for the new application.
- Copy the following into a file called
buildconfig.yaml
and update the {Name}, {Secret}, {Git-Repo-URL}, and {Namespace}
apiVersion: v1kind: BuildConfigmetadata:name: {Name}spec:triggers:- type: GitHubgithub:secret: my-secret-value
where:
Name
is in the name of your pipelineGit-Repo-URL
is the https url to the git repository{NAMESPACE}
is the development namespace where the pipelines will run
- Assuming you are still logged into the cluster, create the buildconfig resource in the cluster
oc project {NAMESPACE}oc create -f buildconfig.yaml
where:
{NAMESPACE}
is the development namespace where the pipelines will run
4. View the pipeline in the OpenShift console
- Open the OpenShift console for the cluster
- Select Builds -> Build Config
- Select your project/namespace (i.e.
{NAMESPACE}
) from the top - The build pipeline that was created in the previous step should appear
- Manually trigger the pipeline by selecting
Start Build
the menu button on the right side of the row
5. Create the webhook
- Run the following to get the webhook details from the build config
oc project {NAMESPACE}oc describe bc {Name}
where:
{Name}
is the name used in the previous step for the build config{NAMESPACE}
is the development namespace where the pipelines will run
The webhook url will have a structure similar to:
http://{openshift_api_host:port}/oapi/v1/namespaces/{namespace}/buildconfigs/{name}/webhooks/{secret}/generic
In this case {secret}
will be my-secret-value
Open a browser to the GitHub repo deployed in the previous step in the build config
Select
Settings
thenWebhooks
. PressAdd webhook
Paste the webhook url from the previous step into the
Payload url
Set the content-type to
application/json
and leave the rest of the values as the defaultsPress
Add webhook
to create the webhookPress the button to test the webhook to ensure that everything was done properly
Go back to your project code and push a change to one of the files
Go to the Build pipeline page in the OpenShift console to see that the build was triggered
TBD
enable
Adds DevOps artifacts to a Git repo that the Developer Environment uses to deploy the app. The command displays a list of available pipelines and applies the one you select to your code repo. The DevOps files added to your repo include (but are not limited to):
- Helm chart
- Jenkinsfile
This command DOES NOT require that the terminal is already logged in to an IBM Cloud account nor the cluster. It DOES require that the terminal’s current directory is the repository directory for your local copy of the Git repo.
The command will add files to the local repo. You should commit these new files and push them to the server repo.
Then run igc pipeline
to connect your repo to a pipeline in the environment.
Command flags
--repo
: the set of pipelines to choose from; the default is https://github.com/ibm-garage-cloud/garage-pipelines-p
: the name of the pipeline that should be installed; if not provided then you will be prompted-b
: the branch from which the pipeline should be installed; the default isstable
r
: the version number of the pipeline that should be installed; the default islatest
Usage
Before running the command, make sure you have a clean repository with no unstaged changes. Either commit any changes or stash them temporarily with
git stash
. It is particularly important that any changes to the pipeline be dealt with.Apply the pipeline updates using the CLI command
igc enable
Review the changes using
git diff
and revert any application-specific changes that should remain (e.g. customization to the Jenkins pipeline in theJenkinsfile
, specific values added tovalues.yaml
, customizations to the templates in thehelm chart
)Commit the changes when you are happy with them
The follow provides the manual steps equivalent to the igc enable
command:
Before updating the pipelines, make sure you have a clean repository with no unstaged changes. Either commit any changes or stash them temporarily with
git stash
. It is particularly important that any changes to the pipeline be dealt with.Download the
index.yaml
file containing the available pipeline versionscurl -O https://ibm-garage-cloud.github.io/garage-pipelines/index.yamlLook through the
index.yaml
file to identify the url for the desired pipeline branch and versionWith the PIPELINE_URL from the previous step, run the following to download the pipeline tar-ball
curl -O ${PIPELINE_URL}Extract the tar-ball into your repository directory. You will be prompted to overwrite files. Overwrite as appropriate
```shell scripttar xzf ${PIPELINE_FILE}```Review the changes using
git diff
and revert any application-specific changes that should remain (e.g. customization to the Jenkins pipeline in theJenkinsfile
, specific values added tovalues.yaml
, customizations to the templates in thehelm chart
)Commit the changes when you are happy with them