1
0
mirror of https://github.com/rancher/types.git synced 2025-09-01 21:32:10 +00:00

Update vendor

This commit is contained in:
Darren Shepherd
2018-02-09 13:46:32 -07:00
parent 0e56750e82
commit b4735f04db
77 changed files with 9551 additions and 13771 deletions

View File

@@ -32,11 +32,23 @@ type ClientOpts struct {
URL string
AccessKey string
SecretKey string
TokenKey string
Timeout time.Duration
HTTPClient *http.Client
CACerts string
}
func (c *ClientOpts) getAuthHeader() string {
if c.TokenKey != "" {
return "Bearer " + c.TokenKey
}
if c.AccessKey != "" && c.SecretKey != "" {
s := c.AccessKey + ":" + c.SecretKey
return "Basic " + base64.StdEncoding.EncodeToString([]byte(s))
}
return ""
}
type APIError struct {
StatusCode int
URL string
@@ -169,7 +181,7 @@ func NewAPIClient(opts *ClientOpts) (APIBaseClient, error) {
return result, err
}
req.SetBasicAuth(opts.AccessKey, opts.SecretKey)
req.Header.Add("Authorization", opts.getAuthHeader())
resp, err := client.Do(req)
if err != nil {
@@ -188,7 +200,7 @@ func NewAPIClient(opts *ClientOpts) (APIBaseClient, error) {
if schemasURLs != opts.URL {
req, err = http.NewRequest("GET", schemasURLs, nil)
req.SetBasicAuth(opts.AccessKey, opts.SecretKey)
req.Header.Add("Authorization", opts.getAuthHeader())
if err != nil {
return result, err
}
@@ -243,8 +255,7 @@ func (a *APIBaseClient) Websocket(url string, headers map[string][]string) (*web
}
if a.Opts != nil {
s := a.Opts.AccessKey + ":" + a.Opts.SecretKey
httpHeaders.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(s)))
httpHeaders.Add("Authorization", a.Opts.getAuthHeader())
}
return dialer.Dial(url, http.Header(httpHeaders))

View File

@@ -14,7 +14,7 @@ import (
)
func (a *APIOperations) setupRequest(req *http.Request) {
req.SetBasicAuth(a.Opts.AccessKey, a.Opts.SecretKey)
req.Header.Add("Authorization", a.Opts.getAuthHeader())
}
func (a *APIOperations) DoDelete(url string) error {

94
vendor/github.com/rancher/norman/httperror/error.go generated vendored Normal file
View File

@@ -0,0 +1,94 @@
package httperror
import (
"fmt"
)
var (
InvalidDateFormat = ErrorCode{"InvalidDateFormat", 422}
InvalidFormat = ErrorCode{"InvalidFormat", 422}
InvalidReference = ErrorCode{"InvalidReference", 422}
NotNullable = ErrorCode{"NotNullable", 422}
NotUnique = ErrorCode{"NotUnique", 422}
MinLimitExceeded = ErrorCode{"MinLimitExceeded", 422}
MaxLimitExceeded = ErrorCode{"MaxLimitExceeded", 422}
MinLengthExceeded = ErrorCode{"MinLengthExceeded", 422}
MaxLengthExceeded = ErrorCode{"MaxLengthExceeded", 422}
InvalidOption = ErrorCode{"InvalidOption", 422}
InvalidCharacters = ErrorCode{"InvalidCharacters", 422}
MissingRequired = ErrorCode{"MissingRequired", 422}
InvalidCSRFToken = ErrorCode{"InvalidCSRFToken", 422}
InvalidAction = ErrorCode{"InvalidAction", 422}
InvalidBodyContent = ErrorCode{"InvalidBodyContent", 422}
InvalidType = ErrorCode{"InvalidType", 422}
ActionNotAvailable = ErrorCode{"ActionNotAvailable", 404}
InvalidState = ErrorCode{"InvalidState", 422}
ServerError = ErrorCode{"ServerError", 500}
ClusterUnavailable = ErrorCode{"ClusterUnavailable", 503}
PermissionDenied = ErrorCode{"PermissionDenied", 403}
MethodNotAllowed = ErrorCode{"MethodNotAllow", 405}
NotFound = ErrorCode{"NotFound", 404}
)
type ErrorCode struct {
code string
Status int
}
func (e ErrorCode) String() string {
return fmt.Sprintf("%s %d", e.code, e.Status)
}
type APIError struct {
code ErrorCode
message string
Cause error
fieldName string
}
func NewAPIErrorLong(status int, code, message string) error {
return NewAPIError(ErrorCode{
code: code,
Status: status,
}, message)
}
func NewAPIError(code ErrorCode, message string) error {
return &APIError{
code: code,
message: message,
}
}
func NewFieldAPIError(code ErrorCode, fieldName, message string) error {
return &APIError{
code: code,
message: message,
fieldName: fieldName,
}
}
func WrapFieldAPIError(err error, code ErrorCode, fieldName, message string) error {
return &APIError{
Cause: err,
code: code,
message: message,
fieldName: fieldName,
}
}
func WrapAPIError(err error, code ErrorCode, message string) error {
return &APIError{
code: code,
message: message,
Cause: err,
}
}
func (a *APIError) Error() string {
if a.fieldName != "" {
return fmt.Sprintf("%s=%s: %s", a.fieldName, a.code, a.message)
}
return fmt.Sprintf("%s: %s", a.code, a.message)
}

36
vendor/github.com/rancher/norman/httperror/handler.go generated vendored Normal file
View File

@@ -0,0 +1,36 @@
package httperror
import (
"github.com/rancher/norman/types"
"github.com/sirupsen/logrus"
)
func ErrorHandler(request *types.APIContext, err error) {
var error *APIError
if apiError, ok := err.(*APIError); ok {
error = apiError
} else {
logrus.Errorf("Unknown error: %v", err)
error = &APIError{
code: ServerError,
message: err.Error(),
}
}
data := toError(error)
request.WriteResponse(error.code.Status, data)
}
func toError(apiError *APIError) map[string]interface{} {
e := map[string]interface{}{
"type": "/meta/schemas/error",
"status": apiError.code.Status,
"code": apiError.code.code,
"message": apiError.message,
}
if apiError.fieldName != "" {
e["fieldName"] = apiError.fieldName
}
return e
}

View File

@@ -59,7 +59,9 @@ func (o *objectLifecycleAdapter) sync(key string, obj runtime.Object) error {
copyObj := obj.DeepCopyObject()
newObj, err := o.lifecycle.Updated(copyObj)
o.update(metadata.GetName(), obj, newObj)
if newObj != nil {
o.update(metadata.GetName(), obj, newObj)
}
return err
}
@@ -82,7 +84,9 @@ func (o *objectLifecycleAdapter) finalize(metadata metav1.Object, obj runtime.Ob
copyObj := obj.DeepCopyObject()
if newObj, err := o.lifecycle.Finalize(copyObj); err != nil {
o.update(metadata.GetName(), obj, newObj)
if newObj != nil {
o.update(metadata.GetName(), obj, newObj)
}
return false, err
} else if newObj != nil {
copyObj = newObj

View File

@@ -0,0 +1,52 @@
package proxy
import (
"github.com/rancher/norman/httperror"
"github.com/rancher/norman/types"
"k8s.io/apimachinery/pkg/api/errors"
)
type errorStore struct {
types.Store
}
func (e *errorStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
data, err := e.Store.ByID(apiContext, schema, id)
return data, translateError(err)
}
func (e *errorStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) {
data, err := e.Store.List(apiContext, schema, opt)
return data, translateError(err)
}
func (e *errorStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) {
data, err := e.Store.Create(apiContext, schema, data)
return data, translateError(err)
}
func (e *errorStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) {
data, err := e.Store.Update(apiContext, schema, data, id)
return data, translateError(err)
}
func (e *errorStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
data, err := e.Store.Delete(apiContext, schema, id)
return data, translateError(err)
}
func (e *errorStore) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) {
data, err := e.Store.Watch(apiContext, schema, opt)
return data, translateError(err)
}
func translateError(err error) error {
if apiError, ok := err.(errors.APIStatus); ok {
status := apiError.Status()
return httperror.NewAPIErrorLong(int(status.Code), string(status.Reason), status.Message)
}
return err
}

View File

@@ -0,0 +1,415 @@
package proxy
import (
ejson "encoding/json"
"net/http"
"strings"
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
"github.com/rancher/norman/types/values"
"github.com/sirupsen/logrus"
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
restclientwatch "k8s.io/client-go/rest/watch"
)
var (
userAuthHeader = "Impersonate-User"
authHeaders = []string{
userAuthHeader,
"Impersonate-Group",
}
)
type ClientGetter interface {
Config(apiContext *types.APIContext, context types.StorageContext) (rest.Config, error)
UnversionedClient(apiContext *types.APIContext, context types.StorageContext) (rest.Interface, error)
APIExtClient(apiContext *types.APIContext, context types.StorageContext) (clientset.Interface, error)
}
type simpleClientGetter struct {
restConfig rest.Config
client rest.Interface
apiExtClient clientset.Interface
}
func NewClientGetterFromConfig(config rest.Config) (ClientGetter, error) {
dynamicConfig := config
if dynamicConfig.NegotiatedSerializer == nil {
configConfig := dynamic.ContentConfig()
dynamicConfig.NegotiatedSerializer = configConfig.NegotiatedSerializer
}
unversionedClient, err := rest.UnversionedRESTClientFor(&dynamicConfig)
if err != nil {
return nil, err
}
apiExtClient, err := clientset.NewForConfig(&dynamicConfig)
if err != nil {
return nil, err
}
return &simpleClientGetter{
restConfig: config,
client: unversionedClient,
apiExtClient: apiExtClient,
}, nil
}
func (s *simpleClientGetter) Config(apiContext *types.APIContext, context types.StorageContext) (rest.Config, error) {
return s.restConfig, nil
}
func (s *simpleClientGetter) UnversionedClient(apiContext *types.APIContext, context types.StorageContext) (rest.Interface, error) {
return s.client, nil
}
func (s *simpleClientGetter) APIExtClient(apiContext *types.APIContext, context types.StorageContext) (clientset.Interface, error) {
return s.apiExtClient, nil
}
type Store struct {
clientGetter ClientGetter
storageContext types.StorageContext
prefix []string
group string
version string
kind string
resourcePlural string
authContext map[string]string
}
func NewProxyStore(clientGetter ClientGetter, storageContext types.StorageContext,
prefix []string, group, version, kind, resourcePlural string) types.Store {
return &errorStore{
Store: &Store{
clientGetter: clientGetter,
storageContext: storageContext,
prefix: prefix,
group: group,
version: version,
kind: kind,
resourcePlural: resourcePlural,
authContext: map[string]string{
"apiGroup": group,
"resource": resourcePlural,
},
},
}
}
func NewRawProxyStore(clientGetter ClientGetter, storageContext types.StorageContext,
prefix []string, group, version, kind, resourcePlural string) *Store {
return &Store{
clientGetter: clientGetter,
storageContext: storageContext,
prefix: prefix,
group: group,
version: version,
kind: kind,
resourcePlural: resourcePlural,
authContext: map[string]string{
"apiGroup": group,
"resource": resourcePlural,
},
}
}
func (p *Store) getUser(apiContext *types.APIContext) string {
return apiContext.Request.Header.Get(userAuthHeader)
}
func (p *Store) doAuthed(apiContext *types.APIContext, request *rest.Request) rest.Result {
for _, header := range authHeaders {
request.SetHeader(header, apiContext.Request.Header[http.CanonicalHeaderKey(header)]...)
}
return request.Do()
}
func (p *Store) k8sClient(apiContext *types.APIContext) (rest.Interface, error) {
return p.clientGetter.UnversionedClient(apiContext, p.storageContext)
}
func (p *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
_, result, err := p.byID(apiContext, schema, id)
return result, err
}
func (p *Store) byID(apiContext *types.APIContext, schema *types.Schema, id string) (string, map[string]interface{}, error) {
namespace, id := splitID(id)
k8sClient, err := p.k8sClient(apiContext)
if err != nil {
return "", nil, err
}
req := p.common(namespace, k8sClient.Get()).
Name(id)
return p.singleResult(apiContext, schema, req)
}
func (p *Store) Context() types.StorageContext {
return p.storageContext
}
func (p *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) {
namespace := getNamespace(apiContext, opt)
k8sClient, err := p.k8sClient(apiContext)
if err != nil {
return nil, err
}
req := p.common(namespace, k8sClient.Get())
resultList := &unstructured.UnstructuredList{}
err = req.Do().Into(resultList)
if err != nil {
return nil, err
}
var result []map[string]interface{}
for _, obj := range resultList.Items {
result = append(result, p.fromInternal(schema, obj.Object))
}
return apiContext.AccessControl.FilterList(apiContext, result, p.authContext), nil
}
func (p *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) {
namespace := getNamespace(apiContext, opt)
k8sClient, err := p.k8sClient(apiContext)
if err != nil {
return nil, err
}
timeout := int64(60 * 60)
req := p.common(namespace, k8sClient.Get())
req.VersionedParams(&metav1.ListOptions{
Watch: true,
TimeoutSeconds: &timeout,
ResourceVersion: "0",
}, dynamic.VersionedParameterEncoderWithV1Fallback)
body, err := req.Stream()
if err != nil {
return nil, err
}
framer := json.Framer.NewFrameReader(body)
decoder := streaming.NewDecoder(framer, &unstructuredDecoder{})
watcher := watch.NewStreamWatcher(restclientwatch.NewDecoder(decoder, &unstructuredDecoder{}))
go func() {
<-apiContext.Request.Context().Done()
logrus.Debugf("stopping watcher for %s", schema.ID)
watcher.Stop()
}()
result := make(chan map[string]interface{})
go func() {
for event := range watcher.ResultChan() {
data := event.Object.(*unstructured.Unstructured)
p.fromInternal(schema, data.Object)
if event.Type == watch.Deleted && data.Object != nil {
data.Object[".removed"] = true
}
result <- apiContext.AccessControl.Filter(apiContext, data.Object, p.authContext)
}
logrus.Debugf("closing watcher for %s", schema.ID)
close(result)
}()
return result, nil
}
type unstructuredDecoder struct {
}
func (d *unstructuredDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
if into == nil {
into = &unstructured.Unstructured{}
}
return into, defaults, ejson.Unmarshal(data, &into)
}
func getNamespace(apiContext *types.APIContext, opt *types.QueryOptions) string {
if val, ok := apiContext.SubContext["namespaces"]; ok {
return convert.ToString(val)
}
for _, condition := range opt.Conditions {
if condition.Field == "namespaceId" && condition.Value != "" {
return condition.Value
}
}
return ""
}
func (p *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) {
namespace, _ := data["namespaceId"].(string)
p.toInternal(schema.Mapper, data)
values.PutValue(data, p.getUser(apiContext), "metadata", "annotations", "field.cattle.io/creatorId")
name, _ := values.GetValueN(data, "metadata", "name").(string)
if name == "" {
generated, _ := values.GetValueN(data, "metadata", "generateName").(string)
if generated == "" {
values.PutValue(data, strings.ToLower(schema.ID+"-"), "metadata", "generateName")
}
}
k8sClient, err := p.k8sClient(apiContext)
if err != nil {
return nil, err
}
req := p.common(namespace, k8sClient.Post()).
Body(&unstructured.Unstructured{
Object: data,
})
_, result, err := p.singleResult(apiContext, schema, req)
return result, err
}
func (p *Store) toInternal(mapper types.Mapper, data map[string]interface{}) {
if mapper != nil {
mapper.ToInternal(data)
}
if p.group == "" {
data["apiVersion"] = p.version
} else {
data["apiVersion"] = p.group + "/" + p.version
}
data["kind"] = p.kind
}
func (p *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) {
k8sClient, err := p.k8sClient(apiContext)
if err != nil {
return nil, err
}
namespace, id := splitID(id)
req := p.common(namespace, k8sClient.Get()).
Name(id)
resourceVersion, existing, err := p.singleResultRaw(apiContext, schema, req)
if err != nil {
return data, nil
}
p.toInternal(schema.Mapper, data)
existing = convert.APIUpdateMerge(existing, data, apiContext.Query.Get("_replace") == "true")
values.PutValue(existing, resourceVersion, "metadata", "resourceVersion")
values.PutValue(existing, namespace, "metadata", "namespace")
values.PutValue(existing, id, "metadata", "name")
req = p.common(namespace, k8sClient.Put()).
Body(&unstructured.Unstructured{
Object: existing,
}).
Name(id)
_, result, err := p.singleResult(apiContext, schema, req)
return result, err
}
func (p *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
k8sClient, err := p.k8sClient(apiContext)
if err != nil {
return nil, err
}
namespace, id := splitID(id)
prop := metav1.DeletePropagationForeground
req := p.common(namespace, k8sClient.Delete()).
Body(&metav1.DeleteOptions{
PropagationPolicy: &prop,
}).
Name(id)
err = p.doAuthed(apiContext, req).Error()
if err != nil {
return nil, err
}
obj, err := p.ByID(apiContext, schema, id)
if err != nil {
return nil, nil
}
return obj, nil
}
func (p *Store) singleResult(apiContext *types.APIContext, schema *types.Schema, req *rest.Request) (string, map[string]interface{}, error) {
version, data, err := p.singleResultRaw(apiContext, schema, req)
if err != nil {
return "", nil, err
}
p.fromInternal(schema, data)
return version, data, nil
}
func (p *Store) singleResultRaw(apiContext *types.APIContext, schema *types.Schema, req *rest.Request) (string, map[string]interface{}, error) {
result := &unstructured.Unstructured{}
err := p.doAuthed(apiContext, req).Into(result)
if err != nil {
return "", nil, err
}
return result.GetResourceVersion(), result.Object, nil
}
func splitID(id string) (string, string) {
namespace := ""
parts := strings.SplitN(id, ":", 2)
if len(parts) == 2 {
namespace = parts[0]
id = parts[1]
}
return namespace, id
}
func (p *Store) common(namespace string, req *rest.Request) *rest.Request {
prefix := append([]string{}, p.prefix...)
if p.group != "" {
prefix = append(prefix, p.group)
}
prefix = append(prefix, p.version)
req.Prefix(prefix...).
Resource(p.resourcePlural)
if namespace != "" {
req.Namespace(namespace)
}
return req
}
func (p *Store) fromInternal(schema *types.Schema, data map[string]interface{}) map[string]interface{} {
if schema.Mapper != nil {
schema.Mapper.FromInternal(data)
}
return data
}

View File

@@ -8,9 +8,7 @@ func NewMetadataMapper() types.Mapper {
return types.Mappers{
ChangeType{Field: "name", Type: "dnsLabel"},
Drop{Field: "generateName"},
//Move{From: "selfLink", To: "resourcePath"},
Drop{Field: "selfLink"},
//Drop{"ownerReferences"},
Move{From: "uid", To: "uuid"},
Drop{Field: "resourceVersion"},
Drop{Field: "generation"},
@@ -18,13 +16,12 @@ func NewMetadataMapper() types.Mapper {
Move{From: "deletionTimestamp", To: "removed"},
Drop{Field: "deletionGracePeriodSeconds"},
Drop{Field: "initializers"},
//Drop{"finalizers"},
Drop{Field: "clusterName"},
ReadOnly{Field: "*"},
Access{
Fields: map[string]string{
"name": "c",
"namespace": "cu",
"namespace": "c",
"labels": "cu",
"annotations": "cu",
},

View File

@@ -131,10 +131,6 @@ func (s *Schemas) MustCustomizeType(version *APIVersion, obj interface{}, f func
f(schema)
if schema.SubContext != "" {
s.schemasBySubContext[schema.SubContext] = schema
}
return s
}

View File

@@ -29,28 +29,26 @@ type BackReference struct {
type Schemas struct {
sync.Mutex
typeNames map[reflect.Type]string
schemasByPath map[string]map[string]*Schema
schemasBySubContext map[string]*Schema
mappers map[string]map[string][]Mapper
references map[string][]BackReference
embedded map[string]*Schema
DefaultMappers MappersFactory
DefaultPostMappers MappersFactory
versions []APIVersion
schemas []*Schema
AddHook SchemaHook
errors []error
typeNames map[reflect.Type]string
schemasByPath map[string]map[string]*Schema
mappers map[string]map[string][]Mapper
references map[string][]BackReference
embedded map[string]*Schema
DefaultMappers MappersFactory
DefaultPostMappers MappersFactory
versions []APIVersion
schemas []*Schema
AddHook SchemaHook
errors []error
}
func NewSchemas() *Schemas {
return &Schemas{
typeNames: map[reflect.Type]string{},
schemasByPath: map[string]map[string]*Schema{},
schemasBySubContext: map[string]*Schema{},
mappers: map[string]map[string][]Mapper{},
references: map[string][]BackReference{},
embedded: map[string]*Schema{},
typeNames: map[reflect.Type]string{},
schemasByPath: map[string]map[string]*Schema{},
mappers: map[string]map[string][]Mapper{},
references: map[string][]BackReference{},
embedded: map[string]*Schema{},
}
}
@@ -62,12 +60,6 @@ func (s *Schemas) Err() error {
return NewErrors(s.errors)
}
func (s *Schemas) SubContext(subContext string) *Schema {
s.Lock()
defer s.Unlock()
return s.schemasBySubContext[subContext]
}
func (s *Schemas) AddSchemas(schema *Schemas) *Schemas {
for _, schema := range schema.Schemas() {
s.AddSchema(*schema)
@@ -86,8 +78,6 @@ func (s *Schemas) doRemoveSchema(schema Schema) *Schemas {
s.removeReferences(&schema)
delete(s.schemasBySubContext, schema.SubContext)
if schema.Embed {
s.removeEmbed(&schema)
}
@@ -145,10 +135,6 @@ func (s *Schemas) doAddSchema(schema Schema) *Schemas {
}
}
if schema.SubContext != "" {
s.schemasBySubContext[schema.SubContext] = &schema
}
if schema.Embed {
s.embed(&schema)
}
@@ -343,6 +329,16 @@ func (s *Schemas) doSchema(version *APIVersion, name string, lock bool) *Schema
return nil
}
func (s *Schemas) SubContextVersionForSchema(schema *Schema) *APIVersion {
fullName := fmt.Sprintf("%s/schemas/%s", schema.Version.Path, schema.ID)
for _, version := range s.Versions() {
if version.SubContextSchema == fullName {
return &version
}
}
return nil
}
type multiErrors struct {
errors []error
}

View File

@@ -186,7 +186,12 @@ type URLBuilder interface {
ResourceLinkByID(schema *Schema, id string) string
}
type StorageContext string
var DefaultStorageContext StorageContext
type Store interface {
Context() StorageContext
ByID(apiContext *APIContext, schema *Schema, id string) (map[string]interface{}, error)
List(apiContext *APIContext, schema *Schema, opt *QueryOptions) ([]map[string]interface{}, error)
Create(apiContext *APIContext, schema *Schema, data map[string]interface{}) (map[string]interface{}, error)

View File

@@ -69,10 +69,11 @@ type Resource struct {
}
type APIVersion struct {
Group string `json:"group,omitempty"`
Version string `json:"version,omitempty"`
Path string `json:"path,omitempty"`
SubContexts map[string]bool `json:"subContext,omitempty"`
Group string `json:"group,omitempty"`
Version string `json:"version,omitempty"`
Path string `json:"path,omitempty"`
SubContext bool `json:"subContext,omitempty"`
SubContextSchema string `json:"filterField,omitempty"`
}
type Namespaced struct{}
@@ -90,7 +91,6 @@ type Schema struct {
PkgName string `json:"-"`
Type string `json:"type,omitempty"`
BaseType string `json:"baseType,omitempty"`
SubContext string `json:"-,omitempty"`
Links map[string]string `json:"links"`
Version APIVersion `json:"version"`
PluralName string `json:"pluralName,omitempty"`