Skip to content
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

API Skeleton 2021-01-31 - swagger #1200

Closed
wants to merge 3 commits into from

Conversation

mjudeikis
Copy link
Contributor

@mjudeikis mjudeikis commented Nov 27, 2020

This is just a skeleton builds on top of #1191

This PR does:

  • enables us to generate swagger for multiple apis in more repeatable way based on features apis delivers
  • Adds placeholders for some new api fields we agreed to add (SDN provider, kubeconfig download endpoint, encryption at host, more VM types (enum adding)). No feature behind them yet.
  • features will be implemented later

Copy link
Member

@jim-minter jim-minter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking pretty plausible to me. Let's catch up on this tomorrow.

pkg/api/v20210131preview/openshiftclustercredentials.go Outdated Show resolved Hide resolved
pkg/api/v20210131preview/openshiftclustercredentials.go Outdated Show resolved Hide resolved
pkg/api/v20210131preview/openshiftclustercredentials.go Outdated Show resolved Hide resolved
@github-actions github-actions bot added the needs-rebase branch needs a rebase label Dec 4, 2020
@github-actions
Copy link

github-actions bot commented Dec 4, 2020

Please rebase pull request.

@mjudeikis mjudeikis force-pushed the api.skeleton branch 2 times, most recently from e05269f to b3b0a69 Compare December 14, 2020 12:08
@github-actions github-actions bot removed the needs-rebase branch needs a rebase label Dec 14, 2020
@mjudeikis mjudeikis marked this pull request as ready for review December 14, 2020 12:10
@mjudeikis mjudeikis force-pushed the api.skeleton branch 3 times, most recently from 61479b8 to e7bf5d5 Compare December 14, 2020 12:49
Copy link
Member

@jim-minter jim-minter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a lot of nits - please fix out and we'll merge.

Converters and changes to internal API are missing here - OK with those being in a follow-up PR.

pkg/api/v20210131preview/openshiftadmincredentials.go Outdated Show resolved Hide resolved
pkg/api/v20210131preview/openshiftadmincredentials.go Outdated Show resolved Hide resolved
pkg/api/v20210131preview/openshiftadmincredentials.go Outdated Show resolved Hide resolved
pkg/swagger/swagger.go Outdated Show resolved Hide resolved
pkg/swagger/swagger.go Outdated Show resolved Hide resolved
pkg/swagger/swagger.go Show resolved Hide resolved
pkg/swagger/typewalker.go Outdated Show resolved Hide resolved
@mjudeikis mjudeikis force-pushed the api.skeleton branch 3 times, most recently from 020f3fd to c0a5aea Compare December 16, 2020 14:33
@mjudeikis
Copy link
Contributor Author

Azure/azure-rest-api-specs#12144 upstream review

@mjudeikis
Copy link
Contributor Author

We had an issue with systemData.
https://github.com/Azure/azure-rest-api-specs/pull/12144/checks?check_run_id=1564328520
https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/common-api-contracts.md#system-metadata-for-all-azure-resources

I interpreted this as a mandatory field on the main object we return. Hence adding it to the OpenShiftCluster object only.

In addition, added struct wrapper to manage API features in all the generators.

@mjudeikis
Copy link
Contributor Author

@jim-minter, the last commit will require your attention.

@mjudeikis mjudeikis added this to the Sprint 196 milestone Jan 27, 2021
pkg/swagger/examples.go Outdated Show resolved Hide resolved
pkg/swagger/swagger.go Outdated Show resolved Hide resolved
@mjudeikis mjudeikis force-pushed the api.skeleton branch 3 times, most recently from eeec873 to e4ae89f Compare February 9, 2021 12:06
var _ generator = &apiv20200430{}

type features struct {
kubeconfig bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed - test if ExampleOpenShiftClusterAdminKubeconfigResponse is non-nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easier to read and easier to understand. As much as it is possible I think consistency is better if we keep same behavior (feature flags). Otherwise some of them will be "flags, some function checks". Unreadable and insiders knowledge.

systemData bool
}

type apiv20210131preview struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is pretty over engineered - you could probably simplify and get away with a static configuration like this:

type api struct {
	exampleOpenShiftClusterPutParameter func() interface{}
	exampleOpenShiftClusterPatchParameter func() interface{}
	exampleOpenShiftClusterResponse func() interface{}
	exampleOpenShiftClusterCredentialsResponse func() interface{}
	exampleOpenShiftClusterAdminKubeconfigResponse func() interface{}
	exampleOpenShiftClusterListResponse func() interface{}
	exampleOperationListResponse func() interface{}

	xmsEnum            []string
	commonTypesVersion string
	systemData         bool
}

