Merge pull request #150 from gabriel-samfira/add-controller-info

Add controller info
This commit is contained in:
Gabriel 2023-08-13 02:03:31 +03:00 committed by GitHub
commit e2b617e12e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 518 additions and 0 deletions

View file

@ -377,3 +377,24 @@ func (a *APIController) ListAllJobs(w http.ResponseWriter, r *http.Request) {
log.Printf("failed to encode response: %q", err)
}
}
// swagger:route GET /controller-info controllerInfo ControllerInfo
//
// Get controller info.
//
// Responses:
// 200: ControllerInfo
// 409: APIErrorResponse
func (a *APIController) ControllerInfoHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
info, err := a.r.GetControllerInfo(ctx)
if err != nil {
handleError(w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(info); err != nil {
log.Printf("failed to encode response: %q", err)
}
}

View file

@ -285,6 +285,10 @@ func NewAPIRouter(han *controllers.APIController, logWriter io.Writer, authMiddl
apiRouter.Handle("/providers/", http.HandlerFunc(han.ListProviders)).Methods("GET", "OPTIONS")
apiRouter.Handle("/providers", http.HandlerFunc(han.ListProviders)).Methods("GET", "OPTIONS")
// Controller info
apiRouter.Handle("/controller-info/", http.HandlerFunc(han.ControllerInfoHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/controller-info", http.HandlerFunc(han.ControllerInfoHandler)).Methods("GET", "OPTIONS")
// Websocket log writer
apiRouter.Handle("/{ws:ws\\/?}", http.HandlerFunc(han.WSHandler)).Methods("GET")
return router

View file

@ -8,6 +8,13 @@ definitions:
import:
package: github.com/cloudbase/garm/params
alias: garm_params
ControllerInfo:
type: object
x-go-type:
type: ControllerInfo
import:
package: github.com/cloudbase/garm/params
alias: garm_params
NewUserParams:
type: object
x-go-type:

View file

@ -9,6 +9,13 @@ definitions:
alias: apiserver_params
package: github.com/cloudbase/garm/apiserver/params
type: APIErrorResponse
ControllerInfo:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: ControllerInfo
CreateEnterpriseParams:
type: object
x-go-type:
@ -239,6 +246,21 @@ paths:
summary: Logs in a user and returns a JWT token.
tags:
- login
/controller-info:
get:
operationId: ControllerInfo
responses:
"200":
description: ControllerInfo
schema:
$ref: '#/definitions/ControllerInfo'
"409":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Get controller info.
tags:
- controllerInfo
/credentials:
get:
operationId: ListCredentials

View file

@ -0,0 +1,80 @@
// Code generated by go-swagger; DO NOT EDIT.
package controller_info
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
)
// New creates a new controller info API client.
func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService {
return &Client{transport: transport, formats: formats}
}
/*
Client for controller info API
*/
type Client struct {
transport runtime.ClientTransport
formats strfmt.Registry
}
// ClientOption is the option for Client methods
type ClientOption func(*runtime.ClientOperation)
// ClientService is the interface for Client methods
type ClientService interface {
ControllerInfo(params *ControllerInfoParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ControllerInfoOK, error)
SetTransport(transport runtime.ClientTransport)
}
/*
ControllerInfo gets controller info
*/
func (a *Client) ControllerInfo(params *ControllerInfoParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ControllerInfoOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewControllerInfoParams()
}
op := &runtime.ClientOperation{
ID: "ControllerInfo",
Method: "GET",
PathPattern: "/controller-info",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &ControllerInfoReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*ControllerInfoOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for ControllerInfo: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
// SetTransport changes the transport on the client
func (a *Client) SetTransport(transport runtime.ClientTransport) {
a.transport = transport
}

View file

@ -0,0 +1,128 @@
// Code generated by go-swagger; DO NOT EDIT.
package controller_info
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewControllerInfoParams creates a new ControllerInfoParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewControllerInfoParams() *ControllerInfoParams {
return &ControllerInfoParams{
timeout: cr.DefaultTimeout,
}
}
// NewControllerInfoParamsWithTimeout creates a new ControllerInfoParams object
// with the ability to set a timeout on a request.
func NewControllerInfoParamsWithTimeout(timeout time.Duration) *ControllerInfoParams {
return &ControllerInfoParams{
timeout: timeout,
}
}
// NewControllerInfoParamsWithContext creates a new ControllerInfoParams object
// with the ability to set a context for a request.
func NewControllerInfoParamsWithContext(ctx context.Context) *ControllerInfoParams {
return &ControllerInfoParams{
Context: ctx,
}
}
// NewControllerInfoParamsWithHTTPClient creates a new ControllerInfoParams object
// with the ability to set a custom HTTPClient for a request.
func NewControllerInfoParamsWithHTTPClient(client *http.Client) *ControllerInfoParams {
return &ControllerInfoParams{
HTTPClient: client,
}
}
/*
ControllerInfoParams contains all the parameters to send to the API endpoint
for the controller info operation.
Typically these are written to a http.Request.
*/
type ControllerInfoParams struct {
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the controller info params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ControllerInfoParams) WithDefaults() *ControllerInfoParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the controller info params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ControllerInfoParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the controller info params
func (o *ControllerInfoParams) WithTimeout(timeout time.Duration) *ControllerInfoParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the controller info params
func (o *ControllerInfoParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the controller info params
func (o *ControllerInfoParams) WithContext(ctx context.Context) *ControllerInfoParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the controller info params
func (o *ControllerInfoParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the controller info params
func (o *ControllerInfoParams) WithHTTPClient(client *http.Client) *ControllerInfoParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the controller info params
func (o *ControllerInfoParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WriteToRequest writes these params to a swagger request
func (o *ControllerInfoParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,174 @@
// Code generated by go-swagger; DO NOT EDIT.
package controller_info
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// ControllerInfoReader is a Reader for the ControllerInfo structure.
type ControllerInfoReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *ControllerInfoReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewControllerInfoOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 409:
result := NewControllerInfoConflict()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[GET /controller-info] ControllerInfo", response, response.Code())
}
}
// NewControllerInfoOK creates a ControllerInfoOK with default headers values
func NewControllerInfoOK() *ControllerInfoOK {
return &ControllerInfoOK{}
}
/*
ControllerInfoOK describes a response with status code 200, with default header values.
ControllerInfo
*/
type ControllerInfoOK struct {
Payload garm_params.ControllerInfo
}
// IsSuccess returns true when this controller info o k response has a 2xx status code
func (o *ControllerInfoOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this controller info o k response has a 3xx status code
func (o *ControllerInfoOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this controller info o k response has a 4xx status code
func (o *ControllerInfoOK) IsClientError() bool {
return false
}
// IsServerError returns true when this controller info o k response has a 5xx status code
func (o *ControllerInfoOK) IsServerError() bool {
return false
}
// IsCode returns true when this controller info o k response a status code equal to that given
func (o *ControllerInfoOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the controller info o k response
func (o *ControllerInfoOK) Code() int {
return 200
}
func (o *ControllerInfoOK) Error() string {
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoOK %+v", 200, o.Payload)
}
func (o *ControllerInfoOK) String() string {
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoOK %+v", 200, o.Payload)
}
func (o *ControllerInfoOK) GetPayload() garm_params.ControllerInfo {
return o.Payload
}
func (o *ControllerInfoOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewControllerInfoConflict creates a ControllerInfoConflict with default headers values
func NewControllerInfoConflict() *ControllerInfoConflict {
return &ControllerInfoConflict{}
}
/*
ControllerInfoConflict describes a response with status code 409, with default header values.
APIErrorResponse
*/
type ControllerInfoConflict struct {
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this controller info conflict response has a 2xx status code
func (o *ControllerInfoConflict) IsSuccess() bool {
return false
}
// IsRedirect returns true when this controller info conflict response has a 3xx status code
func (o *ControllerInfoConflict) IsRedirect() bool {
return false
}
// IsClientError returns true when this controller info conflict response has a 4xx status code
func (o *ControllerInfoConflict) IsClientError() bool {
return true
}
// IsServerError returns true when this controller info conflict response has a 5xx status code
func (o *ControllerInfoConflict) IsServerError() bool {
return false
}
// IsCode returns true when this controller info conflict response a status code equal to that given
func (o *ControllerInfoConflict) IsCode(code int) bool {
return code == 409
}
// Code gets the status code for the controller info conflict response
func (o *ControllerInfoConflict) Code() int {
return 409
}
func (o *ControllerInfoConflict) Error() string {
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoConflict %+v", 409, o.Payload)
}
func (o *ControllerInfoConflict) String() string {
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoConflict %+v", 409, o.Payload)
}
func (o *ControllerInfoConflict) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *ControllerInfoConflict) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -10,6 +10,7 @@ import (
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/cloudbase/garm/client/controller_info"
"github.com/cloudbase/garm/client/credentials"
"github.com/cloudbase/garm/client/enterprises"
"github.com/cloudbase/garm/client/first_run"
@ -65,6 +66,7 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) *GarmAPI {
cli := new(GarmAPI)
cli.Transport = transport
cli.ControllerInfo = controller_info.New(transport, formats)
cli.Credentials = credentials.New(transport, formats)
cli.Enterprises = enterprises.New(transport, formats)
cli.FirstRun = first_run.New(transport, formats)
@ -120,6 +122,8 @@ func (cfg *TransportConfig) WithSchemes(schemes []string) *TransportConfig {
// GarmAPI is a client for garm API
type GarmAPI struct {
ControllerInfo controller_info.ClientService
Credentials credentials.ClientService
Enterprises enterprises.ClientService
@ -148,6 +152,7 @@ type GarmAPI struct {
// SetTransport changes the transport on the client and all its subresources
func (c *GarmAPI) SetTransport(transport runtime.ClientTransport) {
c.Transport = transport
c.ControllerInfo.SetTransport(transport)
c.Credentials.SetTransport(transport)
c.Enterprises.SetTransport(transport)
c.FirstRun.SetTransport(transport)

View file

@ -0,0 +1,73 @@
// Copyright 2023 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package cmd
import (
"fmt"
apiClientControllerInfo "github.com/cloudbase/garm/client/controller_info"
"github.com/cloudbase/garm/params"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
)
var infoCmd = &cobra.Command{
Use: "controller-info",
SilenceUsage: true,
Short: "Information about controller",
Long: `Query information about the current controller.`,
Run: nil,
}
var infoShowCmd = &cobra.Command{
Use: "show",
Short: "Show information",
Long: `Show information about the current controller.`,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
if needsInit {
return errNeedsInitError
}
showInfo := apiClientControllerInfo.NewControllerInfoParams()
response, err := apiCli.ControllerInfo.ControllerInfo(showInfo, authToken)
if err != nil {
return err
}
formatInfo(response.Payload)
return nil
},
}
func formatInfo(info params.ControllerInfo) {
t := table.NewWriter()
header := table.Row{"Field", "Value"}
t.AppendHeader(header)
t.AppendRow(table.Row{"Controller ID", info.ControllerID})
t.AppendRow(table.Row{"Hostname", info.Hostname})
t.AppendRow(table.Row{"Metadata URL", info.MetadataURL})
t.AppendRow(table.Row{"Callback URL", info.CallbackURL})
fmt.Println(t.Render())
}
func init() {
infoCmd.AddCommand(
infoShowCmd,
)
rootCmd.AddCommand(infoCmd)
}

View file

@ -381,6 +381,8 @@ type JWTResponse struct {
type ControllerInfo struct {
ControllerID uuid.UUID `json:"controller_id"`
Hostname string `json:"hostname"`
MetadataURL string `json:"metadata_url"`
CallbackURL string `json:"callback_url"`
}
type GithubCredentials struct {

View file

@ -379,6 +379,8 @@ func (r *Runner) GetControllerInfo(ctx context.Context) (params.ControllerInfo,
return params.ControllerInfo{
ControllerID: r.controllerID,
Hostname: hostname,
MetadataURL: r.config.Default.MetadataURL,
CallbackURL: r.config.Default.CallbackURL,
}, nil
}