Code Monkey home page Code Monkey logo

nomad-openapi's Introduction

HashiCorp Nomad logo

Deprecation Notice

After supporting this library for several releases and using it on internal tools, the Nomad Team has decided to end official support for this OpenAPI library in Nomad. Unfortunately, there has been a higher than anticipated cost to keeping it up to date.

If you are using or want to use an OpenAPI client in Nomad, we encourage you to fork this repository. You can refer to this section on how to contribute, or ask us for guidance in the Nomad Forums. We will be supporting this library until Nomad 1.7, and SDKs should continue to work on later versions of Nomad, though certain endpoints may not be fully supported. Golang users can also use the built-in Go client.

One day, we may resume support for OpenAPI (or something similar), but if we do weโ€™ll be using it in the Nomad repo itself and making sure we auto-generate more of the code necessary to keep this up to date.

Thank you to everybody from the community who contributed or used the library.

Overview

This repository contains the HashiCorp Nomad OpenAPI specification and related artifacts.

The OpenAPI specification defines a machine-readable schema for describing HTTP APIs. From an OpenAPI specification, clients and servers for your project can be generated in a number of programming languages.

Quick start

The latest version of the OpenAPI specification for the Version 1 Nomad HTTP API can be found in this repository at v1/openapi.yaml. This file is itself a generated file and should not be edited directly. You can use this file to generate a client for the Nomad HTTP API in the language of your choice.

Using the Go Client

To use the Go client add a reference to it in your go.mod with go get.

$ go get github.com/hashicorp/nomad-openapi

You can use it from your client applications like this.

package main

import (
	"fmt"
	"os"

	v1 "github.com/hashicorp/nomad-openapi/v1"
)

func main() {
	client, err := v1.NewClient()
	if err != nil {
		fmt.Println(err.Error())
	}

	jobName := "example"
	opts := v1.DefaultQueryOpts()

	job, meta, err := client.Jobs().GetJob(opts.Ctx(), jobName)
	if err != nil {
		os.Exit(1)
	}

	fmt.Println(*job.ID)
	fmt.Printf("%v", &meta)
}

Environmental Configuration

This client supports the following Nomad environment variables.

  • NOMAD_ADDR - Required to overide the default of http://127.0.0.1:4646.
  • NOMAD_TOKEN - Required with ACLs enabled. Can be overidden with QueryOpts or WriteOpts.
  • NOMAD_CACERT - Required with TLS enabled.
  • NOMAD_CLIENT_CERT - Required with TLS enabled.
  • NOMAD_CLIENT_KEY - Required with TLS enabled.
  • NOMAD_REGION - Required if you are calling a server in a region other than global as the NOMAD_CACERT SAN will follow the convention of server.<region>.nomad.

Code generation

The OpenAPI ecosystem has a number of existing code generators to choose from. This repository uses the OpenAPI Generator project to generate a test client in Golang that is then used to validate the generated specification.

To generate a ruby client using the OpenAPI Generator, you can use the following docker command from the root of this repository.

$ mkdir -p /tmp/nomad-openapi && docker run \
	--rm \
	-v "$PWD:/local" \
	-v "/tmp/nomad-openapi:/output" \
	openapitools/openapi-generator-cli:v5.2.0 generate -i /local/v1/openapi.yaml -g ruby -o /output/

Generating a client in a different language should be as straightforward as changing the -g argument in the command above to your language of choice. Check the OpenAPI Generators page for a full list of supported languages.

If you want to generate a client in a language not yet included in the clients directory and submit it for inclusion in this repo, review the Makefile at the root of this repository. Also review the config.yaml file in each client folder. You will need to create a similar file that is specific to your language. Reference the OpenAPI Generator documentation for more information on language specific configuration options.

This repository is currently experimental, and, as such, there is no guarantee of support at this time.

Community Guidelines

The HashiCorp community is a mixture of professionals, volunteers, students, and employees who collaborate to make HashiCorp tools better. Community members play a variety of roles, including mentor, teacher, or connector. If you would like to contribute to HashiCorp products, review our community guidelines which can be found online here.

Issues and Questions

If you have any issues or questions using this package, please raise a Github issue in this repository. Issues raised in the main Nomad repository will be redirected here.

Motivation

