Skip to content

Instantly share code, notes, and snippets.

@sowasred2012
Last active October 1, 2020 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sowasred2012/92e81f0915d0bc122f46179fd40c3843 to your computer and use it in GitHub Desktop.
Save sowasred2012/92e81f0915d0bc122f46179fd40c3843 to your computer and use it in GitHub Desktop.

Contract CLI

Contents

Installation

  • Clone the UA contracts repo
    • If you can't see the repo, speak to someone on the CS team (i.e. Francesco, Allan or Uros), and they can give you access.
  • In a terminal, make sure you have Go installed with go version; if you don't, install it:
    • on Ubuntu: sudo snap install go --classic
    • on macOS: brew install go
  • cd into the directory of the repo you just cloned
  • Run go install ./...
    • I ran into a problem at this point when it tried to install dependencies, and ultimately it was a SSH problem that was fixed by adding the below to ~./gitconfig:
    [url "git@github.com:"]
        insteadOf = https://github.com/
    
    • If after updating your gitconfig you encounter the below errror, again ask the CS team to add you to the CanonicalLtd salesforce repos:
      • reading github.com/CanonicalLtd/salesforce/go.mod at revision v1.11.1: unknown revision 1.11.1
  • A successful installation will add the contract to a bin directory e.g. ~/go/bin/contract.
    • I was advised to then add this my .bashrc, export PATH=$PATH:/home/go/bin, but I had trouble with that, and ended up creating an alias in .bashrc instead: alias contract="~/go/bin/contract".
  • You should now be able to type contract on the command line and see a significant list of commands.

Local testing & public demo setup

While the advantage-shop branch is active, a publicly accessible demo will already be available to use. If you want to test locally, or the demo is not available, you can do the following:

Local testing

Make sure you have a clone of the ubuntu.com repo. Note that this links to the advantage-shop branch, which will remain active while we are QAing the initial release of the shop.

On the advantage-shop branch, we are already using the staging version of the contract API and Stripe so there's no need to change anything. You can just run the site with sudo docker-compose up -d, followed by dotrun (or ./run on macos).

Once the advantage-shop branch is merged into master, that demo will cease to exist, and the repo will be referencing the production version of the contract API and Stripe, so we'll need to update some variables locally to use staging again.

In that case, create a branch to work from, and open the following files:

  • .env
  • webapp/advantage.py
  • webapp/app.py

In each file, there will be a contract API url i.e. https://contracts.canonical.com. For testing, we want this to point to the staging environment: https://contracts.staging.canonical.com

To use the Stripe staging environment, open the following files:

  • .env
  • webapp/views.py

In each file, there will be a string beginning with pk_live_ followed by a run of alphanumeric characters. Update these to pk_test_yndN9H0GcJffPe0W58Nm64cM00riYG4N46. You can then run the site with sudo docker-compose up -d, followed by dotrun (or ./run on macos).

Public demo setup (post initial launch)

To get a publicly accessible demo running, follow the steps for local testing, commit these changes, push to your fork of the ubuntu.com repo, and create a PR. This should trigger the creation of a demo anybody can use - if you have problems, speak to a member of the webteam.

Final checks

From this point on, I am largely running through docs already available on the ua-contracts repo, but filtered through my own experience of using the tool to develop /advantage and /advantage/subscribe.

Log in to staging

The staging deployment of the UA contract service must be used for debugging and QAing. Do not use production. To do that, pass --url https://contracts.staging.canonical.com to every contract command invocation. Alternatively, set the CONTRACTS_URL environment variable:

export CONTRACTS_URL='https://contracts.staging.canonical.com' # bash, zsh
# or
set -x CONTRACTS_URL 'https://contracts.staging.canonical.com' # fish

From now on, for simplicity, this document assumes that you have the environment variable set, hence the --url option is always omitted.

Log in by running contract login --all and then opening one of the suggested locations in order to complete the authentication process using Ubuntu SSO.

To double check that you are using staging, run contract whereami | grep url.

Permissions

In order to create or modify contracts or renewals, including setting up and sharing accounts with customized contracts for testing purposes, a CLI user must be assigned the contract ACL. To do that, first ask the user to log in to https://auth.contracts.staging.canonical.com/ so that its corresponding database user is created in the UA contracts database. Then run contract grant-acl contract <example@canonical.com>.

After running the above, the user identified by <example@canonical.com> is essentially a super-user for all operations concerning accounts, contracts and renewals. At any point we can check what ACLs are granted to a user by running contract show-acl <example@canonical.com>.

Files to create

You'll largely be working with three different entities while testing:

  • Accounts
  • Contracts
  • Renewals

An SSO user can have multiple accounts, each account can have multiple contracts, and each contract can have multiple renewals (though will typically only have one).

You will be creating or updating at least one, if not all of these entities at various points in your testing, so it's handy to have a directory with a few files present (doesn't have to be in any of the repos you've cloned):

  • account.yaml
  • contract.yaml
  • renewal.json

Accounts

Accounts are automatically created if a SSO user logs in to /advantage or /advantage/subscribe, and they are given a free contract. However, they will not yet be able to make purchases via the shop, as they don't have admin permissions. You will need to adjust this*.

The first step is to find the ID and name of the account belonging to the new user. You can discover the account IDs belonging to a given SSO user by using their email with contract status <example@canonical.com>. This will return a list of all accounts belonging to that user, as well as a list of all contracts belonging to those accounts.

A new SSO user will only have one account, so grab that ID and account name (this is usually their SSO email). Open account.yaml and populate with the following:

id: <account id>
name: <account name>
externalAccountIDs:
  - origin: Salesforce
    IDs:
      - this-can-be-anything

What we're doing here is giving them an external account ID with an origin of "Salesforce", this is (for the moment) how we determine whether a user is able to make purchases on an account.

Then run contract update-account path/to/account.yaml, and it should return a summary of the account, with the new Salesforce fake account. It may return an error if the Salesforce account ID already exists in the contracts API, if that happens try a different ID.

The user will now be able to make purchases.

*this entire section should become irrelevant when guest checkout is implemented, as it involves implementing an endpoint that, for logged in SSO users, will automatically do this for us if the user doesn't already have admin permissions on an enterprise account.

Contracts

Now that the user can make purchases, any successful purchases automatically create contracts, and the user will see them when they are redirected to /advantage when their payment succeeds.

If you want to test pro-rating on a new account, you'll need to create some contracts with end dates you've set. Open contract.yaml, and populate it with:

name: "<whatever you like>"
createdBy: <something-to-indentify-you>
effectiveto: 2100-01-01T00:00:00Z
products:
  - uai-advanced-desktop
externalAssetIDs:
  origin: Salesforce
  IDs:
    - <anything-unique>

  • name is what will show up as the contract name in the list on /advantage.
  • createdBy can be anything i.e. scott-mn
  • effectiveto is the end date of the contract, set this to something less than a year from now, and you'll see prorating happen when making purchases i.e. 2021-01-27T00:00:00Z
  • externalAssetIDs: IDs can be anything unique i.e. my-test-asset-1. If you're planning to attach a renewal to the contract, make a note of this ID.

To attach this to a particular account, find the account ID (see previous section), and run contract add-contract <account id> path/to/contract.yaml.

Renewals

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment