Coder Social home page Coder Social logo

up's Introduction

up - The Upbound CLI

up is the official CLI for interacting with Upbound Cloud, Upbound Enterprise, and Universal Crossplane (UXP). It is also the primary tool for building Crossplane packages and pushing them to registries.

For users who wish to use other OCI clients for pushing packages, docker-credential-up is an implementation of the Docker credential helper protocol and can be used as an authentication mechanism for pushing packages by adding it your Docker config file.

Minimum Supported Versions

github.com/crossplane/crossplane: v1.6.0

Notably, this version does not support the v1beta1 API versions of CompositeResourceDefinition and Composition from apiextensions.crossplane.io. Please update to use the v1 equivalent if necessary.

Install

Both up and docker-credential-up can be downloaded by using the official installation script, or can be installed via a variety of common package managers.

Install Script:

up

curl -sL https://cli.upbound.io | sh

docker-credential-up

curl -sL https://cli.upbound.io | BIN=docker-credential-up sh

Homebrew

up

brew install upbound/tap/up

docker-credential-up

brew install upbound/tap/docker-credential-up

Deb/RPM Packages

Deb and RPM packages are available for Linux platforms, but currently require manual download and install.

up

curl -sLo up.deb https://cli.upbound.io/stable/${VERSION}/deb/linux_${ARCH}/up.deb

docker-credential-up

curl -sLo up.deb https://cli.upbound.io/stable/${VERSION}/deb/linux_${ARCH}/docker-credential-up.deb

up

curl -sLo up.rpm https://cli.upbound.io/stable/${VERSION}/rpm/linux_${ARCH}/up.rpm

docker-credential-up

curl -sLo up.rpm https://cli.upbound.io/stable/${VERSION}/rpm/linux_${ARCH}/docker-credential-up.rpm

Nix

The up CLI is available via Nixpkgs via the upbound attribute. To install using nix-env:

nix-env -iA upbound

To install using the unified nix CLI:

nix profile install upbound

Both installation methods install both the docker-credential-up and up executables.

Setup

Users typically begin by either logging in to Upbound or installing UXP.

Upbound Login

up uses profiles to manage sets of credentials for interacting with Upbound Cloud and Upbound Enterprise. You can read more about how to manage multiple profiles in the configuration documentation. If no --profile flag is provided when logging in the profile designated as default will be updated, and if no profiles exist a new one will be created with name default and it will be designated as the default profile.

up login

Install Universal Crossplane

up can install UXP into any Kubernetes cluster, or upgrade an existing Crossplane installation to UXP of compatible version. UXP versions with the same major, minor, and patch number are considered compatible (e.g. v1.2.1 of Crossplane is compatible with UXP v1.2.1-up.N)

To install the latest stable UXP release:

up uxp install

To upgrade a Crossplane installation to a compatible UXP version:

up uxp upgrade vX.Y.Z-up.N -n <crossplane-namespace>

Build and Push Packages

up can be used to build and push Crossplane packages. If pushing to Upbound, the same credentials acquired via up login can be used.

To build a package in your current directory:

up xpkg build

To push the package:

up xpkg push hasheddan/cool-xpkg:v0.1.0

If you prefer to use Docker, or any other OCI client, you can add the following to your config file after downloading docker-credential-up to use your Upbound credentials when pushing.

{
	"credHelpers": {
		"xpkg.upbound.io": "up",
		"registry.upbound.io": "up"
	}
}

Usage

See the documentation on supported commands and common workflows for more information.

Contributing

See CONTRIBUTING.md.

up's People

Contributors

alainroy avatar branden avatar cbuto avatar darkmuggle avatar epk avatar hasheddan avatar jastang avatar julienduchesne avatar lucperkins avatar muvaf avatar negz avatar nlinx avatar nullable-eth avatar sttts avatar tnthornton avatar turkenh avatar ulucinar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

up's Issues

[Umbrella] Improve error messages

Error messages are a bit sparse and can be difficult to understand. They don't have to be perfect for first release, but we should ensure that they do as much as they can to help users get unstuck without needing to go to documentation.

Would also be a good idea to write up a design doc on error message philosophy for up.

Consider supporting an error index

Some tools, such as the rust compiler, support an error index, with each error corresponding to a code that can be looked up for more information. This allows for users to supplement information returned about an error with additional documentation. We should consider what it would look like to have a similar pattern in up and how we can ensure consistency in errors and documentation.

