Skip to content

Commit b64fa46

Browse files
committed
latest changes
1 parent f5a693f commit b64fa46

20 files changed

+614
-334
lines changed

Diff for: Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ crds: $(CONTROLLER_GEN)
265265
paths=./api/... \
266266
paths=./controllers/... \
267267
paths=./tink/api/... \
268-
paths=./tink/controllers/... \
268+
paths=./tink/internal/controllers/... \
269269
crd:crdVersions=v1 \
270270
rbac:roleName=manager-role \
271271
output:crd:dir=./config/crd/bases \

Diff for: config/crd/bases/tinkerbell.org_hardware.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ spec:
3333
type: object
3434
spec:
3535
description: HardwareSpec defines the desired state of Hardware.
36+
properties:
37+
id:
38+
description: ID is the ID of the hardware in Tinkerbell
39+
minLength: 1
40+
type: string
41+
required:
42+
- id
3643
type: object
3744
status:
3845
description: HardwareStatus defines the observed state of Hardware.

Diff for: go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ go 1.15
44

55
require (
66
github.com/go-logr/logr v0.1.0
7+
github.com/google/uuid v1.1.2
78
github.com/onsi/gomega v1.10.1
89
github.com/tinkerbell/tink v0.0.0-20201210163923-6d9159b63857
910
google.golang.org/grpc v1.32.0
11+
google.golang.org/protobuf v1.25.0
1012
k8s.io/api v0.17.14
1113
k8s.io/apimachinery v0.17.14
1214
k8s.io/client-go v0.17.14

Diff for: tink/api/v1alpha1/hardware_types.go

+3-8
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,11 @@ import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2121
)
2222

23-
const (
24-
// HardwareIDAnnotation is used by the controller to store the
25-
// ID assigned to the hardware by Tinkerbell.
26-
HardwareIDAnnotation = "hardware.tinkerbell.org/id"
27-
28-
HardwareFinalizer = "hardware.tinkerbell.org"
29-
)
30-
3123
// HardwareSpec defines the desired state of Hardware.
3224
type HardwareSpec struct {
25+
// ID is the ID of the hardware in Tinkerbell
26+
// +kubebuilder:validation:MinLength=1
27+
ID string `json:"id"`
3328
}
3429

3530
// HardwareStatus defines the observed state of Hardware.

