Skip to content

Commit 75e6c92

Browse files
Add service metadata configuration file (#126)
Description of changes: Creates a new specification for a `metadata.yaml` file that resides in the root of the controller repository. The purpose of this file is to provide human-friendly display information about the service (long name, acronym, links) and to provide a source of truth for API versions. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 7832e9a commit 75e6c92

File tree

12 files changed

+385
-31
lines changed

12 files changed

+385
-31
lines changed

cmd/ack-generate/command/apis.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/spf13/cobra"
2424

2525
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
26+
ackmetadata "github.com/aws-controllers-k8s/code-generator/pkg/metadata"
2627
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
2728
"github.com/aws-controllers-k8s/code-generator/pkg/util"
2829
)
@@ -59,10 +60,10 @@ func init() {
5960
// saveGeneratedMetadata saves the parameters used to generate APIs and checksum
6061
// of the generated code.
6162
func saveGeneratedMetadata(cmd *cobra.Command, args []string) error {
62-
err := ackgenerate.CreateGenerationMetadata(
63+
err := ackmetadata.CreateGenerationMetadata(
6364
optGenVersion,
6465
filepath.Join(optOutputPath, "apis"),
65-
ackgenerate.UpdateReasonAPIGeneration,
66+
ackmetadata.UpdateReasonAPIGeneration,
6667
optAWSSDKGoVersion,
6768
optGeneratorConfigPath,
6869
)

cmd/ack-generate/command/root.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ var (
4141
optDryRun bool
4242
sdkDir string
4343
optGeneratorConfigPath string
44+
optMetadataConfigPath string
4445
optOutputPath string
4546
)
4647

@@ -111,6 +112,9 @@ func init() {
111112
rootCmd.PersistentFlags().StringVar(
112113
&optGeneratorConfigPath, "generator-config-path", "", "Path to file containing instructions for code generation to use",
113114
)
115+
rootCmd.PersistentFlags().StringVar(
116+
&optMetadataConfigPath, "metadata-config-path", "", "Path to file containing service metadata to use",
117+
)
114118
rootCmd.PersistentFlags().StringVarP(
115119
&optOutputPath, "output", "o", "", "Path to directory to output generated files.",
116120
)

go.sum

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
6767
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
6868
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
6969
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
70-
github.com/aws-controllers-k8s/runtime v0.4.0 h1:qsCp1OKXoSMtjS+6zlH65PN3/UkVJNbI/ybwYjPmhrY=
71-
github.com/aws-controllers-k8s/runtime v0.4.0/go.mod h1:xA2F18PJerBHaqrS4de1lpP7skeSMeStkmh+3x5sWvw=
70+
github.com/aws-controllers-k8s/runtime v0.5.0 h1:lV2QxuEHHKS+nbJ7lYgPjwVBY6Aqw+RHJF8eDZZeswM=
71+
github.com/aws-controllers-k8s/runtime v0.5.0/go.mod h1:xA2F18PJerBHaqrS4de1lpP7skeSMeStkmh+3x5sWvw=
7272
github.com/aws/aws-sdk-go v1.37.4 h1:tWxrpMK/oRSXVnjUzhGeCWLR00fW0WF4V4sycYPPrJ8=
7373
github.com/aws/aws-sdk-go v1.37.4/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
7474
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -475,6 +475,7 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
475475
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
476476
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
477477
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
478+
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
478479
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
479480
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
480481
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
@@ -584,6 +585,7 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
584585
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
585586
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
586587
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
588+
golang.org/x/mod v0.1.0 h1:sfUMP1Gu8qASkorDVjnMuvgJzwFbTZSeXFiGBYAVdl4=
587589
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
588590
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
589591
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
@@ -622,6 +624,7 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL
622624
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
623625
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
624626
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
627+
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
625628
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
626629
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
627630
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -688,6 +691,7 @@ golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPj
688691
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
689692
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
690693
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
694+
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
691695
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
692696
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
693697
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=

pkg/model/multiversion/api_info.go renamed to pkg/metadata/api_info.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,12 @@
1111
// express or implied. See the License for the specific language governing
1212
// permissions and limitations under the License.
1313

14-
package multiversion
15-
16-
// TODO(a-hilaly) move this file outside of pkg/model/multiversion. Idealy we
17-
// Should be able to access APIStatus and APIInfo to prevent regenerating removed or
18-
// deprecated APIs.
14+
package metadata
1915

2016
type APIStatus string
2117

2218
const (
23-
APIStatusUnknown APIStatus = "unknown"
24-
APIStatusAvailable = "available"
19+
APIStatusAvailable APIStatus = "available"
2520
APIStatusRemoved = "removed"
2621
APIStatusDeprecated = "deprecated"
2722
)

pkg/generate/ack/output.go renamed to pkg/metadata/generation_metadata.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// express or implied. See the License for the specific language governing
1212
// permissions and limitations under the License.
1313

14-
package ack
14+
package metadata
1515

1616
import (
1717
"crypto/sha1"

pkg/metadata/service_metadata.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package metadata
15+
16+
import (
17+
"errors"
18+
"io/ioutil"
19+
20+
"github.com/ghodss/yaml"
21+
)
22+
23+
var (
24+
ErrNoServiceMetadataFile = errors.New("expected metadata file path, none provided")
25+
ErrNoAvailableVersions = errors.New("service metadata contains no available versions")
26+
)
27+
28+
// ServiceMetadata consists of information about the service and relative links as well
29+
// as a list of supported/deprecated versions
30+
type ServiceMetadata struct {
31+
Service ServiceDetails `json:"service"`
32+
// A list of all generated API versions of the service
33+
APIVersions []ServiceVersion `json:"api_versions"`
34+
}
35+
36+
// ServiceDetails contains string identifiers and relevant links for the
37+
// service
38+
type ServiceDetails struct {
39+
// The full display name for the service. eg. Amazon Elastic Kubernetes
40+
// Service
41+
FullName string `json:"full_name"`
42+
// The short name (abbreviation) for the service. eg. S3
43+
ShortName string `json:"short_name"`
44+
// The URL of the service's homepage
45+
Link string `json:"link"`
46+
// The URL of the service's main documentation/user guide
47+
Documentation string `json:"documentation"`
48+
}
49+
50+
// ServiceVersion describes the status of all existing version of the controller
51+
type ServiceVersion struct {
52+
APIVersion string `json:"api_version"`
53+
Status APIStatus `json:"status"`
54+
}
55+
56+
// GetLatestAPIVersion returns the latest available API version.
57+
// This should always be used by the generators as the source of truth
58+
// for what version to build.
59+
func (m *ServiceMetadata) GetLatestAPIVersion() (string, error) {
60+
availableVersions := m.GetAvailableAPIVersions()
61+
62+
if len(availableVersions) == 0 {
63+
return "", ErrNoAvailableVersions
64+
}
65+
66+
return availableVersions[len(availableVersions)-1], nil
67+
}
68+
69+
// GetDeprecatedAPIVersions returns all API versions that have been marked as
70+
// deprecated
71+
func (m *ServiceMetadata) GetDeprecatedAPIVersions() []string {
72+
return m.getVersionsByStatus(APIStatusDeprecated)
73+
}
74+
75+
// GetRemovedAPIVersions returns all API versions that have been marked as
76+
// removed
77+
func (m *ServiceMetadata) GetRemovedAPIVersions() []string {
78+
return m.getVersionsByStatus(APIStatusRemoved)
79+
}
80+
81+
// GetAvailableAPIVersions returns all API versions that have been marked as
82+
// available
83+
func (m *ServiceMetadata) GetAvailableAPIVersions() []string {
84+
return m.getVersionsByStatus(APIStatusAvailable)
85+
}
86+
87+
// getVersionsByStatus filters all of the versions by their respective statuses
88+
// and returns their API versions
89+
func (m *ServiceMetadata) getVersionsByStatus(status APIStatus) []string {
90+
if len(m.APIVersions) == 0 {
91+
return []string{}
92+
}
93+
94+
versions := []string{}
95+
for _, v := range m.APIVersions {
96+
if v.Status == status {
97+
versions = append(versions, v.APIVersion)
98+
}
99+
}
100+
return versions
101+
}
102+
103+
// NewServiceMetadata returns a new Metadata object given a supplied
104+
// path to a metadata file
105+
func NewServiceMetadata(
106+
metadataPath string,
107+
) (ServiceMetadata, error) {
108+
if metadataPath == "" {
109+
return ServiceMetadata{}, ErrNoServiceMetadataFile
110+
}
111+
content, err := ioutil.ReadFile(metadataPath)
112+
if err != nil {
113+
return ServiceMetadata{}, err
114+
}
115+
gc := ServiceMetadata{}
116+
if err = yaml.Unmarshal(content, &gc); err != nil {
117+
return ServiceMetadata{}, err
118+
}
119+
return gc, nil
120+
}

pkg/model/multiversion/manager.go

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"gopkg.in/src-d/go-git.v4"
2222

2323
ackgenconfig "github.com/aws-controllers-k8s/code-generator/pkg/generate/config"
24+
ackmetadata "github.com/aws-controllers-k8s/code-generator/pkg/metadata"
2425
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
2526
"github.com/aws-controllers-k8s/code-generator/pkg/util"
2627
)
@@ -35,31 +36,36 @@ var (
3536
// of each non-deprecated version with their correspending ackmodel.Model
3637
// and APIInfos.
3738
type APIVersionManager struct {
38-
gitRepo *git.Repository
39+
gitRepo *git.Repository
40+
metadata ackmetadata.ServiceMetadata
3941

4042
hubVersion string
4143
spokeVersions []string
4244

43-
deprecatedVersions []string
44-
removedVersions []string
45-
46-
apiInfos map[string]APIInfo
45+
apiInfos map[string]ackmetadata.APIInfo
4746
models map[string]*ackmodel.Model
4847
}
4948

5049
// NewAPIVersionManager initialises and returns a new APIVersionManager.
5150
func NewAPIVersionManager(
5251
sdkCacheDir string,
52+
metadataPath string,
5353
serviceAlias string,
5454
hubVersion string,
55-
apisInfo map[string]APIInfo,
55+
apisInfo map[string]ackmetadata.APIInfo,
5656
defaultConfig ackgenconfig.Config,
5757
) (*APIVersionManager, error) {
5858
if len(apisInfo) == 0 {
5959
return nil, fmt.Errorf("empty apisInfo")
6060
}
6161

62-
spokeVersions := make([]string, 0, len(apisInfo)-1)
62+
metadata, err := ackmetadata.NewServiceMetadata(metadataPath)
63+
if err != nil {
64+
return nil, err
65+
}
66+
67+
spokeVersions := []string{}
68+
6369
gitRepo, err := util.LoadRepository(sdkCacheDir)
6470
if err != nil {
6571
return nil, fmt.Errorf("cannot read sdk git repository: %v", err)
@@ -68,11 +74,19 @@ func NewAPIVersionManager(
6874
SDKAPIHelper := ackmodel.NewSDKHelper(sdkCacheDir)
6975

7076
// create model for each non-deprecated api version
71-
models := make(map[string]*ackmodel.Model, len(apisInfo))
72-
for apiVersion, apiInfo := range apisInfo {
73-
// TODO(a-hilaly) filter deprecated and removed api versions
74-
if apiVersion != hubVersion {
75-
spokeVersions = append(spokeVersions, apiVersion)
77+
models := map[string]*ackmodel.Model{}
78+
for _, version := range metadata.APIVersions {
79+
if version.Status == ackmetadata.APIStatusDeprecated || version.Status == ackmetadata.APIStatusRemoved {
80+
continue
81+
}
82+
83+
if version.APIVersion != hubVersion {
84+
spokeVersions = append(spokeVersions, version.APIVersion)
85+
}
86+
87+
apiInfo, ok := apisInfo[version.APIVersion]
88+
if !ok {
89+
return nil, fmt.Errorf("could not find API info for API version %s", version.APIVersion)
7690
}
7791

7892
err = SDKAPIHelper.WithSDKVersion(apiInfo.AWSSDKVersion)
@@ -87,25 +101,26 @@ func NewAPIVersionManager(
87101

88102
i, err := ackmodel.New(
89103
SDKAPI,
90-
apiVersion,
104+
version.APIVersion,
91105
apiInfo.GeneratorConfigPath,
92106
defaultConfig,
93107
)
94108
if err != nil {
95-
return nil, fmt.Errorf("cannot create model for API version %s: %v", apiVersion, err)
109+
return nil, fmt.Errorf("cannot create model for API version %s: %v", version.APIVersion, err)
96110
}
97-
models[apiVersion] = i
111+
models[version.APIVersion] = i
98112
}
99113

100114
sort.Strings(spokeVersions)
101115
model := &APIVersionManager{
102116
gitRepo: gitRepo,
117+
metadata: metadata,
103118
hubVersion: hubVersion,
104119
spokeVersions: spokeVersions,
105120
apiInfos: apisInfo,
106121
models: models,
107122
}
108-
// TODO(hilalymh): Audit deprecated and removed versions
123+
109124
return model, nil
110125
}
111126

@@ -140,10 +155,10 @@ func (m *APIVersionManager) VerifyAPIVersions(apiVersions ...string) error {
140155
if !ok {
141156
return fmt.Errorf("%v: %s", ErrAPIVersionNotFound, apiVersion)
142157
}
143-
if apiInfo.Status == APIStatusDeprecated {
158+
if apiInfo.Status == ackmetadata.APIStatusDeprecated {
144159
return fmt.Errorf("%v: %s", ErrAPIVersionDeprecated, apiVersion)
145160
}
146-
if apiInfo.Status == APIStatusRemoved {
161+
if apiInfo.Status == ackmetadata.APIStatusRemoved {
147162
return fmt.Errorf("%v: %s", ErrAPIVersionRemoved, apiVersion)
148163
}
149164
}

pkg/testdata/models/metadata.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
service:
2+
full_name: Amazon Test Service
3+
short_name: ATS
4+
link: https://example.com/
5+
documentation: https://docs.example.com/
6+
versions:
7+
- api_version: v1alpha1
8+
status: available

0 commit comments

Comments
 (0)