-
Notifications
You must be signed in to change notification settings - Fork 225
Add service metadata configuration file #126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
bc244b1
3fe7227
94b8b7b
312504d
ecd2144
21380e1
1dad7ad
f5c9d83
5f5a820
7967740
0e4c103
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"). You may | ||
| // not use this file except in compliance with the License. A copy of the | ||
| // License is located at | ||
| // | ||
| // http://aws.amazon.com/apache2.0/ | ||
| // | ||
| // or in the "license" file accompanying this file. This file 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 metadata | ||
|
|
||
| import ( | ||
| "errors" | ||
| "io/ioutil" | ||
|
|
||
| "github.com/ghodss/yaml" | ||
| ) | ||
|
|
||
| var ( | ||
| ErrNoServiceMetadataFile = errors.New("expected metadata file path, none provided") | ||
| ErrNoAvailableVersions = errors.New("service metadata contains no available versions") | ||
| ) | ||
|
|
||
| // ServiceMetadata consists of information about the service and relative links as well | ||
| // as a list of supported/deprecated versions | ||
| type ServiceMetadata struct { | ||
| Service ServiceDetails `json:"service"` | ||
| // A list of all generated API versions of the service | ||
| APIVersions []ServiceVersion `json:"api_versions"` | ||
| } | ||
|
|
||
| // ServiceDetails contains string identifiers and relevant links for the | ||
| // service | ||
| type ServiceDetails struct { | ||
| // The full display name for the service. eg. Amazon Elastic Kubernetes | ||
| // Service | ||
| FullName string `json:"full_name"` | ||
| // The short name (abbreviation) for the service. eg. S3 | ||
| ShortName string `json:"short_name"` | ||
| // The URL of the service's homepage | ||
| Link string `json:"link"` | ||
| // The URL of the service's main documentation/user guide | ||
| Documentation string `json:"documentation"` | ||
| } | ||
|
|
||
| // ServiceVersion describes the status of all existing version of the controller | ||
| type ServiceVersion struct { | ||
| APIVersion string `json:"api_version"` | ||
| Status APIStatus `json:"status"` | ||
| } | ||
|
|
||
| func (m *ServiceMetadata) GetLatestAPIVersion() (string, error) { | ||
| availableVersions := m.GetAvailableAPIVersions() | ||
|
|
||
| if len(availableVersions) == 0 { | ||
| return "", ErrNoAvailableVersions | ||
| } | ||
|
|
||
| return availableVersions[len(availableVersions)-1], nil | ||
| } | ||
|
|
||
| func (m *ServiceMetadata) GetDeprecatedAPIVersions() []string { | ||
| return m.getVersionsByStatus(APIStatusDeprecated) | ||
| } | ||
|
|
||
| func (m *ServiceMetadata) GetRemovedAPIVersions() []string { | ||
| return m.getVersionsByStatus(APIStatusRemoved) | ||
| } | ||
|
|
||
| func (m *ServiceMetadata) GetAvailableAPIVersions() []string { | ||
| return m.getVersionsByStatus(APIStatusAvailable) | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. half nit:please add godoc comment, at least for the exported functions |
||
|
|
||
| func (m *ServiceMetadata) getVersionsByStatus(status APIStatus) []string { | ||
| if len(m.APIVersions) == 0 { | ||
| return []string{} | ||
| } | ||
|
|
||
| versions := []string{} | ||
| for _, v := range m.APIVersions { | ||
| if v.Status == status { | ||
| versions = append(versions, v.APIVersion) | ||
| } | ||
| } | ||
| return versions | ||
| } | ||
|
|
||
| // NewServiceMetadata returns a new Metadata object given a supplied | ||
| // path to a metadata file | ||
| func NewServiceMetadata( | ||
| metadataPath string, | ||
| ) (ServiceMetadata, error) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: you can return a |
||
| if metadataPath == "" { | ||
| return ServiceMetadata{}, ErrNoServiceMetadataFile | ||
| } | ||
| content, err := ioutil.ReadFile(metadataPath) | ||
| if err != nil { | ||
| return ServiceMetadata{}, err | ||
| } | ||
| gc := ServiceMetadata{} | ||
| if err = yaml.Unmarshal(content, &gc); err != nil { | ||
| return ServiceMetadata{}, err | ||
| } | ||
| return gc, nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ import ( | |
| "gopkg.in/src-d/go-git.v4" | ||
|
|
||
| ackgenconfig "github.com/aws-controllers-k8s/code-generator/pkg/generate/config" | ||
| ackmetadata "github.com/aws-controllers-k8s/code-generator/pkg/metadata" | ||
| ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model" | ||
| "github.com/aws-controllers-k8s/code-generator/pkg/util" | ||
| ) | ||
|
|
@@ -35,31 +36,36 @@ var ( | |
| // of each non-deprecated version with their correspending ackmodel.Model | ||
| // and APIInfos. | ||
| type APIVersionManager struct { | ||
| gitRepo *git.Repository | ||
| gitRepo *git.Repository | ||
| metadata ackmetadata.ServiceMetadata | ||
|
|
||
| hubVersion string | ||
| spokeVersions []string | ||
|
|
||
| deprecatedVersions []string | ||
| removedVersions []string | ||
|
|
||
| apiInfos map[string]APIInfo | ||
| apiInfos map[string]ackmetadata.APIInfo | ||
| models map[string]*ackmodel.Model | ||
| } | ||
|
|
||
| // NewAPIVersionManager initialises and returns a new APIVersionManager. | ||
| func NewAPIVersionManager( | ||
| sdkCacheDir string, | ||
| metadataPath string, | ||
| serviceAlias string, | ||
| hubVersion string, | ||
| apisInfo map[string]APIInfo, | ||
| apisInfo map[string]ackmetadata.APIInfo, | ||
| defaultConfig ackgenconfig.Config, | ||
| ) (*APIVersionManager, error) { | ||
| if len(apisInfo) == 0 { | ||
| return nil, fmt.Errorf("empty apisInfo") | ||
| } | ||
|
|
||
| spokeVersions := make([]string, 0, len(apisInfo)-1) | ||
| metadata, err := ackmetadata.NewServiceMetadata(metadataPath) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| spokeVersions := []string{} | ||
|
|
||
| gitRepo, err := util.LoadRepository(sdkCacheDir) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("cannot read sdk git repository: %v", err) | ||
|
|
@@ -68,11 +74,19 @@ func NewAPIVersionManager( | |
| SDKAPIHelper := ackmodel.NewSDKHelper(sdkCacheDir) | ||
|
|
||
| // create model for each non-deprecated api version | ||
| models := make(map[string]*ackmodel.Model, len(apisInfo)) | ||
| for apiVersion, apiInfo := range apisInfo { | ||
| // TODO(a-hilaly) filter deprecated and removed api versions | ||
| if apiVersion != hubVersion { | ||
| spokeVersions = append(spokeVersions, apiVersion) | ||
| models := map[string]*ackmodel.Model{} | ||
| for _, version := range metadata.APIVersions { | ||
| if version.Status == ackmetadata.APIStatusDeprecated || version.Status == ackmetadata.APIStatusRemoved { | ||
| continue | ||
| } | ||
|
|
||
| if version.APIVersion != hubVersion { | ||
| spokeVersions = append(spokeVersions, version.APIVersion) | ||
| } | ||
|
|
||
| apiInfo, ok := apisInfo[version.APIVersion] | ||
| if !ok { | ||
| return nil, fmt.Errorf("could not find API info for API version %s", version.APIVersion) | ||
| } | ||
|
|
||
| err = SDKAPIHelper.WithSDKVersion(apiInfo.AWSSDKVersion) | ||
|
|
@@ -87,25 +101,26 @@ func NewAPIVersionManager( | |
|
|
||
| i, err := ackmodel.New( | ||
| SDKAPI, | ||
| apiVersion, | ||
| version.APIVersion, | ||
| apiInfo.GeneratorConfigPath, | ||
| defaultConfig, | ||
| ) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("cannot create model for API version %s: %v", apiVersion, err) | ||
| return nil, fmt.Errorf("cannot create model for API version %s: %v", version.APIVersion, err) | ||
| } | ||
| models[apiVersion] = i | ||
| models[version.APIVersion] = i | ||
| } | ||
|
|
||
| sort.Strings(spokeVersions) | ||
| model := &APIVersionManager{ | ||
| gitRepo: gitRepo, | ||
| metadata: metadata, | ||
| hubVersion: hubVersion, | ||
| spokeVersions: spokeVersions, | ||
| apiInfos: apisInfo, | ||
| models: models, | ||
| } | ||
| // TODO(hilalymh): Audit deprecated and removed versions | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm still going to send a PR for API versions examination. Mainly to verify that service controller maintainers didn't violate one of the deprecation/removal policies. |
||
|
|
||
| return model, nil | ||
| } | ||
|
|
||
|
|
@@ -140,10 +155,10 @@ func (m *APIVersionManager) VerifyAPIVersions(apiVersions ...string) error { | |
| if !ok { | ||
| return fmt.Errorf("%v: %s", ErrAPIVersionNotFound, apiVersion) | ||
| } | ||
| if apiInfo.Status == APIStatusDeprecated { | ||
| if apiInfo.Status == ackmetadata.APIStatusDeprecated { | ||
| return fmt.Errorf("%v: %s", ErrAPIVersionDeprecated, apiVersion) | ||
| } | ||
| if apiInfo.Status == APIStatusRemoved { | ||
| if apiInfo.Status == ackmetadata.APIStatusRemoved { | ||
| return fmt.Errorf("%v: %s", ErrAPIVersionRemoved, apiVersion) | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| service: | ||
| full_name: Amazon Test Service | ||
| short_name: ATS | ||
| link: https://example.com/ | ||
| documentation: https://docs.example.com/ | ||
| versions: | ||
| - api_version: v1alpha1 | ||
| status: development | ||
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also add a boolean field called
IsHub, to be able to override the hub version. In most of the cases the latestAvailableversion is the hub (prefered storage version). However, according to k8s deprecation policy sometimes the hub can be different from the latest version.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am quite averse to the idea of the hub being anything other than the latest generated version - we rely on it being the latest for the common runtime elements to match.