[Umbrella] Documentation for first release

Appropriate documentation should exist for up in the following locations:

  • Brief getting started in README.md
  • Complete command documentation in /docs (consider generating, though might do manual for now)
  • Common workflows doc in /docs
  • Both of the two above should also appear on upbound.io

Consider supporting `--helm-values` are for up uxp install/upgrade

Currently the default helm chart values cannot be generically overridden when installing / upgrading UXP with up. This greatly reduces the capabilities of the installer, but it does allow for decoupling of the installer egnine, which means that we could switch out the engine in the future without the user having to know (or let them choose which engine to use). However, since we plan on using helm for the near to distant future, it doesn't make sense to restrict this functionality, and we could potentially accept "helm-style" parameterization in the future, even for a different engine. Therefore, it would be great to allow for pointing to a values.yaml file via a --helm-values flag on up uxp install and up uxp upgrade.

Add to Homebrew

Homebrew is the most popular package manager for macOS and it'd be really easy to get up and running with up if it's distributed in that channel. Details are in https://docs.brew.sh/Formula-Cookbook

This issue tracks creating the formulae, not automating the release pipeline to push every new version.

@hasheddan I know you have a linux, so I can take a stab at this if you'd like to.

`up uxp install / upgrade` fails if `v` is supplied in version

Running up uxp install v1.2.1-up.3 / up uxp upgrade v1.2.1-up.3 fails because helm strips off the v when storing the chart in the cache:

up: error: stat /home/dan/.cache/up/charts/universal-crossplane-v1.2.1-up.3.tgz: no such file or directory

Because UXP uses a leading v in its versioning scheme and it is valid semver, we should support specifying the version to install with a leading v.

Add CONTRIBUTING.md

This repo should contain a document describing how to contribute to up and what the current process is for design and implementation of features.

no account was specified and a default could not be found

Hi

I attempted to connect upbound cloud with up CLI.
But I faced following error.
How can I set account information?

NAME=mycrossplane
up cloud controlplane attach $NAME | up uxp connect -
up: error: no account was specified and a default could not be found

my up config is below.

❯ cat ~/.up/config.json | jq .
{
  "cloud": {
    "default": "default",
    "profiles": {
      "default": {
        "id": "[email protected]",
        "type": "user",
        "session": "MASKED"
      }
    }
  }
}

I found both cloudCtx.Account and profile.Account are empty like below.

Screen Shot 2021-05-18 at 22 37 35

Thank you.

Add command to set default cloud profile

We currently set the first profile the user logs in with as the default in ~/.up/config.json. We should make it easy to change the default profile as desired.

Package CLI for distribution

The CLI should be available from all major package managers, an initial list could be:

  • Homebrew
  • Winget
  • deb (apt/dpkg)

Create schema for config.json

Session tokens and default configured values as specified in #4 will be stored in ~/.up/config.json. A schema will need to be introduced to read and write data to this file.

Support population of kubeconfig files

Currently it is a manual process add cluster credentials of an Upbound-hosted cluster to a user's kubeconfig file.

Support the ability to populate a kubeconfig file from an Upbound Cloud hosted control plane, something like;

up cloud controlplane get kubeconfig

Make `login` a top level command

The Upbound CLI is Upbound's official CLI for all our products including UXP, Upbound Cloud, and Upbound Registry. Today users authenticate the CLI with Upbound using the up cloud login command. This makes it seem like users are logging into Upbound Cloud when in reality those credentials might be used to interact with a variety of Upbound products.

Users could instead up login to authenticate.

Use pinned version of nfpm

We currently use the latest stable version of nfpm in CI. We should instead pin to a specific version and update when appropriate. It appears the install script doesn't currently allow selecting a version for install, but we can download directly from the GitHub release if needed.

Should we make "up uxp uninstall" idempotent?

Currently it seems like if you run up uxp uninstall on a cluster where UXP is not installed exits with a non-zero code with the following message:

❯ up uxp uninstall
up: error: uninstall: Release not loaded: universal-crossplane: release: not found

How about displaying this warning message but exiting with a zero-code to make this command idempotent?

Need a way to create self-hosted control planes without kube-uid

What problem are you facing?

