Skip to content

Commit

Permalink
Merge pull request #3998 from MartinForReal/shafan/removeapiversion
Browse files Browse the repository at this point in the history
track2 sdk: add subresource template and add vmssvmclient and subnetclient
  • Loading branch information
k8s-ci-robot authored May 30, 2023
2 parents e20de36 + 63c3ccf commit 813dbee
Show file tree
Hide file tree
Showing 19 changed files with 931 additions and 30 deletions.
2 changes: 2 additions & 0 deletions pkg/azclient/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ generatecode: build ## Generate client
$(TYPESCAFFOLD) --package github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 --package-alias armcompute --resource AvailabilitySet --client-name AvailabilitySetsClient --verbs get,list
$(TYPESCAFFOLD) --package github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 --package-alias armcompute --resource VirtualMachine --client-name VirtualMachinesClient --verbs createorupdate,delete,list --expand
$(TYPESCAFFOLD) --package github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 --package-alias armcompute --resource VirtualMachineScaleSet --client-name VirtualMachineScaleSetsClient --verbs get,createorupdate,delete,list
$(TYPESCAFFOLD) --package github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 --package-alias armcompute --resource VirtualMachineScaleSet --subresource VirtualMachineScaleSetVM --client-name VirtualMachineScaleSetVMsClient --verbs get,delete,list
$(TYPESCAFFOLD) --package github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 --package-alias armcompute --resource Snapshot --client-name SnapshotsClient --verbs get,createorupdate,delete
$(TYPESCAFFOLD) --package github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v3 --package-alias armnetwork --resource VirtualNetwork --subresource Subnet --client-name SubnetsClient --verbs get,createorupdate,delete,list --expand
$(TYPESCAFFOLD) --package github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v3 --package-alias armnetwork --resource Interface --client-name InterfacesClient --verbs get,createorupdate,delete,list --expand
$(TYPESCAFFOLD) --package github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v3 --package-alias armnetwork --resource LoadBalancer --client-name LoadBalancersClient --verbs get,createorupdate,delete,list --expand
$(TYPESCAFFOLD) --package github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v3 --package-alias armnetwork --resource PrivateEndpoint --client-name PrivateEndpointsClient --verbs get,createorupdate --expand
Expand Down
60 changes: 50 additions & 10 deletions pkg/azclient/client-gen/cmd/typescaffold/type_scaffold.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (

type TypeScaffoldOptions struct {
Resource string
SubResource string
Package string
PackageAlias string
ClientName string
Expand All @@ -38,7 +39,11 @@ type TypeScaffoldOptions struct {
}

var (
TypeTemplateRaw = `
TypeTemplateHeader = `
{{ $resource := .Resource}}
{{ if (gt (len .SubResource) 0) }}
{{ $resource = .SubResource}}
{{ end }}
/*
Copyright {{now.UTC.Year}} The Kubernetes Authors.
Expand All @@ -56,12 +61,13 @@ limitations under the License.
*/
// +azure:enableclientgen:=true
package {{tolower .Resource}}client
package {{tolower $resource}}client
import (
{{tolower .PackageAlias}} "{{.Package}}"
"sigs.k8s.io/cloud-provider-azure/pkg/azclient/utils"
)
`
TypeResourceTemplate = `
// +azure:client:verbs={{join .Verbs ";"}},resource={{.Resource}},packageName={{.Package}},packageAlias={{tolower .PackageAlias}},clientName={{.ClientName}},expand={{.Expand}}
type Interface interface {
{{ $expandable := .Expand}}
Expand All @@ -78,15 +84,34 @@ type Interface interface {
utils.DeleteFunc[{{tolower $packageAlias}}.{{$resource}}]{{end}}
{{end}}
}
`
TypeSubResourceTemplate = `
// +azure:client:verbs={{join .Verbs ";"}},resource={{.Resource}},subResource={{.SubResource}},packageName={{.Package}},packageAlias={{tolower .PackageAlias}},clientName={{.ClientName}},expand={{.Expand}}
type Interface interface {
{{ $expandable := .Expand}}
{{ $packageAlias := .PackageAlias}}
{{ $resource := .SubResource}}
{{range $index,$element := .Verbs}}
{{if strequal $element "Get"}}
{{ if $expandable }}utils.SubResourceGetWithExpandFunc[{{tolower $packageAlias}}.{{$resource}}]{{ else }}utils.SubResourceGetFunc[{{tolower $packageAlias}}.{{$resource}}]{{end}}{{end}}
{{if or (strequal $element "ListByRG") (strequal $element "List") }}
utils.SubResourceListFunc[{{tolower $packageAlias}}.{{$resource}}]{{end}}
{{if strequal $element "CreateOrUpdate"}}
utils.SubResourceCreateOrUpdateFunc[{{tolower $packageAlias}}.{{$resource}}]{{end}}
{{if strequal $element "Delete"}}
utils.SubResourceDeleteFunc[{{tolower $packageAlias}}.{{$resource}}]{{end}}
{{end}}
}
`
typesTemplateHelpers = template.FuncMap{
"tolower": strings.ToLower,
"now": time.Now,
"join": strings.Join,
"strequal": strings.EqualFold,
}
typesSubResourceTemplate = template.Must(template.New("object-scaffolding").Funcs(typesTemplateHelpers).Parse(TypeTemplateHeader + TypeSubResourceTemplate))

typesTemplate = template.Must(template.New("object-scaffolding").Funcs(typesTemplateHelpers).Parse(TypeTemplateRaw))
typesResourceTemplate = template.Must(template.New("object-scaffolding").Funcs(typesTemplateHelpers).Parse(TypeTemplateHeader + TypeResourceTemplate))
)

func main() {
Expand All @@ -99,18 +124,30 @@ func main() {
Long: `scaffold client interface for azure resource`,

Run: func(cmd *cobra.Command, args []string) {

content := new(bytes.Buffer)
if err := typesTemplate.Execute(content, scaffoldOptions); err != nil {
fmt.Printf("failed to generate client from template %s\n", err.Error())
return
if len(scaffoldOptions.SubResource) > 0 {
if err := typesSubResourceTemplate.Execute(content, scaffoldOptions); err != nil {
fmt.Printf("failed to generate client from template %s\n", err.Error())
return
}
} else {
if err := typesResourceTemplate.Execute(content, scaffoldOptions); err != nil {
fmt.Printf("failed to generate client from template %s\n", err.Error())
return
}
}
formattedContent, err := format.Source(content.Bytes())
if err != nil {
fmt.Printf("failed to generate client %s\n", err.Error())
fmt.Printf("failed to generate client %s\noriginal content: \n%s\n", err.Error(), content.String())
return
}
fileName := strings.ToLower(scaffoldOptions.Resource) + "client"
var resourceName string
if len(scaffoldOptions.SubResource) > 0 {
resourceName = scaffoldOptions.SubResource
} else {
resourceName = scaffoldOptions.Resource
}
fileName := strings.ToLower(resourceName) + "client"
if err := os.MkdirAll(fileName, 0755); err != nil && !os.IsExist(err) {
fmt.Printf("failed to create dir %s\n", err.Error())
return
Expand Down Expand Up @@ -152,8 +189,11 @@ func main() {
}
rootCmd.Flags().StringSliceVar(&scaffoldOptions.Verbs, "verbs", []string{"get", "createorupdate", "delete", "listbyrg"}, "verbs")
rootCmd.Flags().BoolVar(&scaffoldOptions.Expand, "expand", false, "get support expand params")
rootCmd.Flags().StringVar(&scaffoldOptions.SubResource, "subresource", "", "subresource name")

err := rootCmd.Execute()
if err != nil {
fmt.Printf("failed to generate interface %s\n", err.Error())
os.Exit(1)
}
}
60 changes: 42 additions & 18 deletions pkg/azclient/client-gen/generator/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import "html/template"
type ClientGenConfig struct {
Verbs []string
Resource string
SubResource string `marker:"subResource,optional"`
PackageName string
PackageAlias string
ClientName string
Expand Down Expand Up @@ -48,14 +49,18 @@ func New(subscriptionID string, credential azcore.TokenCredential, options *arm.
`))

const CreateOrUpdateFuncTemplateRaw = `
// CreateOrUpdate creates or updates a {{.Resource}}.
func (client *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, resourceName string, resource {{.PackageAlias}}.{{.Resource}}) (*{{.PackageAlias}}.{{.Resource}}, error) {
resp, err := utils.NewPollerWrapper(client.{{.ClientName}}.BeginCreateOrUpdate(ctx, resourceGroupName, resourceName, resource, nil)).WaitforPollerResp(ctx)
{{ $resource := .Resource}}
{{ if (gt (len .SubResource) 0) }}
{{ $resource = .SubResource}}
{{ end }}
// CreateOrUpdate creates or updates a {{$resource}}.
func (client *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, resourceName string,{{with .SubResource}}parentResourceName string, {{end}} resource {{.PackageAlias}}.{{$resource}}) (*{{.PackageAlias}}.{{$resource}}, error) {
resp, err := utils.NewPollerWrapper(client.{{.ClientName}}.BeginCreateOrUpdate(ctx, resourceGroupName, resourceName,{{with .SubResource}}parentResourceName,{{end}} resource, nil)).WaitforPollerResp(ctx)
if err != nil {
return nil, err
}
if resp != nil {
return &resp.{{.Resource}}, nil
return &resp.{{$resource}}, nil
}
return nil, nil
}
Expand All @@ -64,8 +69,12 @@ func (client *Client) CreateOrUpdate(ctx context.Context, resourceGroupName stri
var CreateOrUpdateFuncTemplate = template.Must(template.New("object-scaffolding-create-func").Parse(CreateOrUpdateFuncTemplateRaw))

const ListByRGFuncTemplateRaw = `
// List gets a list of {{.Resource}} in the resource group.
func (client *Client) List(ctx context.Context, resourceGroupName string) (result []*{{.PackageAlias}}.{{.Resource}}, rerr error) {
{{ $resource := .Resource}}
{{ if (gt (len .SubResource) 0) }}
{{ $resource = .SubResource}}
{{ end }}
// List gets a list of {{$resource}} in the resource group.
func (client *Client) List(ctx context.Context, resourceGroupName string{{with .SubResource}}, parentResourceName string{{end}}) (result []*{{.PackageAlias}}.{{$resource}}, rerr error) {
pager := client.{{.ClientName}}.NewListByResourceGroupPager(resourceGroupName, nil)
for pager.More() {
nextResult, err := pager.NextPage(ctx)
Expand All @@ -81,9 +90,13 @@ func (client *Client) List(ctx context.Context, resourceGroupName string) (resul
var ListByRGFuncTemplate = template.Must(template.New("object-scaffolding-list-func").Parse(ListByRGFuncTemplateRaw))

const ListFuncTemplateRaw = `
// List gets a list of {{.Resource}} in the resource group.
func (client *Client) List(ctx context.Context, resourceGroupName string) (result []*{{.PackageAlias}}.{{.Resource}}, rerr error) {
pager := client.{{.ClientName}}.NewListPager(resourceGroupName, nil)
{{ $resource := .Resource}}
{{ if (gt (len .SubResource) 0) }}
{{ $resource = .SubResource}}
{{ end }}
// List gets a list of {{$resource}} in the resource group.
func (client *Client) List(ctx context.Context, resourceGroupName string{{with .SubResource}}, parentResourceName string{{end}}) (result []*{{.PackageAlias}}.{{$resource}}, rerr error) {
pager := client.{{.ClientName}}.NewListPager(resourceGroupName,{{with .SubResource}}parentResourceName,{{end}} nil)
for pager.More() {
nextResult, err := pager.NextPage(ctx)
if err != nil {
Expand All @@ -98,29 +111,37 @@ func (client *Client) List(ctx context.Context, resourceGroupName string) (resul
var ListFuncTemplate = template.Must(template.New("object-scaffolding-list-func").Parse(ListFuncTemplateRaw))

const DeleteFuncTemplateRaw = `
// Delete deletes a {{.Resource}} by name.
func (client *Client) Delete(ctx context.Context, resourceGroupName string, resourceName string) error {
_, err := utils.NewPollerWrapper(client.BeginDelete(ctx, resourceGroupName, resourceName, nil)).WaitforPollerResp(ctx)
{{ $resource := .Resource}}
{{ if (gt (len .SubResource) 0) }}
{{ $resource = .SubResource}}
{{ end }}
// Delete deletes a {{$resource}} by name.
func (client *Client) Delete(ctx context.Context, resourceGroupName string, {{with .SubResource}} parentResourceName string, {{end}}resourceName string) error {
_, err := utils.NewPollerWrapper(client.BeginDelete(ctx, resourceGroupName,{{with .SubResource}}parentResourceName,{{end}} resourceName, nil)).WaitforPollerResp(ctx)
return err
}
`

var DeleteFuncTemplate = template.Must(template.New("object-scaffolding-delete-func").Parse(DeleteFuncTemplateRaw))

const GetFuncTemplateRaw = `
// Get gets the {{.Resource}}
func (client *Client) Get(ctx context.Context, resourceGroupName string, resourceName string{{if .Expand}}, expand *string{{end}}) (result *{{.PackageAlias}}.{{.Resource}}, rerr error) {
{{ $resource := .Resource}}
{{ if (gt (len .SubResource) 0) }}
{{ $resource = .SubResource}}
{{ end }}
// Get gets the {{$resource}}
func (client *Client) Get(ctx context.Context, resourceGroupName string, {{with .SubResource}}parentResourceName string,{{end}} resourceName string{{if .Expand}}, expand *string{{end}}) (result *{{.PackageAlias}}.{{$resource}}, rerr error) {
var ops *{{.PackageAlias}}.{{.ClientName}}GetOptions
{{if .Expand}}if expand != nil {
ops = &{{.PackageAlias}}.{{.ClientName}}GetOptions{ Expand: expand }
}{{end}}
resp, err := client.{{.ClientName}}.Get(ctx, resourceGroupName, resourceName, ops)
resp, err := client.{{.ClientName}}.Get(ctx, resourceGroupName,{{with .SubResource}}parentResourceName,{{end}} resourceName, ops)
if err != nil {
return nil, err
}
//handle statuscode
return &resp.{{.Resource}}, nil
return &resp.{{$resource}}, nil
}
`

Expand All @@ -136,7 +157,10 @@ type ImportStatement struct {

var TestSuiteTemplate = template.Must(template.New("object-scaffolding-test-suite").Parse(
`
{{ $resource := .Resource}}
{{ if (gt (len .SubResource) 0) }}
{{ $resource = .SubResource}}
{{ end }}
func TestClient(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Client Suite")
Expand All @@ -152,7 +176,7 @@ var recorder *recording.Recorder
var realClient Interface
var _ = BeforeSuite(func(ctx context.Context) {
recorder, err = recording.NewRecorder("testdata/{{.Resource}}")
recorder, err = recording.NewRecorder("testdata/{{$resource}}")
Expect(err).ToNot(HaveOccurred())
subscriptionID = recorder.SubscriptionID()
Expect(err).NotTo(HaveOccurred())
Expand Down
46 changes: 46 additions & 0 deletions pkg/azclient/deploymentclient/mock_deploymentclient/interface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/azclient/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.1.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1
github.com/Azure/go-armbalancer v0.0.2
github.com/golang/mock v1.6.0
github.com/google/go-cmp v0.5.9
github.com/google/uuid v1.3.0
github.com/onsi/ginkgo/v2 v2.9.5
Expand All @@ -29,7 +30,6 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
Expand Down
5 changes: 4 additions & 1 deletion pkg/azclient/interfaceclient/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ limitations under the License.
package interfaceclient

import (
"context"

armnetwork "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v3"

"sigs.k8s.io/cloud-provider-azure/pkg/azclient/utils"
Expand All @@ -26,7 +28,8 @@ import (
// +azure:client:verbs=get;createorupdate;delete;list,resource=Interface,packageName=github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v3,packageAlias=armnetwork,clientName=InterfacesClient,expand=true
type Interface interface {
utils.GetWithExpandFunc[armnetwork.Interface]

// GetVirtualMachineScaleSetNetworkInterface gets a network.Interface of VMSS VM.
GetVirtualMachineScaleSetNetworkInterface(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, options *armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceOptions) (armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceResponse, error)
utils.CreateOrUpdateFunc[armnetwork.Interface]

utils.DeleteFunc[armnetwork.Interface]
Expand Down
15 changes: 15 additions & 0 deletions pkg/azclient/interfaceclient/mock_interfaceclient/interface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 813dbee

Please sign in to comment.