class NexClient::Cli

Public Instance Methods

run() click to toggle source

include whatever modules you need

# File lib/nex_client/cli.rb, line 12
    def run
      program :name, 'nex-cli'
      program :version, NexClient::VERSION
      program :description, 'Nex!™ PaaS Client'
      default_command :help

      command :addons do |c|
        c.syntax = 'nex-cli addons [APP_NAME] [options]'
        c.summary = 'Manage addons'
        c.description = 'List addons'
        c.example 'list all active addons', 'nex-cli addons'
        c.example 'list all active addons for myapp', 'nex-cli addons myapp'
        c.example 'list all including terminated addons', 'nex-cli addons --all'
        c.option '--all', 'list all addons (no filtering)'
        c.option '--status <active|terminated>', String, 'list all addons in a given status'
        c.option '--service <mysql|redis|mongo26|kafka|minio>', String, 'list all addons for a specific service'
        c.action do |args, options|
          NexClient::Commands::Addons.list(args,options)
        end
      end

      command :'addons:create' do |c|
        c.syntax = 'nex-cli addons:create SERVICE APP_NAME'
        c.summary = 'Create addons'
        c.description = 'Create addons for your apps. Available addons: mysql | redis | mongo26 | kafka | minio'
        c.example 'create mysql addon for myapp', 'nex-cli addons:create mysql myapp'
        c.example 'create redis addon for myapp', 'nex-cli addons:create redis myapp'
        c.option '--size SIZE', Integer, 'specify container size (default: 2, min: 1, max: 20). Container will have N shares of CPU and N*128M of memory.'
        c.option '--http-log-drain DRAIN_URL', String, 'specify the URL of a remote log drain'
        c.option '--region-balancing REGIONS', String, 'specify how the addon should be proportionally distributed geographically. E.g. "all" or "ap-southeast-1,us-west-2" or "ap-southeast-1=1,us-west-2=2".'
        c.action do |args, options|
          NexClient::Commands::Addons.create(args,options)
        end
      end

      command :'addons:delete' do |c|
        c.syntax = 'nex-cli addons:delete ADDON_NAME'
        c.summary = 'Delete addons'
        c.description = 'Permanently delete an addons'
        c.example 'delete addon my-addon', 'nex-cli addons:delete my-addon'
        c.action do |args, options|
          NexClient::Commands::Addons.destroy(args,options)
        end
      end

      command :'addons:down' do |c|
        c.syntax = 'nex-cli addons:down ADDON_NAME [options]'
        c.summary = 'Scale addons down'
        c.description = 'Bring nodes down for a given addon'
        c.example 'scale myaddon down by removing one node', 'nex-cli addons:down myaddon'
        c.example 'scale myaddon down by removing two nodes', 'nex-cli addons:down myaddon --count 2'
        c.option '--count NUMBER', String, 'number of nodes to bring down'
        c.option '--region REGION', String, 'region to scale down'
        c.action do |args, options|
          NexClient::Commands::Addons.scale(:down,args,options)
        end
      end

      command :'addons:events' do |c|
        c.syntax = 'nex-cli addons:events APP_NAME [options]'
        c.summary = 'Gather system events'
        c.description = 'Gather system events for a given addon'
        c.example 'display events for myaddon', 'nex-cli addons:events myaddon'
        c.example 'display 100 events for myaddon', 'nex-cli addons:events --tail 100 myaddon'
        c.option '--tail NUMBER', String, 'number of events to retrieve (default: 50)'
        c.option '--type TYPE', String, 'filter events on type (e.g. status, container)'
        c.action do |args, options|
          NexClient::Commands::Addons.events(args,options)
        end
      end

      command :'addons:info' do |c|
        c.syntax = 'nex-cli addons:info ADDON_NAME [options]'
        c.summary = 'Show information about an addon'
        c.description = 'Show all details about an addon'
        c.example 'show details about myaddon', 'nex-cli addons:info myaddon'
        c.option '--full-vars', 'do not truncate environment variables'
        c.action do |args, options|
          NexClient::Commands::Addons.info(args,options)
        end
      end

      command :'addons:logs' do |c|
        c.syntax = 'nex-cli addons:logs ADDON_NAME [options]'
        c.summary = 'Gather addon logs'
        c.description = 'Gather container logs for a given addon'
        c.example 'gather logs for myaddon', 'nex-cli addons:logs myaddon'
        c.example 'gather logs for myapp with a tail of 50', 'nex-cli addons:logs --tail 50 myaddon'
        c.option '--tail NUMBER', String, 'number of lines to retrieve for each container'
        c.action do |args, options|
          NexClient::Commands::Addons.logs(args,options)
        end
      end

      command :'addons:restart' do |c|
        c.syntax = 'nex-cli addons:restart APP_NAME'
        c.summary = 'Restart an addon'
        c.description = 'Initiate a phased restart of an addon'
        c.example 'phase-restart my-awesome-app', 'nex-cli addons:restart my-awesome-app'
        c.action do |args, options|
          NexClient::Commands::Addons.restart(args,options)
        end
      end

      command :'addons:ssh' do |c|
        c.syntax = 'nex-cli addons:ssh ADDON_NAME [options]'
        c.summary = 'SSH to an addon container [platform admin]'
        c.description = 'Initiate an SSH session to a given addon container'
        c.example 'ssh to addon myaddon', 'nex-cli addons:ssh myaddon'
        c.action do |args, options|
          NexClient::Commands::Addons.ssh(args,options)
        end
      end

      command :'addons:up' do |c|
        c.syntax = 'nex-cli addons:up ADDON_NAME [options]'
        c.summary = 'Scale addons up'
        c.description = 'Add nodes to a given addon'
        c.example 'scale myaddon up by adding one node', 'nex-cli addons:up myaddon'
        c.example 'scale myaddon up by adding two nodes', 'nex-cli addons:up myaddon --count 2'
        c.option '--count NUMBER', String, 'number of nodes to bring up'
        c.option '--region REGION', String, 'region to scale up'
        c.action do |args, options|
          NexClient::Commands::Addons.scale(:up,args,options)
        end
      end

      command :'addons:update' do |c|
        c.syntax = 'nex-cli addons:update ADDON_NAME [options]'
        c.summary = 'Update addon settings'
        c.description = 'Update addon settings'
        c.example 'change container size to 4', 'nex-cli addons:update myaddon --size 4'
        c.example 'balance containers equally between regions', 'nex-cli apps:update myapp --region-balancing="ap-southeast-1,us-west-2"'
        c.example 'deploy more containers in one region', 'nex-cli apps:update myapp --region-balancing="ap-southeast-1=1,us-west-2=2"'
        c.example 'scale containers across all regions', 'nex-cli apps:update myapp --region-balancing=all'
        c.option '--size SIZE', Integer, 'change container size (default: 2, min: 1, max: 20). Container will have N shares of CPU and N*128M of memory. [restart required]'
        c.option '--http-log-drain DRAIN_URL', String, 'specify the URL of a remote log drain. [restart required]'
        c.option '--region-balancing REGIONS', String, 'specify how scalability should be handled per region. E.g. "all" or "ap-southeast-1,us-west-2" or "ap-southeast-1=1,us-west-2=2".'
        c.action do |args, options|
          NexClient::Commands::Addons.update(args,options)
        end
      end

      command :apps do |c|
        c.syntax = 'nex-cli apps [options]'
        c.summary = 'Manage apps'
        c.description = 'List, create, manage, scale and delete apps'
        c.example 'list all my active apps', 'nex-cli apps'
        c.example 'list all active apps for owner myorg', 'nex-cli apps --owner myorg'
        c.example 'list all my terminated apps', 'nex-cli apps --status terminated'
        c.example 'list all terminated apps for owner myorg', 'nex-cli apps --status terminated --owner myorg'
        c.example 'list all apps tagged ruby and rails', 'nex-cli apps --tags ruby,rails'
        c.option '--all', 'list all apps (no filtering)'
        c.option '--status <active|terminated>', String, 'list all apps in a given status'
        c.option '--ssl', 'list all apps with SSL enabled'
        c.option '--storage', 'list all apps with persistent storage'
        c.option '--owner HANDLE', 'list all apps for the specified owner. Use "@self" to display your apps including any organization you are part of'
        c.option '--image IMAGE', 'list the app with this image'
        c.option '--tags TAG_LIST', Array, 'comma separated list of tags to filter on'
        c.action do |args, options|
          NexClient::Commands::Apps.list(args,options)
        end
      end

      command :'apps:create' do |c|
        c.syntax = 'nex-cli apps:create DOCKER_IMAGE[:tag] [options]'
        c.summary = 'Create apps'
        c.description = 'Create new docker applications'
        c.example 'create new web-ruby application', 'nex-cli apps:create maestrano/web-ruby'
        c.example 'create new web-ruby application with increased container size', 'nex-cli apps:create maestrano/web-ruby --size 8'
        c.option '--env MYVAR=value,MYVAR2=value,...', Array, 'comma separated list of env variables'
        c.option '--env-file FILE', String, 'newline separated list of env variables (MYVAR=1) or YAML file'
        c.option '--no-ssl', 'disable SSL support (enabled by default)'
        c.option '--size SIZE', Integer, 'specify container size (default: 2, min: 1, max: 20). Container will have N shares of CPU and N*128M of memory.'
        c.option '--storage', 'enable persistent storage (/!\ only one node allowed)'
        c.option '--http-log-drain DRAIN_URL', String, 'specify the URL of a remote log drain'
        c.option '--owner ORGANIZATION_HANDLE', 'specify an organisation as owner (organization admin only)'
        c.option '--desc DESCRIPTION', String, 'description for this application (140 characters max)'
        c.option '--tags TAG_LIST', Array, 'comma separated list of tags describing this app'
        c.option '--region REGION', String, 'default region to use deploy/scale this application'
        c.option '--region-balancing REGIONS', String, 'specify how scalability should be handled per region. E.g. "all" or "ap-southeast-1,us-west-2" or "ap-southeast-1=1,us-west-2=2".'
        c.action do |args, options|
          NexClient::Commands::Apps.create(args,options)
        end
      end

      command :'apps:delete' do |c|
        c.syntax = 'nex-cli apps:delete APP_NAME'
        c.summary = 'Delete an app'
        c.description = 'Permanently delete an app'
        c.example 'delete my-awesome-app', 'nex-cli apps:delete my-awesome-app'
        c.action do |args, options|
          NexClient::Commands::Apps.destroy(args,options)
        end
      end

      command :'apps:down' do |c|
        c.syntax = 'nex-cli apps:down APP_NAME [options]'
        c.summary = 'Scale applications down'
        c.description = 'Bring nodes down for a given application'
        c.example 'scale myapp down by removing one node', 'nex-cli apps:down myapp'
        c.example 'scale myapp down by removing two nodes', 'nex-cli apps:down myapp --count 2'
        c.option '--count NUMBER', String, 'number of nodes to bring down'
        c.option '--region REGION', String, 'region to scale down'
        c.action do |args, options|
          NexClient::Commands::Apps.scale(:down,args,options)
        end
      end

      command :'apps:events' do |c|
        c.syntax = 'nex-cli apps:events APP_NAME [options]'
        c.summary = 'Gather system events'
        c.description = 'Gather system events for a given app'
        c.example 'display events for myapp', 'nex-cli apps:events myapp'
        c.example 'display 100 events for myapp', 'nex-cli apps:events --tail 100 myapp'
        c.option '--tail NUMBER', String, 'number of events to retrieve (default: 50)'
        c.option '--type TYPE', String, 'filter events on type (e.g. status, container)'
        c.action do |args, options|
          NexClient::Commands::Apps.events(args,options)
        end
      end

      command :'apps:info' do |c|
        c.syntax = 'nex-cli apps:info APP_NAME [options]'
        c.summary = 'Show information about an app'
        c.description = 'Show all details about an app'
        c.example 'show details about myapp', 'nex-cli apps:info myapp'
        c.option '--full-vars', 'do not truncate environment variables'
        c.action do |args, options|
          NexClient::Commands::Apps.info(args,options)
        end
      end

      command :'apps:logs' do |c|
        c.syntax = 'nex-cli apps:logs APP_NAME [options]'
        c.summary = 'Gather app logs'
        c.description = 'Gather container logs for a given app'
        c.example 'gather logs for myapp', 'nex-cli apps:logs myapp'
        c.example 'gather logs for myapp with a tail of 50', 'nex-cli apps:logs --tail 50 myapp'
        c.option '--tail NUMBER', String, 'number of lines to retrieve for each container'
        c.action do |args, options|
          NexClient::Commands::Apps.logs(args,options)
        end
      end

      command :'apps:restart' do |c|
        c.syntax = 'nex-cli apps:restart APP_NAME'
        c.summary = 'Restart an app'
        c.description = 'Initiate a phased restart of an app'
        c.example 'phase-restart my-awesome-app', 'nex-cli apps:restart my-awesome-app'
        c.action do |args, options|
          NexClient::Commands::Apps.restart(args,options)
        end
      end

      command :'apps:scm' do |c|
        c.syntax = 'nex-cli apps:scm APP_NAME [options]'
        c.summary = 'Manage source control for your apps'
        c.description = <<~HEREDOC
          Link/unlink an SCM (e.g. github, s3) to your applications

          Github:
          -------
          Use: --link github:repo[:branch] (--credentials GITHUB_OAUTH_TOKEN)
          The branch will be defaulted to your default repository branch if unspecified.
          Specifying 'credentials'is optional if your account on Nex!™ has been created through github or
          if the repository is public.

          S3:
          ---
          Use: --link s3:bucket/folder[:tar_package] --credentials AWS_KEY:AWS_SECRET
          The branch must be the name of an actual file. It will be defaulted to 'latest.tar.gz'. This filename will
          be overriden if you specify a different filename when sending deployment webhooks ('after' attribute).
          Specifying credentials is only required if the S3 bucket is private.
        HEREDOC
        c.example 'link myapp to github using some/repo on branch master', 'nex-cli apps:scm myapp --link github:some/repo'
        c.example 'link myapp to github using some/repo on branch develop', 'nex-cli apps:scm myapp --link github:some/repo:develop'
        c.example 'link myapp to s3 using a bucket, path and filename', 'nex-cli apps:scm myapp --link s3:bucket/folder:somefile.tar.gz --credentials AWS_KEY:AWS_SECRET'
        c.example 'link myapp to s3 to the latest.tar.gz file in folder', 'nex-cli apps:scm myapp --link s3:bucket/folder --credentials AWS_KEY:AWS_SECRET'
        c.option '--credentials api_key[:api_secret]', String, 'colon separated key/secret pair to use with the provider'
        c.option '--link <provider>:<repo>[:branch]', String, 'link your SCM repo to this application (github and s3 supported)'
        c.option '--unlink', 'unlink your SCM from the application'
        c.action do |args, options|
          NexClient::Commands::Apps.manage_scm(args,options)
        end
      end

      command :'apps:ssh' do |c|
        c.syntax = 'nex-cli apps:ssh APP_NAME [options]'
        c.summary = 'SSH to an app container [platform admin]'
        c.description = 'Initiate an SSH session to a given app container'
        c.example 'ssh to app myapp', 'nex-cli apps:ssh myapp'
        c.action do |args, options|
          NexClient::Commands::Apps.ssh(args,options)
        end
      end

      command :'apps:transfer' do |c|
        c.syntax = 'nex-cli apps:transfer APP_NAME OWNER_HANDLE [options]'
        c.summary = 'Transfer app ownership'
        c.description = 'Transfer an app to another organization or user'
        c.example 'transfer myapp to doecorp', 'nex-cli apps:transfer myapp doecorp'
        c.action do |args, options|
          NexClient::Commands::Apps.transfer(args,options)
        end
      end

      command :'apps:up' do |c|
        c.syntax = 'nex-cli apps:up APP_NAME [options]'
        c.summary = 'Scale applications up'
        c.description = 'Add nodes to a given application'
        c.example 'scale myapp up by adding one node', 'nex-cli apps:up myapp'
        c.example 'scale myapp up by adding two nodes', 'nex-cli apps:up myapp --count 2'
        c.option '--count NUMBER', String, 'number of nodes to bring up'
        c.option '--region REGION', String, 'region to scale up'
        c.action do |args, options|
          NexClient::Commands::Apps.scale(:up,args,options)
        end
      end

      command :'apps:update' do |c|
        c.syntax = 'nex-cli apps:update APP_NAME [options]'
        c.summary = 'Update apps settings'
        c.description = <<~HEREDOC
          Update general application settings and behaviour

          Log drain:
          ----------
          Use: --http-log-drain DRAIN_URL
          The log drain is a HTTP(s) URL where application logs will be POSTed.

          Default region:
          ---------------
          Use: --region REGION
          Containers will be deployed in the specified region by default if no region-balancing
          policies have been specified. This is only relevant when the Nex!™ platform has been deployed in multiple regions.

          Geo-Balancing:
          ---------------
          Use: --region-balancing REGIONS
          Specify how your containers should be distributed across the available Nex!™ regions. This is only relevant when the Nex!™ platform has been deployed
          in multiple regions.

          Options are the following:
            - evenly distribute across all regions: --region-balancing=all
            - eventy distribute across specified regions: --region-balancing="ap-southeast-1,us-west-2"
            - distribute with relative weights: --region-balancing="ap-southeast-1=1,us-west-2=2"

          Web Application Firewall (WAF)
          ------------------------------
          Use: --waf-rules [PATH]
          Specify a JSON (.json) or YAML (.yml) file describing the security rules to apply/ignore. If no files are specified you will be prompted to
          paste rules in JSON format in the terminal.
          The WAF always runs in SIMULATE mode by default - this means security events will be logged but no requests will be blocked.

          The list of base rules applied by default is available here: https://github.com/p0pr0ck5/lua-resty-waf/tree/master/rules

          The base WAF behaviour can be extended by passing a JSON (or YAML) manifest to '--waf-rules' with the following format:
            {
              // Whether the WAF should be enabled, disabled or do log-only
              // 'ACTIVE', 'INACTIVE' or 'SIMULATE'
              "mode": "SIMULATE",

              // Array of rule IDs to ignore
              "ignore_rule": [],

              // Array of rulesets to ignore
              "ignore_ruleset": [],

              // Array of ['rulename','rule'] objects
              "add_ruleset_string": [],

              // Rules sieves allow you to apply/ignore rules based on a
              // specific context such as request parameters
              // Array of ['rule_id', [{ sieve_cond }, { sieve_cond }] ] objects
              "sieve_rule": []
            }
          See this for more info: https://github.com/p0pr0ck5/lua-resty-waf
          See this for rule sieves: https://github.com/p0pr0ck5/lua-resty-waf/wiki/Rule-Sieves

        HEREDOC
        c.example 'change container size to 4', 'nex-cli apps:update myapp --size 4'
        c.example 'balance containers equally between regions', 'nex-cli apps:update myapp --region-balancing="ap-southeast-1,us-west-2"'
        c.example 'deploy more containers in one region', 'nex-cli apps:update myapp --region-balancing="ap-southeast-1=1,us-west-2=2"'
        c.example 'scale containers across all regions', 'nex-cli apps:update myapp --region-balancing=all'
        c.option '--desc DESCRIPTION', String, 'update the application description'
        c.option '--http-log-drain DRAIN_URL', String, 'specify the URL of a remote log drain. [restart required]'
        c.option '--image-tag IMAGE_TAG', String, 'update the docker image tag [restart required]'
        c.option '--size SIZE', Integer, 'change container size (default: 2, min: 1, max: 20). Container will have N shares of CPU and N*128M of memory. [restart required]'
        c.option '--tags TAG_LIST', String, 'comma separated list of tags to use to describe the app'
        c.option '--region REGION', String, 'default region to use deploy/scale this application'
        c.option '--region-balancing REGIONS', String, 'specify how the app should be proportionally distributed geographically. E.g. "all" or "ap-southeast-1,us-west-2" or "ap-southeast-1=1,us-west-2=2". [restart required]'
        c.option '--waf-rules [PATH]', String, 'specify web application firewall rules using JSON or YAML file (prompt will appear otherwise). [restart required]'
        c.action do |args, options|
          NexClient::Commands::Apps.update(args,options)
        end
      end

      command :'apps:vars' do |c|
        c.syntax = 'nex-cli apps:vars APP_NAME [options]'
        c.summary = 'Manage app environment variables'
        c.description = 'List and update environment variables for an app'
        c.example 'list all env variables for myapp', 'nex-cli apps:vars myapp'
        c.example 'Add env variables to myapp', 'nex-cli apps:vars myapp --add MYVAR1=VAL1,MYVAR2=VAL2'
        c.example 'Delete env variables from myapp', 'nex-cli apps:vars myapp --delete MYVAR,MYVAR'
        c.example 'Add env variables to myapp from file', 'nex-cli apps:vars myapp --env-file ~/myenvfile'
        c.example 'Add env variables to myapp from file and prefix all vars with foo (foo_myvar)', 'nex-cli apps:vars myapp --env-file ~/myenvfile --env-prefix foo'
        c.option '--add MYVAR=value,MYVAR2=value,...', Array, 'comma separated list of env variables'
        c.option '--delete MYVAR,MYVAR2,...', Array, 'comma separated list of env variables'
        c.option '--delete-all', 'delete all vars'
        c.option '--full-vars', 'do not truncate environment variables'
        c.option '--env-file FILE', String, 'newline separated list of env variables (MYVAR=1) or YAML file. Note that YAML parsing is recursive.'
        c.option '--env-prefix PREFIX', String, 'prefix all variables contained in the env file with the specified prefix (PREFIX_MYVAR)'
        c.option '--raw', 'vars are returned in a environment file format (key=value)'
        c.option '--yaml', 'vars are returned in a yaml file format'
        c.action do |args, options|
          NexClient::Commands::Apps.manage_vars(args,options)
        end
      end

      command :'apps:open' do |c|
        c.syntax = 'nex-cli apps:open APP_NAME'
        c.summary = 'Open app url'
        c.description = 'Open app in your browser'
        c.example 'open app for myapp', 'nex-cli apps:open myapp'
        c.action do |args, options|
          NexClient::Commands::Apps.open(args,options)
        end
      end

      command :certs do |c|
        c.syntax = 'nex-cli certs [APP_OR_ORG_NAME] [options]'
        c.summary = 'Manage certs'
        c.description = 'List ssl certificates'
        c.example 'list all certs', 'nex-cli certs'
        c.example 'list all certs under app myapp', 'nex-cli certs myapp'
        c.example 'list all certs under organization myorg', 'nex-cli certs myorg'
        c.example 'list all certs matching example.com', 'nex-cli certs --domain example.com'
        c.option '--domain', 'list all certs matching the provided cname'
        c.action do |args, options|
          NexClient::Commands::SslCertificates.list(args,options)
        end
      end

      command :'certs:create' do |c|
        c.syntax = 'nex-cli certs:create CNAME APP_OR_ORG_NAME'
        c.summary = 'Create ssl certificates'
        c.description = 'Create certs for your apps'
        c.example 'create some.example.com certificate for myapp', 'nex-cli certs:create some.example.com myapp'
        c.example 'create *.example.com certificate for myorg', 'nex-cli certs:create *.example.com myorg'
        c.option '--cert CERT_PATH', String, 'path to pem certificate'
        c.option '--bundle BUNDLE_PATH', String, 'path to certificate bundle'
        c.option '--privkey KEY_PATH', String, 'path to certificate private key'
        c.action do |args, options|
          NexClient::Commands::SslCertificates.create(args,options)
        end
      end

      command :'certs:delete' do |c|
        c.syntax = 'nex-cli certs:delete CNAME'
        c.summary = 'Delete certs'
        c.description = 'Permanently delete a ssl certificate'
        c.example 'delete certificate for some.example.com', 'nex-cli certs:delete some.example.com'
        c.action do |args, options|
          NexClient::Commands::SslCertificates.destroy(args,options)
        end
      end

      command :cubes do |c|
        c.syntax = 'nex-cli cubes [options]'
        c.summary = 'Manage cubes [platform admin]'
        c.description = 'List, create, manage, scale and delete cubes'
        c.example 'list all cubes', 'nex-cli cubes'
        c.example 'list all cubes for owner myorg', 'nex-cli cubes --owner myorg'
        c.example 'list all terminated cubes', 'nex-cli cubes --status terminated'
        c.example 'list all terminated cubes for owner myorg', 'nex-cli cubes --status terminated --owner myorg'
        c.example 'list cube xyz.domain.co', 'nex-cli cubes --name xyz.domain.co'
        c.example 'list cube xyz', 'nex-cli cubes --name xyz'
        c.option '--all', 'list all cubes (no filtering)'
        c.option '--status <provisioning|running|stopped|terminated>', String, 'list all cubes in a given status'
        c.option '--storage', 'list all cubes with persistent storage'
        c.option '--app APP_NAME', 'list all cubes attached to the specified app'
        c.option '--addon ADDON_NAME', 'list all cubes attached to the specified addon'
        c.option '--owner HANDLE', 'list all cubes for the specified owner'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.list(args,options)
        end
      end

      command :'cubes:download' do |c|
        c.syntax = 'nex-cli cubes:download CUBE_ID REMOTE_SRC_PATH [DST_LOCAL_PATH]'
        c.summary = 'Download a file from a container'
        c.description = 'Download a file from a container'
        c.example 'download file /tmp/foo.txt locally', 'nex-cli cubes:download mycube /tmp/foo.txt'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.download(args,options)
        end
      end

      command :'cubes:events' do |c|
        c.syntax = 'nex-cli cubes:events CUBE_ID [options]'
        c.summary = 'Gather system events'
        c.description = 'Gather system events for a given cube'
        c.example 'display events for mycube', 'nex-cli cubes:events mycube'
        c.example 'display 100 events for mycube', 'nex-cli cubes:events --tail 100 mycube'
        c.option '--tail NUMBER', String, 'number of events to retrieve (default: 50)'
        c.option '--type TYPE', String, 'filter events on type (e.g. status, container)'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.events(args,options)
        end
      end

      command :'cubes:info' do |c|
        c.syntax = 'nex-cli cubes:info CUBE_ID [options]'
        c.summary = 'Display information on a cube'
        c.description = 'Display information about a given cube'
        c.example 'display info for mycube', 'nex-cli cubes:info mycube'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.info(args,options)
        end
      end

      command :'cubes:logs' do |c|
        c.syntax = 'nex-cli cubes:logs CUBE_ID [options]'
        c.summary = 'Gather cube logs'
        c.description = 'Gather container logs for a given cube'
        c.example 'gather logs for mycube', 'nex-cli cubes:logs mycube'
        c.example 'gather logs for mycube with a tail of 50', 'nex-cli cubes:logs --tail 50 mycube'
        c.option '--tail NUMBER', String, 'number of lines to retrieve (default: 30)'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.logs(args,options)
        end
      end

      command :'cubes:restart' do |c|
        c.syntax = 'nex-cli cubes:restart CUBE_ID'
        c.summary = 'Restart a cube'
        c.description = 'Restart a cube'
        c.example 'restart cube xyz', 'nex-cli cubes:restart xyz'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.trigger_action(:restart,args,options)
        end
      end

      command :'cubes:snapshots' do |c|
        c.syntax = 'nex-cli cubes:snapshots CUBE_ID'
        c.summary = 'List cube snapshots'
        c.description = 'List all snapshots created for a given cube. This command is only effective for cubes with a backup strategy (e.g. addons)'
        c.example 'gather snapshots created for mycube', 'nex-cli cubes:snapshots mycube'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.snapshots(args,options)
        end
      end

      command :'cubes:start' do |c|
        c.syntax = 'nex-cli cubes:start CUBE_ID'
        c.summary = 'Start a cube'
        c.description = 'Start a cube'
        c.example 'start cube xyz', 'nex-cli cubes:start xyz'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.trigger_action(:start,args,options)
        end
      end

      command :'cubes:stop' do |c|
        c.syntax = 'nex-cli cubes:stop CUBE_ID'
        c.summary = 'Stop a cube'
        c.description = 'Stop a cube'
        c.example 'stop cube xyz', 'nex-cli cubes:stop xyz'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.trigger_action(:stop,args,options)
        end
      end

      command :'cubes:ssh' do |c|
        c.syntax = 'nex-cli cubes:ssh APP_NAME [options]'
        c.summary = 'SSH to a specific container [platform admin]'
        c.description = 'Initiate an SSH session to a given container'
        c.example 'ssh to cube some-uuid', 'nex-cli cubes:ssh some-uuid'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.ssh(args,options)
        end
      end

      command :'cubes:upload' do |c|
        c.syntax = 'nex-cli cubes:upload CUBE_ID LOCAL_SRC_PATH [DEST_PATH]'
        c.summary = 'Upload a file to a container'
        c.description = 'Upload a file to a container. If no DEST_PATH is specified then file will be created in /tmp.'
        c.example 'upload file foo.txt to remote /tmp directory', 'nex-cli cubes:upload mycube ./foo.txt'
        c.example 'upload file foo.txt to remote data directory', 'nex-cli cubes:upload mycube ./foo.txt /data/'
        c.action do |args, options|
          NexClient::Commands::CubeInstances.upload(args,options)
        end
      end

      command :cube_templates do |c|
        c.syntax = 'nex-cli cube_templates [options]'
        c.summary = 'Manage cube_templates [platform admin][legacy]'
        c.description = 'List, create, manage, scale and delete cube templates'
        c.example 'list all templates', 'nex-cli cube_templates'
        c.example 'list all docker templates', 'nex-cli cube_templates --stack docker'
        c.example 'list specific template', 'nex-cli cube_templates --name mytemplate'
        c.example 'list templates using image someimage', 'nex-cli cube_templates --image someimage'
        c.option '--stack <lxc|docker>', 'list all templates for the specified stack'
        c.option '--name TEMPLATE_NAME', 'list specific template'
        c.option '--image IMAGE_NAME', 'list templates using a specific image'
        c.action do |args, options|
          NexClient::Commands::CubeTemplates.list(args,options)
        end
      end

      command :domains do |c|
        c.syntax = 'nex-cli domains [APP_NAME] [options]'
        c.summary = 'Manage domains'
        c.description = 'List domains'
        c.example 'list all domains', 'nex-cli addons'
        c.example 'list all domains matching example.com', 'nex-cli domains --domain example.com'
        c.option '--domain', 'list all domains matching the provided cname'
        c.action do |args, options|
          NexClient::Commands::Domains.list(args,options)
        end
      end

      command :'domains:create' do |c|
        c.syntax = 'nex-cli domains:create CNAME APP_NAME'
        c.summary = 'Create domains'
        c.description = 'Create domains for your apps'
        c.example 'create some.example.com cname for myapp', 'nex-cli domains:create some.example.com myapp'
        c.action do |args, options|
          NexClient::Commands::Domains.create(args,options)
        end
      end

      command :'domains:delete' do |c|
        c.syntax = 'nex-cli domains:delete CNAME'
        c.summary = 'Delete domains'
        c.description = 'Permanently delete a domain'
        c.example 'delete domain some.example.com', 'nex-cli domains:delete some.example.com'
        c.action do |args, options|
          NexClient::Commands::Domains.destroy(args,options)
        end
      end

      command :'exec-tasks' do |c|
        c.syntax = 'nex-cli exec-tasks [EXECUTOR_NAME] [options]'
        c.summary = 'Manage execution tasks'
        c.description = 'List executions tasks (all or for specific resources)'
        c.example 'list all execution tasks', 'nex-cli exec-tasks'
        c.example 'list all execution tasks for cube 111-222-333', 'nex-cli exec-tasks 111-222-333'
        c.action do |args, options|
          NexClient::Commands::ExecTasks.list(args,options)
        end
      end

      command :'exec-tasks:info' do |c|
        c.syntax = 'nex-cli exec-tasks:info [TASK_ID] [options]'
        c.summary = 'Display an execution task'
        c.description = 'Display an execution task'
        c.example 'Display execution tasks aaaa-2222', 'nex-cli exec-tasks:info aaaa-2222'
        c.action do |args, options|
          NexClient::Commands::ExecTasks.info(args,options)
        end
      end

      command :'exec-tasks:create' do |c|
        c.syntax = 'nex-cli exec-tasks:create [options]'
        c.summary = 'Create execution task'
        c.description = <<~HEREDOC
          Create execution task for a resource such as a cube, app, addon or rack

          Crontab Format:
          ----------------
          * * * * *
          - - - - -
          | | | | +-------------------> day of week (0 - 6) (Sunday=0)
          | | | +-----------------> month (1 - 12)
          | | +---------------> day of month (1 - 31)
          | +-------------> hour (0 - 23)
          +-----------> min (0 - 59)
        HEREDOC
        c.example 'Create task for cube 111-222', 'nex-cli exec-tasks:create --cube 111-222'
        c.example 'Create task for app myapp', 'nex-cli exec-tasks:create --app myapp'
        c.example 'Create task for addon myaddon', 'nex-cli exec-tasks:create --addon myaddon'
        c.example 'Create task for rack 10.0.1.1', 'nex-cli exec-tasks:create --rack 10.0.1.1'
        c.option '--app APP_NAME', String, 'name of the app to attach this task to'
        c.option '--addon ADDON_NAME', String, 'name of the addon to attach this task to'
        c.option '--crontab CRON_EXPRESSION', String, 'frequency expressed as cron expression'
        c.option '--cube CUBE_ID', String, 'id of the cube to attach this task to'
        c.option '--name TASK_NAME', String, 'name of this task'
        c.option '--rack RACK_IP', String, 'IP of the rack to attach this task to'
        c.option '--script SCRIPT_PATH', String, 'path to shell script'
        c.action do |args, options|
          NexClient::Commands::ExecTasks.create(args,options)
        end
      end

      command :'exec-tasks:delete' do |c|
        c.syntax = 'nex-cli exec-tasks:delete CNAME'
        c.summary = 'Delete execution task'
        c.description = 'Permanently delete an execution task'
        c.example 'Delete task aaaa-2222', 'nex-cli exec-tasks:delete aaaa-2222'
        c.action do |args, options|
          NexClient::Commands::ExecTasks.destroy(args,options)
        end
      end

      command :organizations do |c|
        c.syntax = 'nex-cli organizations [options]'
        c.summary = 'List organizations'
        c.description = 'List organizations'
        c.example 'list all organizations', 'nex-cli organizations'
        c.action do |args, options|
          NexClient::Commands::Organizations.list(args,options)
        end
      end

      command :racks do |c|
        c.syntax = 'nex-cli racks [options]'
        c.summary = 'Manage racks [platform admin]'
        c.description = 'List, create, manage, delete racks'
        c.example 'list all running racks', 'nex-cli racks'
        c.example 'list all running racks', 'nex-cli racks --status running'
        c.example 'list all stopped racks', 'nex-cli racks --status stopped'
        c.example 'list all terminated racks', 'nex-cli racks --status terminated'
        c.example 'list all racks', 'nex-cli racks --all'
        c.option '--all', 'list all racks (no filtering)'
        c.option '--status <provisioning|running|stopped|terminated>', String, 'list all racks in a given status'
        c.option '--type <compute|storage|routing|gateway>', String, 'list all racks of the specified type'
        c.option '--stack <lxc|docker>', String, 'list all compute racks for the specified stack'
        c.action do |args, options|
          NexClient::Commands::Racks.list(args,options)
        end
      end

      command :'racks:download' do |c|
        c.syntax = 'nex-cli racks:download IP_ADDRESS REMOTE_SRC_PATH [DST_LOCAL_PATH]'
        c.summary = 'Download a file from a rack'
        c.description = 'Download a file from a rack'
        c.example 'download file /tmp/foo.txt locally', 'nex-cli racks:download 10.0.1.1 /tmp/foo.txt'
        c.action do |args, options|
          NexClient::Commands::Racks.download(args,options)
        end
      end

      command :'racks:upload' do |c|
        c.syntax = 'nex-cli racks:upload IP_ADDRESS LOCAL_SRC_PATH [DEST_PATH]'
        c.summary = 'Upload a file to a rack'
        c.description = 'Upload a file to a rack. If no DEST_PATH is specified then file will be created in /tmp.'
        c.example 'upload file foo.txt to remote /tmp directory', 'nex-cli racks:upload 10.0.1.1 foo.txt'
        c.example 'upload file foo.txt to remote data directory', 'nex-cli racks:upload 10.0.1.1 foo.txt /data/'
        c.action do |args, options|
          NexClient::Commands::Racks.upload(args,options)
        end
      end

      command :'racks:ssh' do |c|
        c.syntax = 'nex-cli racks:ssh IP_ADDRESS [options]'
        c.summary = 'SSH to racks [platform admin]'
        c.description = 'Initiate an SSH session to a given rack'
        c.example 'ssh to rack with ip 10.1.2.3', 'nex-cli racks:ssh 10.1.2.3'
        c.action do |args, options|
          NexClient::Commands::Racks.ssh(args,options)
        end
      end

      command :users do |c|
        c.syntax = 'nex-cli users [options]'
        c.summary = 'List users'
        c.description = 'List users'
        c.example 'list all users', 'nex-cli users'
        c.example 'list all users in doecorp organization', 'nex-cli users --organization doecorp'
        c.example 'list all api-only users in doecorp organization', 'nex-cli users --api --organization doecorp'
        c.option '--org ORG_HANDLE', String, 'list all users in the specified organization'
        c.option '--organization ORG_HANDLE', String, 'list all users in the specified organization'
        c.option '--api', 'list api-only users'
        c.action do |args, options|
          NexClient::Commands::Users.list(args,options)
        end
      end

      command :'users:create' do |c|
        c.syntax = 'nex-cli users:create [options]'
        c.summary = 'Create API users'
        c.description = 'Create API users for organizations'
        c.example 'create api user for doecorp organization', 'nex-cli users:create doecorp'
        c.action do |args, options|
          NexClient::Commands::Users.create_api_user(args,options)
        end
      end

      command :'users:delete' do |c|
        c.syntax = 'nex-cli users:delete HANDLE [options]'
        c.summary = 'Delete API users'
        c.description = 'Delete API users from organizations'
        c.example 'delete api user doecorp/37fhsg', 'nex-cli users:delete doecorp/37fhsg'
        c.action do |args, options|
          NexClient::Commands::Users.destroy(args,options)
        end
      end

      run!
    end