In some scenarios, kube-cluster uid is not known or easily accessible by the user but available to agent running on the cluster.

Deployments through marketplaces are a good example here. For example, while deploying through Rancher marketplace, all deployment flow can be completed through UI without connecting cluster from a local terminal (with up installed).

How could up cli help solve your problem?

It should be possible to create a self-hosted control plane and obtain a control plane token without cluster connectivity or providing kube-uid to the cli.

Or to unify the experience, we can always leave setting kube-uid to the agent (with the first connection attempt) and up cloud controlplane attach $NAME command never sets kube-uid.

Formalize structure of cloud profiles (for initial release)

This issue is timeboxed to 48 hours. Lazy consensus (i.e. maintain status quo) will be used at 8 AM PST 4/30/21 if universal consensus is not reached prior.

Currently, "user' profiles are stored in ~/.up/config.json in the following format:

{
  "cloud": {
    "default": "ada",
    "profiles": {
      "a-uuid-for-ada-token": {
        "type": "token",
        "session": "cool-session-token"
      },
      "ada": {
        "type": "user",
        "session": "cool-session-token"
      },
      "a-uuid-for-hasheddan-user": {
        "type": "token",
        "session": "cool-session-token"
      },
      "[email protected]": {
        "type": "user",
        "session": "cool-session-token",
        "org": "dan" // optional
      }
    }
  }
}

As can bee seen in this example (and by reading the ratified design for initial commands), there are two types of cloud profiles that can be stored:

  1. User (either identified by username or email)
  2. Token (identified by token UUID)

When a user executes an up cloud command that requires supplying a user + org, the following order of precedence takes place:

  1. If --user and --organization are supplied as flags their values will be used (i.e. the profile that matches --user will use the designated session token to establish identify).
  2. If --user is specified, but not --organization, the matching profile will be selected and if it has an org field then that will be used. If it does not have an org field then we try to use the specified user as org, which obviously will fail in the case that the user identifier is email or token UUID.
  3. If --user is not specified, but --organization is, the profile specified as default will be used with the supplied organization.

Essentially, this boils down to "supplying a flag will always win". @turkenh pointed out some valid concerns with this structure in #14 (comment) revolving around the fact that we have "profiles", similar to how GCP and AWS credentials are stored, but we only allow one profile per user identifier (although you can kind of work around this by creating both a username and email profile for the same user). Hasan (justafiably) points out there that allowing for named profiles is more flexible as a user could theoretically have an endless number of custom profiles with differing configuration setups. However, I am somewhat opposed to this approach as our auth model does not currently mirror cloud providers in its complexity, and I personally don't actually love their model of profiles either (not that what I like or do not like should be the direction we go, but it is another UX data point.

The current design of our configuration schema feels simple and intuitive to me because if you specify a --user you will always be logged in as that user (or token), whereas passing something like --profile <arbitrary profile name> feels more opaque to me. We have dedicated commands to switch the default user and the default org for a user profile. This structure also simplifies our login command as we don't require that a user provide a profile name or anything other than user+password or token. However, I feel almost certain that our auth model is not in its final form, so I would anticipate this schema evolving over time. The nice thing about these config files is that updating them is relatively non-destructive -- if this schema changes in the future, the worst thing a user would have to do is delete their ~/.up/config.json and up cloud login again after updating the CLI.

All of that being said, I think there are two cases in which we should modify this structure prior to the first release of up:

  • If we think there is a clearly better model for this config structure and we can reach rapid consensus on it.
  • If we anticipate that command structure will look fundamentally different with a different config structure (i.e. preserving command compatibility should outweigh config file compatibility).

In view both of these cases as unlikely, so I would advocate for preserving the current structure for the time-being. However, since this is a fairly important design choice, I want to offer a short period of discussion before finalizing for just the initial release. Thank you to @turkenh for always having an eye on UX and providing thorough reviews with very constructive feedback :)

cc @negz @grantgumina @bassam @jbw976 @turkenh @muvaf

M1 Mac Instructions

While up is a native M1 Mac executable available in homebew, developers on M1 macs may wish to run UXP against a local Kind or Minikube cluster for testing. UXP already supports arm64 images so any arm64-compatible version of Kubernetes should run if Docker version > 3.3.1 is installed.

Docker

Ensure that you are running a version of Docker that supports Apple Silicon: https://docs.docker.com/docker-for-mac/apple-silicon/