The OpenAPI specification is ideal if you are working in a greenfield scenario, and can write your specification first. This spec first approach is highly recommended and widely supported by many of the tool vendors and experts in the OpenAPI space.

However, this approach leaves brownfield projects with an existing API that either predates the OpenAPI specification, or for whatever reason was built with a code first approach, to their own devices in terms of generating a specification from existing code. The code found in the generator directory is one such device. It is highly, experimental, and subject to change.

Contributing

The /v1/openapi.yaml specification file is a generated file that should not be edited manually.

This video contains an overview of how to contribute endpoint configurations. The slide deck for this video can be found here.

The README file in the generator directory contains a detailed technical overview of the generator package as well as instructions on how to contribute to that package.

Client and API packages are not officially supported packages

The clients and v1 packages found in this repository are not officially supported packages.

Checklist for Updating For New Versions of Nomad

Updating to a new version of Nomad involves updating the spec generation code, and then running make to both create an updated v1/openapi.yml spec and generating the update clients.

  • Determine what changes will need to be made.
    • Find the go.mod file at the top of this repo to find the version of Nomad this repo is currently pinned to.
    • Go to your local checkout of Nomad OSS and find the differences in the api package between the version you intend to release and the version pinned in this repo. For example, to find the differences changes made between 1.3.5 and the 1.4.0-beta.1, run git diff v1.3.5..v1.4.0-beta.1 ./api.
  • In this repo, create a new branch update-nomad-vX.Y.Z
  • Update go.mod to the released version of Nomad.
  • Run go mod tidy.
  • Make a commit for updating the version of Nomad: git commit -am "update Nomad to vX.Y.Z"
  • Find the generator/*.go files that correspond to each API endpoint change you found above. For example, if the git diff found changes to api/acl.go you'll need to edit generator/acl.go.
  • Make the appropriate changes.
    • If you are adding new fields, edit the endpoints in place.
    • If you are adding new endpoints, start by copying this snippet: ./snippets/generator-endpoint.txt. Write the new endpoint by hand in the generator snippet. Refer to the slideshow above.
  • Make a commit with the spec generator update: git commit -am "update spec generator"
  • Run make v1 to update all the clients with that spec. Note: You will need Docker installed and running to update the clients.
  • Make a commit with all the client updates: git commit -am "update all clients"
  • Open a PR in this repo, targeting the main branch.

nomad-openapi's People

Contributors

angrycub avatar bndbsh avatar dependabot[bot] avatar derekstrickland avatar hashicorp-copywrite[bot] avatar jonasvinther avatar jrasell avatar lgfa29 avatar mikenomitch avatar nathancoleman avatar neutrollized avatar tgross 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  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

nomad-openapi's Issues

Missing nomad/v1/allocation/<id> endpoint

Hello,

from what I can see there exists no such endpoint nomad/v1/allocation/<id> in the openapi spec.

On my running instance (v1.2.3) I found the endpoint and it seems to return additional information.

The only way to get my required information was to perform v1/allocations?resources=true&task_states=true which produces way more content than necessary and requires additional filtering on the allocation id of interest.

Is there any chance that this endpoint will make it in the openapi spec?

Thanks!

feature: Add event stream related endpoints

Add support for the Event Stream. The current very rough thinking is to

  • Create an AsyncAPI specification
  • Devise a way to serve the Event Stream over websockets rather than long polling
  • Generate Websocket based clients from the specification

[rust] No pagination support on paginated requests

Functions such as nomad_client::apis::jobs_api::get_job_allocations, which access APIs that use X-Nomad-Nexttoken headers to express pagination, do not actually expose that header to the caller, preventing them from retrieving anything beyond the first page of results.

Python pip install `git+https://github.com/.../python/v1.git` not working

Hi,

maybe I'm overlooking something but the pip install as mentioned in the readme doesn't work me

~/temp/foo via ๐Ÿ v3.9.12 (foovenv)
โฏ pip install git+https://github.com/hashicorp/nomad-openapi/clients/python/v1.git
Collecting git+https://github.com/hashicorp/nomad-openapi/clients/python/v1.git
  Cloning https://github.com/hashicorp/nomad-openapi/clients/python/v1.git to /private/var/folders/zt/4d___54j41q5xhgw80pcmtyh0000gn/T/pip-req-build-clmb4zx8
  Running command git clone --filter=blob:none --quiet https://github.com/hashicorp/nomad-openapi/clients/python/v1.git /private/var/folders/zt/4d___54j41q5xhgw80pcmtyh0000gn/T/pip-req-build-clmb4zx8
  remote: Not Found
  fatal: Repository 'https://github.com/hashicorp/nomad-openapi/clients/python/v1.git/' not found
  error: subprocess-exited-with-error

  ร— git clone --filter=blob:none --quiet https://github.com/hashicorp/nomad-openapi/clients/python/v1.git /private/var/folders/zt/4d___54j41q5xhgw80pcmtyh0000gn/T/pip-req-build-clmb4zx8 did not run successfully.
  โ”‚ exit code: 128
  โ•ฐโ”€> See above for output.

Any suggestions?

array and object nullable is not handled correctly, at least for python.

In the openapi spec, when the type is array, the generated python validation code will complain when the value is null, which the nomad restful API does return. For example, if I call:

    configuration = nomad_client.Configuration(host="http://127.0.01:4646/v1")
    api_client = nomad_client.ApiClient(configuration)
    api_instance = JobsApi(api_client)
    job_name = HELLO_WORLD_JOB_NAME
    job_status = api_instance.get_job(job_name)
    print(job_status)

the get_job call should return a job, but a number of fields such as constraints are returned null, but it is defined as array type in the openapi spec. The same with object type. The openapi solution seems to be adding nullable: true to these fields, but there are a lot of them. Not sure what is the best solution to automatically fix this.

chore: rename JobName parameter

The jobName parameter in generator/v1api.go is erroneously named due to a similar available naming mistake in Nomad itself. This parameter should be renamed jobID to more accurately express what data is represented.

feature: add ping/connectivity check to API client

When instantiating a new client for use, it would be useful to have a simple ping/connectivity check that can be called before proceeding. This would help avoid situations where a lot of processing work is performed, to ultimately make a call with the client which will fail. I believe it will also improve the UX.

GitHub Actions - deprecated warnings found - action required!

Workflow Name: Go Tests
Branch: main
Run URL: https://github.com/hashicorp/nomad-openapi/actions/runs/4166903825

save-state deprecation warnings: 0
set-output deprecation warnings: 0
node12 deprecation warnings: 1

Please review these deprecation warnings as soon as possible and merge in the necessary updates.

GitHub will be removing support for these commands and plan to fully disable them on 31st May 2023. At this time, any workflow that still utilizes these commands will fail. See https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/.

GitHub have not finalized a date for deprecating node12 yet but have indicated that this will be summer 2023. So it is advised to switch to node16 asap. See https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/.

If you need any help, please reach out to us in #team-rel-eng.

enhancement: Support new QueryOpts & Evaluations filter settings

Once this PR lands, Evaluations will be the first API to support pagination and filtering options.

We'll need to:

  • Update the QueryOpts struct to support LastToken and deprecate NextToken.
  • Update the setQueryOpts framework method and associated tests to manage the new parameter and warn on use of the deprecated parameter (possibly a new X-Deprecation-Warning header or something similar - need to design)
  • Update the Evaluations generator code to include new supported query parameters
  • Update the set of default query options in the generator code
  • Regenerate clients

client: does not support basic auth in NOMAD_ADDR env var

Issue content copied from hashicorp/nomad-pack#153

Using username and password included in NOMAD_ADDR:

$ export NOMAD_ADDR=https://user:[email protected]/
$ nomad-pack run hello_world
! Failed To Parse Job Specification

        Error:   401 Unauthorized
        Type:    client.GenericOpenAPIError
        Context:
                 - Template Name: hello_world/templates/hello_world.nomad.tpl
                 - Registry Name: default
                 - Pack Name: hello_world
                 - Pack Ref: latest
                 - Deployment Name: hello_world@latest
$ nomad status
ID           Type     Priority  Status   Submit Date
hello_world  service  50        running  2021-10-24T13:04:06+02:00
traefik      service  50        running  2021-07-14T20:36:18+02:00

As you can see, nomad supports this way of authorization but nomad-pack doesn't

Note: details in NOMAD_ADDR were redacted due to security reasons

Incorrect validations for eg. CreateIndex, JobModifyIndex, ModifyIndex

As an example the JobListStub is defined in the openapi.yml as:

JobListStub:
      properties:
        CreateIndex:
          maximum: 1.8446744073709552e+19
          minimum: 0
          type: integer

Which seems to generate the golang code without further validations:

// JobListStub struct for JobListStub
type JobListStub struct {
	CreateIndex *int32 `json:"CreateIndex,omitempty"`
	...
}

But for ruby/python validations are added:

    validations = {
        ('create_index',): {
            'inclusive_maximum': 384,
            'inclusive_minimum': 0,
        },
         ...
    }
    # Check to see if the all the properties in the model are valid
    # @return true if the model is valid
    def valid?
      return false if !@create_index.nil? && @create_index > 384
      return false if !@create_index.nil? && @create_index < 0
      return false if !@job_modify_index.nil? && @job_modify_index > 384
      return false if !@job_modify_index.nil? && @job_modify_index < 0
      return false if !@modify_index.nil? && @modify_index > 384
      return false if !@modify_index.nil? && @modify_index < 0
      true
    end

ruby/v1 client seems to be python client

The ruby client seems to be a python client due to incorrect config file.
The current file states:

# File is used by the openapi-generator cli to generate a javascript client.
generatorName: python
gitUserId: hashicorp
gitRepoId: nomad-openapi/clients/ruby/v1
inputSpec: /local/v1/openapi.yaml
outputDir: /local/clients/ruby/v1
moduleName: NomadClient
packageVersion: 1.1.4
gemLicense: MPL 2.0

But I guess it should be:

# File is used by the openapi-generator cli to generate a ruby client.
generatorName: ruby <---
gitUserId: hashicorp
gitRepoId: nomad-openapi/clients/ruby/v1
inputSpec: /local/v1/openapi.yaml
outputDir: /local/clients/ruby/v1
moduleName: NomadClient
packageVersion: 1.1.4
gemLicense: MPL 2.0

A bit offtopic:

I am wondering what is the benefit of having all the clients generated in this repository? I think it would make more sense to either publish the generated clients to whatever package manager the language uses or to only keep the configuration files and document the command to generate any of the clients:

docker run --rm -v "$PWD:/local" openapitools/openapi-generator-cli:v5.2.0 batch --clean path/to/config.yaml

enhancement: Add put support to generator

In an attempt to standardize on POST, the generator did not support PUT configuration for endpoints. Community contributor @Neutrollized ran into some endpoints that only accept PUT. We need to update the generator to all PUT configuration.

chore: Add new helper method to handle responses without `WriteMeta` or `QueryMeta`

The Nomad OperatorAutopilotConfiguration handler supports PUT operations, and accepts WriteOpts parameters, but it does not set the index or any other WriteMeta values. OperatorServerHealth has the same issue but for GET.

There aren't helpers in the api.go file yet that handle a responses with this shape. We need to add them so that the client WriteOpts or QueryOpts will be set. Currently, the workaround is to use ExecRequest which works for unit tests and simple scenarios, but silently ignore any WriteOpts or QueryOpts set by callers.

question: Remove QueryOptions and WriteOptions embedded structs from models

##Problem

  • Currently, the API exposes the RPC QueryOptions/WriteOptions on input/output structs returned from the primary Nomad API package.
  • This is confusing as a user because all of those options are also accepted as parameters (query or header).
  • It would be less confusing to users if the generated request/response models excluded those structs and could rely solely on the parameters.
  • Currently, the generated models have setters for the embedded struct fields, but the framework ignores them and instead consumes the passed parameters
  • Uninitiated contributors might easily make the mistake of bypassing the parameter parsing methodology if they rely on IntelliSense discovery rather than looking at existing implementations.
  • Inclusion of these embedded structs bloats the generated models, the payload size, and the generated YAML.
  • I'd like to remove these embedded structs from the request/response models, but I am unsure if it is safe to do so.
  • Generally, the handler code maps the input parameters to the RPC structs before making RPC calls, but not having been through all the handlers yet, I am unclear if this is always guaranteed.

@schmichael @jrasell Can one of you weigh in on whether this will be safe to do, or point me in the direction of the best person to ask?

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.