Diff for: tink/internal/client/common.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ import (
2525
var ErrNotFound = errors.New("resource not found")
2626

2727
// TODO: Tinkerbell should return some type of status that is easier to handle
28-
// than parsing for this specific error message.
28+
// than parsing for these specific error message.
2929
const sqlErrorString = "rpc error: code = Unknown desc = sql: no rows in result set"
30+
const sqlErrorStringAlt = "rpc error: code = Unknown desc = SELECT: sql: no rows in result set"

Diff for: tink/internal/client/fake/hardware.go

+56-6
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ package fake
1919

2020
import (
2121
"context"
22+
"errors"
2223

24+
"github.com/google/uuid"
2325
"github.com/tinkerbell/cluster-api-provider-tinkerbell/tink/internal/client"
2426
"github.com/tinkerbell/tink/protos/hardware"
27+
"google.golang.org/protobuf/proto"
2528
)
2629

2730
// Hardware is a fake client for Tinkerbell Hardwares.
@@ -33,18 +36,65 @@ type Hardware struct {
3336
func NewFakeHardwareClient(objs ...*hardware.Hardware) *Hardware {
3437
f := &Hardware{Objs: map[string]*hardware.Hardware{}}
3538

36-
for i, obj := range objs {
37-
f.Objs[obj.GetId()] = objs[i]
39+
for _, obj := range objs {
40+
if obj.GetId() == "" {
41+
obj.Id = uuid.New().String()
42+
}
43+
44+
f.Objs[obj.Id] = proto.Clone(obj).(*hardware.Hardware)
3845
}
3946

4047
return f
4148
}
4249

50+
// Create creates a new Hardware.
51+
func (f *Hardware) Create(ctx context.Context, in *hardware.Hardware) error {
52+
if in.GetId() == "" {
53+
in.Id = uuid.New().String()
54+
}
55+
56+
if _, ok := f.Objs[in.Id]; ok {
57+
return errors.New("duplicate")
58+
}
59+
60+
f.Objs[in.Id] = proto.Clone(in).(*hardware.Hardware)
61+
62+
return nil
63+
}
64+
65+
// Update Hardware in Tinkerbell.
66+
func (f *Hardware) Update(ctx context.Context, in *hardware.Hardware) error {
67+
if _, ok := f.Objs[in.Id]; ok {
68+
f.Objs[in.Id] = proto.Clone(in).(*hardware.Hardware)
69+
70+
return nil
71+
}
72+
73+
return errors.New("nobody home")
74+
}
75+
4376
// Get gets a Hardware from Tinkerbell.
44-
func (f *Hardware) Get(ctx context.Context, id, mac, ip string) (*hardware.Hardware, error) {
45-
// TODO: need to implement fake ip and mac lookups
46-
if _, ok := f.Objs[id]; ok {
47-
return f.Objs[id], nil
77+
func (f *Hardware) Get(ctx context.Context, id, ip, mac string) (*hardware.Hardware, error) {
78+
switch {
79+
case id != "":
80+
if _, ok := f.Objs[id]; ok {
81+
return proto.Clone(f.Objs[id]).(*hardware.Hardware), nil
82+
}
83+
default:
84+
for _, hw := range f.Objs {
85+
for _, i := range hw.GetNetwork().GetInterfaces() {
86+
switch {
87+
case mac != "":
88+
if i.GetDhcp().GetMac() == mac {
89+
return proto.Clone(hw).(*hardware.Hardware), nil
90+
}
91+
case ip != "":
92+
if i.GetDhcp().GetIp().Address == ip {
93+
return proto.Clone(hw).(*hardware.Hardware), nil
94+
}
95+
}
96+
}
97+
}
4898
}
4999

50100
return nil, client.ErrNotFound

Diff for: tink/internal/client/fake/template.go

+23-32
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ import (
2121
"context"
2222
"errors"
2323

24+
"github.com/google/uuid"
2425
"github.com/tinkerbell/cluster-api-provider-tinkerbell/tink/internal/client"
2526
"github.com/tinkerbell/tink/protos/template"
27+
"google.golang.org/protobuf/proto"
2628
)
2729

2830
// Template is a fake client for Tinkerbell Templates.
@@ -34,50 +36,45 @@ type Template struct {
3436
func NewFakeTemplateClient(objs ...*template.WorkflowTemplate) *Template {
3537
f := &Template{Objs: map[string]*template.WorkflowTemplate{}}
3638

37-
for i, obj := range objs {
38-
id := obj.GetId()
39-
40-
if id == "" {
41-
obj.Id = obj.GetName()
39+
for _, obj := range objs {
40+
if obj.GetId() == "" {
41+
obj.Id = uuid.New().String()
4242
}
4343

44-
f.Objs[id] = objs[i]
44+
f.Objs[obj.Id] = proto.Clone(obj).(*template.WorkflowTemplate)
4545
}
4646

4747
return f
4848
}
4949

5050
// Create creates a new Template.
5151
func (f *Template) Create(ctx context.Context, in *template.WorkflowTemplate) error {
52-
id := in.GetId()
53-
54-
if id == "" {
55-
id = in.GetName()
52+
if in.GetId() == "" {
53+
in.Id = uuid.New().String()
5654
}
5755

58-
if _, ok := f.Objs[id]; ok {
56+
if _, ok := f.Objs[in.Id]; ok {
5957
return errors.New("duplicate")
6058
}
6159

62-
f.Objs[id] = &template.WorkflowTemplate{
63-
Id: id,
64-
Name: in.GetName(),
65-
Data: in.GetData(),
66-
}
67-
68-
in.Id = id
60+
f.Objs[in.Id] = proto.Clone(in).(*template.WorkflowTemplate)
6961

7062
return nil
7163
}
7264

7365
// Get gets a Template from Tinkerbell.
7466
func (f *Template) Get(ctx context.Context, id, name string) (*template.WorkflowTemplate, error) {
75-
if id == "" {
76-
id = name
77-
}
78-
79-
if _, ok := f.Objs[id]; ok {
80-
return f.Objs[id], nil
67+
switch {
68+
case id != "":
69+
if _, ok := f.Objs[id]; ok {
70+
return proto.Clone(f.Objs[id]).(*template.WorkflowTemplate), nil
71+
}
72+
default:
73+
for _, obj := range f.Objs {
74+
if obj.GetName() == name {
75+
return proto.Clone(obj).(*template.WorkflowTemplate), nil
76+
}
77+
}
8178
}
8279

8380
return nil, client.ErrNotFound
@@ -96,14 +93,8 @@ func (f *Template) Delete(ctx context.Context, id string) error {
9693

9794
// Update updates a Template from Tinkerbell.
9895
func (f *Template) Update(ctx context.Context, in *template.WorkflowTemplate) error {
99-
id := in.GetId()
100-
101-
if id == "" {
102-
in.Id = in.GetName()
103-
}
104-
105-
if _, ok := f.Objs[id]; ok {
106-
f.Objs[id].Data = in.GetData()
96+
if _, ok := f.Objs[in.Id]; ok {
97+
f.Objs[in.Id] = proto.Clone(in).(*template.WorkflowTemplate)
10798

10899
return nil
109100
}

Diff for: tink/internal/client/fake/workflow.go

+20-9
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,43 @@ import (
2323
"github.com/google/uuid"
2424
"github.com/tinkerbell/cluster-api-provider-tinkerbell/tink/internal/client"
2525
"github.com/tinkerbell/tink/protos/workflow"
26+
"google.golang.org/protobuf/proto"
2627
)
2728

2829
// Workflow is a fake client for Tinkerbell Workflows.
2930
type Workflow struct {
30-
Objs map[string]*workflow.Workflow
31+
Objs map[string]*workflow.Workflow
32+
hwClient Hardware
33+
templateClient Template
3134
}
3235

3336
// NewFakeWorkflowClient returns a new fake client.
34-
func NewFakeWorkflowClient(objs ...*workflow.Workflow) *Workflow {
35-
f := &Workflow{Objs: map[string]*workflow.Workflow{}}
37+
func NewFakeWorkflowClient(hwClient Hardware, templateClient Template, objs ...*workflow.Workflow) *Workflow {
38+
f := &Workflow{
39+
Objs: map[string]*workflow.Workflow{},
40+
hwClient: hwClient,
41+
templateClient: templateClient,
42+
}
43+
44+
for _, obj := range objs {
45+
if obj.GetId() == "" {
46+
obj.Id = uuid.New().String()
47+
}
3648

37-
for i, obj := range objs {
38-
f.Objs[obj.GetId()] = objs[i]
49+
f.Objs[obj.Id] = proto.Clone(obj).(*workflow.Workflow)
3950
}
4051

4152
return f
4253
}
4354

4455
// Create creates a new Workflow.
45-
func (f *Workflow) Create(ctx context.Context, template, hardware string) (string, error) {
56+
func (f *Workflow) Create(ctx context.Context, templateID, hardwareID string) (string, error) {
4657
id := uuid.New().String()
4758

4859
f.Objs[id] = &workflow.Workflow{
4960
Id: id,
50-
Template: template,
51-
Hardware: hardware,
61+
Template: templateID,
62+
Hardware: hardwareID,
5263
// TODO: populate fake Data
5364
}
5465

@@ -58,7 +69,7 @@ func (f *Workflow) Create(ctx context.Context, template, hardware string) (strin
5869
// Get gets a Workflow from Tinkerbell.
5970
func (f *Workflow) Get(ctx context.Context, id string) (*workflow.Workflow, error) {
6071
if _, ok := f.Objs[id]; ok {
61-
return f.Objs[id], nil
72+
return proto.Clone(f.Objs[id]).(*workflow.Workflow), nil
6273
}
6374

6475
return nil, client.ErrNotFound

Diff for: tink/internal/client/hardware.go

+30-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ package client
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223

24+
"github.com/google/uuid"
2325
"github.com/tinkerbell/tink/protos/hardware"
2426
"google.golang.org/grpc"
2527
)
@@ -34,6 +36,32 @@ func NewHardwareClient(client hardware.HardwareServiceClient) Hardware {
3436
return Hardware{client: client}
3537
}
3638

39+
// Create Tinkerbell Hardware.
40+
func (t *Hardware) Create(ctx context.Context, h *hardware.Hardware) error {
41+
if h == nil {
42+
return errors.New("hardware should not be nil")
43+
}
44+
45+
if h.GetId() == "" {
46+
h.Id = uuid.New().String()
47+
}
48+
49+
if _, err := t.client.Push(ctx, &hardware.PushRequest{Data: h}); err != nil {
50+
return fmt.Errorf("failed to create hardware in Tinkerbell: %w", err)
51+
}
52+
53+
return nil
54+
}
55+
56+
// Update Tinkerbell Hardware.
57+
func (t *Hardware) Update(ctx context.Context, h *hardware.Hardware) error {
58+
if _, err := t.client.Push(ctx, &hardware.PushRequest{Data: h}); err != nil {
59+
return fmt.Errorf("failed to update template in Tinkerbell: %w", err)
60+
}
61+
62+
return nil
63+
}
64+
3765
// Get returns a Tinkerbell Hardware.
3866
func (t *Hardware) Get(ctx context.Context, id, ip, mac string) (*hardware.Hardware, error) {
3967
var method func(context.Context, *hardware.GetRequest, ...grpc.CallOption) (*hardware.Hardware, error)
@@ -54,7 +82,7 @@ func (t *Hardware) Get(ctx context.Context, id, ip, mac string) (*hardware.Hardw
5482

5583
tinkHardware, err := method(ctx, req)
5684
if err != nil {
57-
if err.Error() == sqlErrorString {
85+
if err.Error() == sqlErrorString || err.Error() == sqlErrorStringAlt {
5886
return nil, fmt.Errorf("hardware %w", ErrNotFound)
5987
}
6088

@@ -67,7 +95,7 @@ func (t *Hardware) Get(ctx context.Context, id, ip, mac string) (*hardware.Hardw
6795
// Delete a Tinkerbell Hardware.
6896
func (t *Hardware) Delete(ctx context.Context, id string) error {
6997
if _, err := t.client.Delete(ctx, &hardware.DeleteRequest{Id: id}); err != nil {
70-
if err.Error() == sqlErrorString {
98+
if err.Error() == sqlErrorString || err.Error() == sqlErrorStringAlt {
7199
return fmt.Errorf("hardware %w", ErrNotFound)
72100
}
73101

Diff for: tink/internal/client/template.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func (t *Template) Get(ctx context.Context, id, name string) (*template.Workflow
4444

4545
tinkTemplate, err := t.client.GetTemplate(ctx, req)
4646
if err != nil {
47-
if err.Error() == sqlErrorString {
47+
if err.Error() == sqlErrorString || err.Error() == sqlErrorStringAlt {
4848
return nil, fmt.Errorf("template %w", ErrNotFound)
4949
}
5050

@@ -81,7 +81,7 @@ func (t *Template) Delete(ctx context.Context, id string) error {
8181
GetBy: &template.GetRequest_Id{Id: id},
8282
}
8383
if _, err := t.client.DeleteTemplate(ctx, req); err != nil {
84-
if err.Error() == sqlErrorString {
84+
if err.Error() == sqlErrorString || err.Error() == sqlErrorStringAlt {
8585
return fmt.Errorf("template %w", ErrNotFound)
8686
}
8787

0 commit comments

Comments
 (0)