Kind

M1 Mac support (via arm64 node images) in Kind is currently a WIP.

There is a workaround to build your own images: kubernetes-sigs/kind#166 (comment)

Until issue #2176 is closed, a custom image can be used as in the example below:

brew install kind
kind create cluster --image rossgeorgiev/kind-node-arm64:v1.21
up uxp install

Minikube

Minikube currently supports M1 Macs out of the box:

brew install minikube
minikube start
up uxp install

Should up uxp install be more idempotent?

Currently if you run up uxp install on a cluster that already has UXP, it comes back with an error and an error code. Is this the right behavior?

Looking at the docs and CLI options, I'm not sure to determine if UXP is already running on a cluster using up, which may force some users to install and check error codes if they are writing deployment scripts.

$ up uxp install                            
up: error: chart already installed with version 1.2.1-up.1
$ echo $?
1

Support managing control plane tokens

Self-hosted control planes use tokens to establish communication with Upbound Cloud. Currently, users are able to create a token for a self-hosted control plane when running up cloud xp attach <name>, which both creates the control plane on Upbound Cloud and returns the token to connect. However, there is currently not an interface in the UI to manage control plane tokens. It would be great to give users the ability to manage them in up with commands such as:

up cloud xp token list <control-plane-id>: list all tokens for a control plane
up cloud xp token delete <token-id>: delete a specified control plane token
up cloud xp token create <control-plane id>: create a new token for the specified control plane

Setup publishing location for binaries

The up binaries need to be made available for download. Possible options include attaching them to the GitHub release, pushing them to a bucket, or other.

Implement up login

The first command that will need to be supported by up is login, which will allow users to login to Upbound Cloud and store their credentials. By default, this command should be interactive, prompting users for username and password. Providing flags for --username and --password should also be supported, as well as overriding with environment variables. By default, credentials will be stored in ~/.up/credentials.json.

Print status of controlplane in controlplane list output

What problem are you facing?

As an SRE, I will want to create a new controlplane with up controlplane create and then monitor for the readiness of the controlplane from a scripted tool.

How could Upbound help solve your problem?

Inclue a Ready column with the output of up controlplane list:

NAME                 ID                                     SELF-HOSTED		STATUS
kubeconfigtest       a5a3f5cb-df6f-4c25-8529-08301531587f   false		Ready
hasan-test           44c83a5b-ce4b-4c07-8d37-1fc08440e7ac   true		Ready
demo-control-plane   5949c08a-0b65-492e-a22c-7387b0877510   false		Creating
Michael Test         747379cf-0adc-47b1-8058-fba81e915f31   false		Deleting

Support `up cloud logout`

Currently when users login with up cloud login we store a session token in ~/.up/config.json that will be valid for 30 days (unless user revokes sessions in the UI). We should also make it easy to revoke these individual session tokens using the CLI in the event they are compromised. up cloud logout will take no arguments and will use the default profile to log out unless overridden by --profile. This will invalidate the current stored session token.

Summary of the installation in the output of install command

After a Helm installation, the following is printed:

NAME: uxp
LAST DEPLOYED: Mon May 10 19:29:06 2021
NAMESPACE: upbound-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
By proceeding, you are accepting to comply with terms and conditions in https://licenses.upbound.io/upbound-software-license.html

✨ Thank you for installing Universal Crossplane!
🚀 You can now connect your cluster to Upbound Cloud!

Example command:

$ up cloud controlplane attach <control plane name> | \
up uxp connect --token-secret-name upbound-control-plane-token --namespace upbound-system -

It tells you which namespaces it's installed into and the next steps. I think it'd be great to have something similar to be printed so that users knows the next step and it's a confirmation that the installation went through without errors (right now, it just exits)

Printing confirmation of login information

$ up cloud login
Username: muvaf
Password:
$

I log in with up cloud login with correct credentials successfully, but in order to know that it's successful I need to check the return code. It'd be great to print where the credentials are stored and which profile is used after a successful login.

Document initial and anticipated supported commands

In order to create a coherent experience for up users, we should document all of the commands we aim to support in the initial release, as well as any commands we know we may want to support in the future. Thinking about the long-term experience will inform the design decisions we make initially.

UX around installed release name and namespace