var apis = map[string]*api {
	apiv20200430Path: {
		exampleOpenShiftClusterPutParameter: v20200430.ExampleOpenShiftClusterPutParameter,
		// ...
	},
	// ...
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this in go?

cannot use v20200430.ExampleOpenShiftClusterPutParameter (value of type func() *v20200430.OpenShiftCluster) as func() interface{} value in struct literal

was sitting on this for 2 hours trying to understand what you had in mind here....

foo func() interface{}
!=
func foo() *Custom{

https://play.golang.org/p/jUb0aqTLP5s

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before I start refactoring for 4th time I would like to understand if Im missing something here for this to work (?)

Copy link
Collaborator

@gvanderpotte gvanderpotte Mar 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This caught my curiosity and found this interesting answer.
https://stackoverflow.com/a/54751503
I still need to see if the same applies to return values

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mjudeikis I'm inclined to do the horrible thing and make all the Example*() functions return interface{}. It's rubbish but it's a lot less boilerplate.

pkg/swagger/swagger.go Outdated Show resolved Hide resolved
pkg/swagger/generator.go Outdated Show resolved Hide resolved
@@ -73,16 +93,18 @@ func Run(api, outputDir string) error {

xmsEnumList := map[string]struct{}{}

if api != "github.com/Azure/ARO-RP/pkg/api/v20200430" {
names := []string{"OpenShiftClusterList", "OpenShiftClusterCredentials"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a lot of the code around here could be more neatly parameterised and defined in g

@@ -126,6 +148,19 @@ func Run(api, outputDir string) error {
}

s.Definitions[azureResource].Properties = properties

if g.Features().systemData {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't look right. I think it is masking the fact that we actually need to add this to the model and deal with it. See https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/common-api-contracts.md#system-metadata-for-all-azure-resources

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added separate PR for this. Sill in draft, but working on it #1412

@@ -164,6 +164,7 @@ type Response struct {
Schema *Schema `json:"schema,omitempty"`
Headers Headers `json:"headers,omitempty"`
Examples Example `json:"examples,omitempty"`
SystemData *Schema `json:"systemData,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ARM CI/sign-off required this for all new APIs/API Versions. I think we will need to make change not to log this in any away in our code but overall we need it now

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure that I understand - how is it related to the response object?

@jim-minter jim-minter removed this from the Sprint 196 milestone Feb 18, 2021
@mjudeikis mjudeikis added next-up and removed next-up labels Feb 24, 2021
@jim-minter
Copy link
Member

bump - there's a longstanding unactioned review here

@@ -126,6 +142,19 @@ func Run(api, outputDir string) error {
}

s.Definitions[azureResource].Properties = properties

if g.systemData {
s.Definitions[azureResource].Properties = append(s.Definitions[azureResource].Properties,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering if this is right?

@mjudeikis
Copy link
Contributor Author

/azp run e2e

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@github-actions
Copy link

Please rebase pull request.

@github-actions github-actions bot added the needs-rebase branch needs a rebase label Apr 21, 2021
@github-actions github-actions bot removed the needs-rebase branch needs a rebase label Apr 21, 2021
@mjudeikis
Copy link
Contributor Author

/azp run e2e

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mjudeikis
Copy link
Contributor Author

/azp run e2e

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mjudeikis
Copy link
Contributor Author

/azp run e2e

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

@m1kola m1kola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like how you introduced support for generating multiple api versions and their examples, but I'm not sure that changes related to systemData and admin kube config are correct. For instance this PR introduces a new endpoint to list the admin kube config. Are we ready to make this decision?

I'm up for merging the generator part, but not sure that I'm comfortable with placeholders for new features and related swagger generation changes. If you want - we can split this into multiple pull requests so we can merge the generator part faster.

@@ -164,6 +164,7 @@ type Response struct {
Schema *Schema `json:"schema,omitempty"`
Headers Headers `json:"headers,omitempty"`
Examples Example `json:"examples,omitempty"`
SystemData *Schema `json:"systemData,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure that I understand - how is it related to the response object?

},
}
if g.kubeconfig {
s.Paths["/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.RedHatOpenShift/openShiftClusters/{resourceName}/listAdminCredentials"] = &PathItem{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implies that we will have another endpoint (and another az cli command) to get admin kubeconfig. Why not extend existing command/endpoint for the new verson?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this will be different endpoint and API. Few reasons for this:

  1. Prevent api breakage for old API
  2. API purpose is different as it will download file, and not expose
  3. Easier to implement.
  4. It will return privileged kubeconfig so in the future dedicated rbac could be added

@@ -24,7 +29,7 @@ func Run(api, outputDir string) error {
Schemes: []string{"https"},
Consumes: []string{"application/json"},
Produces: []string{"application/json"},
Paths: populateTopLevelPaths("Microsoft.RedHatOpenShift", "openShiftCluster", "OpenShift cluster"),
Paths: g.populateTopLevelPaths("Microsoft.RedHatOpenShift", "openShiftCluster", "OpenShift cluster"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put resourceProviderNamespace as a parameter into generator struct so we don't have to pass it here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not on this PR, or one if follow-up. Too much change.

Responses: g.populateResponses("OpenShiftClusterAdminKubeconfig", false, http.StatusOK),
},
}
}

s.Paths["/providers/Microsoft.RedHatOpenShift/operations"] = &PathItem{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to move listCredentials, listAdminCredentials (if we actually need it, see the question above) and operations paths somewhere into generator. Similarly to populateTopLevelPaths.

And probably all logic from Run into generator so the whole Run function will be something like:

g, err := New(api, params1, param2)
if err != nil {
	return err
}

s := g.Swagger()

b, err := json.MarshalIndent(s, "", "  ")
if err != nil {
	return err
}

b = append(b, '\n')

return ioutil.WriteFile(outputDir+"/redhatopenshift.json", b, 0666)

But I think it should be a separate PR: this one is already too big.

@mjudeikis
Copy link
Contributor Author

I like how you introduced support for generating multiple api versions and their examples, but I'm not sure that changes related to systemData and admin kube config are correct. For instance this PR introduces a new endpoint to list the admin kube config. Are we ready to make this decision?

I'm up for merging the generator part, but not sure that I'm comfortable with placeholders for new features and related swagger generation changes. If you want - we can split this into multiple pull requests so we can merge the generator part faster.

I think I gonna split the PRs as you suggest. Initially placeholder where there to kick start arm review process on API so could do implementation in parallel. We still need to do this, but maybe separate PR.

@mjudeikis
Copy link
Contributor Author

will re-open in smallers prs

@mjudeikis mjudeikis closed this Apr 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants