Skip to content

Commit 697835a

Browse files
authored
Merge pull request #9 from jwcesign/main
feat: add instance types provider
2 parents 40b6ae7 + 154359b commit 697835a

File tree

4,844 files changed

+1768483
-16
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

4,844 files changed

+1768483
-16
lines changed

.github/workflows/presubmit.yaml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Pre-submit check
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request: {}
7+
8+
permissions:
9+
contents: read
10+
pull-requests: read
11+
12+
jobs:
13+
presubmit:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
submodules: true
19+
20+
- uses: actions/setup-go@v5
21+
with:
22+
go-version: '1.23'
23+
cache: false
24+
25+
- name: Install toolchain
26+
run: |
27+
make toolchain
28+
29+
- name: Presubmit check
30+
run: |
31+
make presubmit

go.mod

+14-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ module github.com/cloudpilot-ai/karpenter-provider-gcp
33
go 1.23.2
44

55
require (
6+
cloud.google.com/go/compute v1.23.3
67
github.com/awslabs/operatorpkg v0.0.0-20241205163410-0fff9f28d115
78
github.com/cloudpilot-ai/karpenter-provider-alibabacloud v0.1.4
89
github.com/mitchellh/hashstructure/v2 v2.0.2
10+
github.com/patrickmn/go-cache v2.1.0+incompatible
911
github.com/samber/lo v1.47.0
12+
google.golang.org/api v0.149.0
1013
k8s.io/api v0.32.1
1114
k8s.io/apimachinery v0.32.1
1215
k8s.io/client-go v0.32.1
@@ -15,6 +18,7 @@ require (
1518
)
1619

1720
require (
21+
cloud.google.com/go/compute/metadata v0.3.0 // indirect
1822
github.com/beorn7/perks v1.0.1 // indirect
1923
github.com/cespare/xxhash/v2 v2.3.0 // indirect
2024
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@@ -27,20 +31,23 @@ require (
2731
github.com/go-openapi/jsonreference v0.20.2 // indirect
2832
github.com/go-openapi/swag v0.23.0 // indirect
2933
github.com/gogo/protobuf v1.3.2 // indirect
34+
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
3035
github.com/golang/protobuf v1.5.4 // indirect
3136
github.com/google/btree v1.1.3 // indirect
3237
github.com/google/gnostic-models v0.6.8 // indirect
3338
github.com/google/go-cmp v0.6.0 // indirect
3439
github.com/google/gofuzz v1.2.0 // indirect
40+
github.com/google/s2a-go v0.1.7 // indirect
3541
github.com/google/uuid v1.6.0 // indirect
42+
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
43+
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
3644
github.com/josharian/intern v1.0.0 // indirect
3745
github.com/json-iterator/go v1.1.12 // indirect
3846
github.com/klauspost/compress v1.17.9 // indirect
3947
github.com/mailru/easyjson v0.7.7 // indirect
4048
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
4149
github.com/modern-go/reflect2 v1.0.2 // indirect
4250
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
43-
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
4451
github.com/pkg/errors v0.9.1 // indirect
4552
github.com/prometheus/client_golang v1.20.5 // indirect
4653
github.com/prometheus/client_model v0.6.1 // indirect
@@ -49,7 +56,9 @@ require (
4956
github.com/robfig/cron/v3 v3.0.1 // indirect
5057
github.com/spf13/pflag v1.0.5 // indirect
5158
github.com/x448/float16 v0.8.4 // indirect
59+
go.opencensus.io v0.24.0 // indirect
5260
go.uber.org/multierr v1.11.0 // indirect
61+
golang.org/x/crypto v0.31.0 // indirect
5362
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
5463
golang.org/x/net v0.33.0 // indirect
5564
golang.org/x/oauth2 v0.23.0 // indirect
@@ -59,6 +68,10 @@ require (
5968
golang.org/x/text v0.21.0 // indirect
6069
golang.org/x/time v0.9.0 // indirect
6170
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
71+
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
72+
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect
73+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect
74+
google.golang.org/grpc v1.65.0 // indirect
6275
google.golang.org/protobuf v1.36.1 // indirect
6376
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
6477
gopkg.in/inf.v0 v0.9.1 // indirect

go.sum

+105
Large diffs are not rendered by default.

pkg/auth/credential.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
Copyright 2025 The CloudPilot AI Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package auth
18+
19+
import "google.golang.org/api/option"
20+
21+
type Credential struct {
22+
ProjectID string
23+
Region string
24+
CredentialOptions option.ClientOption
25+
}

pkg/cache/cache.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright 2025 The CloudPilot AI Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cache
18+
19+
import "time"
20+
21+
const (
22+
// DefaultCleanupInterval triggers cache cleanup (lazy eviction) at this interval.
23+
DefaultCleanupInterval = 1 * time.Minute
24+
)

pkg/providers/instancetype/instancetype.go

+64-15
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,26 @@ package instancetype
1616

1717
import (
1818
"context"
19+
"errors"
20+
"fmt"
1921
"net/http"
22+
"sync"
23+
"time"
2024

21-
"sigs.k8s.io/controller-runtime/pkg/client"
25+
compute "cloud.google.com/go/compute/apiv1"
26+
"cloud.google.com/go/compute/apiv1/computepb"
27+
"github.com/patrickmn/go-cache"
28+
"google.golang.org/api/iterator"
2229
"sigs.k8s.io/karpenter/pkg/cloudprovider"
2330

2431
"github.com/cloudpilot-ai/karpenter-provider-gcp/pkg/apis/v1alpha1"
32+
"github.com/cloudpilot-ai/karpenter-provider-gcp/pkg/auth"
33+
pkgcache "github.com/cloudpilot-ai/karpenter-provider-gcp/pkg/cache"
34+
)
35+
36+
const (
37+
InstanceTypesCacheKey = "gce-instancetypes"
38+
InstanceTypesCacheTTL = 23 * time.Hour
2539
)
2640

2741
type Provider interface {
@@ -32,33 +46,68 @@ type Provider interface {
3246
}
3347

3448
type DefaultProvider struct {
35-
region string
36-
kubeClient client.Client
49+
authOptions *auth.Credential
50+
vmTypesClient *compute.MachineTypesClient
51+
52+
muCache sync.Mutex
53+
cache *cache.Cache
3754
}
3855

39-
func NewProvider(kubeClient client.Client, region string) *DefaultProvider {
40-
return &DefaultProvider{
41-
kubeClient: kubeClient,
42-
region: region,
56+
func NewProvider(region string, authOptions *auth.Credential) (*DefaultProvider, error) {
57+
vmTypesClient, err := compute.NewMachineTypesRESTClient(context.Background(), authOptions.CredentialOptions)
58+
if err != nil {
59+
return nil, err
4360
}
61+
return &DefaultProvider{
62+
authOptions: authOptions,
63+
vmTypesClient: vmTypesClient,
64+
cache: cache.New(InstanceTypesCacheTTL, pkgcache.DefaultCleanupInterval),
65+
}, nil
4466
}
4567

4668
func (p *DefaultProvider) LivenessProbe(*http.Request) error {
4769
// TODO: Implement me
4870
return nil
4971
}
5072

51-
func (p *DefaultProvider) List(ctx context.Context, kubeletConfiguration *v1alpha1.KubeletConfiguration, nodeClass *v1alpha1.GCENodeClass) ([]*cloudprovider.InstanceType, error) {
73+
func (p *DefaultProvider) List(ctx context.Context, kc *v1alpha1.KubeletConfiguration, nodeClass *v1alpha1.GCENodeClass) ([]*cloudprovider.InstanceType, error) {
5274
// TODO: Implement me
75+
p.muCache.Lock()
76+
defer p.muCache.Unlock()
77+
5378
return nil, nil
5479
}
5580

56-
func (p *DefaultProvider) UpdateInstanceTypes(ctx context.Context) error {
57-
// TODO: Implement me
58-
return nil
59-
}
81+
func (p *DefaultProvider) getInstanceTypes(ctx context.Context) ([]*computepb.MachineType, error) {
82+
p.muCache.Lock()
83+
defer p.muCache.Unlock()
6084

61-
func (p *DefaultProvider) UpdateInstanceTypeOfferings(ctx context.Context) error {
62-
// TODO: Implement me
63-
return nil
85+
if cached, ok := p.cache.Get(InstanceTypesCacheKey); ok {
86+
return cached.([]*computepb.MachineType), nil
87+
}
88+
89+
vmFilter := fmt.Sprintf("(zone eq .*%s-.*)", p.authOptions.Region)
90+
req := &computepb.AggregatedListMachineTypesRequest{
91+
Project: p.authOptions.ProjectID,
92+
Filter: &vmFilter,
93+
}
94+
95+
it := p.vmTypesClient.AggregatedList(ctx, req)
96+
97+
var vmTypes []*computepb.MachineType
98+
for {
99+
resp, err := it.Next()
100+
if errors.Is(err, iterator.Done) {
101+
break
102+
}
103+
104+
if err != nil {
105+
return nil, err
106+
}
107+
108+
vmTypes = append(vmTypes, resp.Value.MachineTypes...)
109+
}
110+
111+
p.cache.SetDefault(InstanceTypesCacheKey, vmTypes)
112+
return vmTypes, nil
64113
}

0 commit comments

Comments
 (0)