Currently we force users to either be upgrading from a helm release named crossplane or universal-crossplane. Though it is not a frequent occurrence, users are not required to actually helm install Crossplane or UXP with those names. This means that as up currently functions, users could not interact with installs that use alternate names. A simple solution for this case would be to support a --name flag for all UXP commands. However, this makes our installer abstraction somewhat leaky in that a release is a helm concept. In practice, any other installer we build may also need to support "names" for installs as well, and would likely want to support upgrading a helm installed Crossplane, so it may not pose much of an issue. In the worst case, the name flag would be ignored by other installer backends. If the --name flag had a UXP_NAME env var counterpart, dealing with alternatively named installs may not be too cumbersome, but there has also been some discussion around storing UXP install information in ~/.up/config.json.

Up should provide installed information

For operators the up command should provide information about the cluster's installed crossplane.

For example:

$ up uxp info
Universal Crossplane version 1.2.1 running.up.1
$ up uxp status
Healthy (exit code 0)
$ up uxp status
The Upbound RBAC controller is unhealthy (exit code -1)

Add PR and Issue templates

This repo should have PR and issue templates to make it easier for folks to report bugs and make contributions.

Project licensing

Our CLI needs to be open sourced under Apache 2.0, similar to how upbound/universal-crossplane is today. Additionally, we need to have a usage license for this project like UXP does.

AC's

Support configurable log level

Users should be able to run commands with verbose logging by passing a top-level flag. This can be accomplished by passing a logger down through the command tree.

Implement basic packaging commands

What problem are you facing?

Users currently have to either download the Crossplane CLI or know how to build a Crossplane package using Docker (or other OCI image tooling) in addition to up to accomplish the full life-cycle of building, pushing, and installing packages alongside UXP and other Upbound services.

How could Upbound help solve your problem?

Users should be able to build and push Crossplane packages (Provider/Configuration) to the Upbound registry without needing any tooling outside of up. The initial supported commands should include:

up xpkg build
up xpkg push

Future commands may include:

up xpkg init
up xpkg pull

Epic https://github.com/upbound/roadmap/issues/34

/points 5

Publish checksums and check them in download script

All downloads of up should be checked against a checksum. Checksums can be automatically published on github for releases, but we should consider publishing them alongside binaries on https://cli.upbound.io so that are present on dev builds as well.

Add integration tests

Every PR and merge to main should run a set of integration tests against a live k8s cluster and an Upbound Cloud account.

Create new token in `up cloud ctp attach` if control plane already exists

Currently if a self-hosted control plane already exists we don't have a way to connect to it. It would be nice if up cloud ctp attach would produce a token if a control plane already exists, but that is problematic right now because:

  1. We can have multiple control planes with the same name in an account, meaning the name is not a unique identifier.
  2. The Create call for control planes in the Upbound API does not return a helpful error for identifying the control plane by ID in the case that a control plane already exists with the specified KubeClusterID.

We do have a up cloud ctp list command now, which makes it easy to get a control plane ID. One simple fix would be to add something like --existing=<uuid> to up cloud ctp attach in the case where we want to use a self-hosted control plane that already exists.

That being said, self hosted control planes are lightweight and easy to create and delete, so users can always just up cloud xp delete <id> and run up cloud attach again.

Better Compatibility on KUBECONFIG with other Kubernetes Clients

Currently, if KUBECONFIG env. variable points to a list of kubeconfig files delimited by :, up fails with the following error:

Usage: up cloud login

Login to Upbound Cloud.

Flags:
  -h, --help                               Show context-sensitive help.
  -v, --version                            Print version and exit.

      --endpoint=https://api.upbound.io    Endpoint used for Upbound API ($UP_ENDPOINT).
      --profile=STRING                     Profile used to execute command ($UP_PROFILE).
  -a, --account=STRING                     Account used to execute command ($UP_ACCOUNT).

  -u, --username=STRING                    Username used to execute command ($UP_USER).
  -p, --password=STRING                    Password for specified user. '-' to read from stdin ($UP_PASSWORD).
  -t, --token=STRING                       Token used to execute command. '-' to read from stdin ($UP_TOKEN).

up: error: --kubeconfig: stat file1:file2: no such file or directory (from envar KUBECONFIG="file1:file2")

Under the same environment, kubectl works as expected. I have tested this with up cloud login as shown above.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.