-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Show correct message on NodeStatus failure (#564)
* Show correct message on NodeStatus failure
- Loading branch information
1 parent
0e63e4c
commit 26ae5d3
Showing
9 changed files
with
156 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package cmdutil | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"net/http" | ||
|
||
apiv1 "github.com/canonical/k8s/api/v1" | ||
"github.com/canonical/k8s/pkg/client/k8sd" | ||
|
||
"github.com/canonical/lxd/shared/api" | ||
) | ||
|
||
// GetNodeStatus retrieves the NodeStatus from k8sd server. If the daemon is not initialized, it exits with an error | ||
// describing that the cluster should be bootstrapped. In case of any other errors it exits and shows the error. | ||
func GetNodeStatus(ctx context.Context, client k8sd.Client, env ExecutionEnvironment) (status apiv1.NodeStatus, isBootstrapped bool, err error) { | ||
status, err = client.NodeStatus(ctx) | ||
if err == nil { | ||
return status, true, nil | ||
} | ||
|
||
if errors.As(err, &api.StatusError{}) { | ||
// the returned `ok` can be ignored since we're using errors.As() | ||
// on the same type immediately before it | ||
statusErr, _ := err.(api.StatusError) | ||
|
||
// if we get an `http.StatusServiceUnavailable` it will be (most likely) because | ||
// the handler we're trying to reach is not `AllowedBeforeInit` and hence we can understand that | ||
// the daemon is not yet initialized (this statement should be available | ||
// in the `statusErr.Error()` explicitly but for the sake of decoupling we don't rely on that) | ||
if statusErr.Status() == http.StatusServiceUnavailable { | ||
return status, false, err | ||
} | ||
} | ||
|
||
return status, true, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package cmdutil_test | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"net/http" | ||
"testing" | ||
|
||
apiv1 "github.com/canonical/k8s/api/v1" | ||
cmdutil "github.com/canonical/k8s/cmd/util" | ||
k8sdmock "github.com/canonical/k8s/pkg/client/k8sd/mock" | ||
snapmock "github.com/canonical/k8s/pkg/snap/mock" | ||
"github.com/canonical/lxd/shared/api" | ||
|
||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestGetNodeStatusUtil(t *testing.T) { | ||
type testcase struct { | ||
expIsBootstrapped bool | ||
name string | ||
nodeStatusErr error | ||
nodeStatusResult apiv1.NodeStatus | ||
} | ||
|
||
tests := []testcase{ | ||
{ | ||
name: "NoError", | ||
expIsBootstrapped: true, | ||
nodeStatusResult: apiv1.NodeStatus{ | ||
Name: "name", Address: "addr", | ||
ClusterRole: apiv1.ClusterRoleControlPlane, DatastoreRole: apiv1.DatastoreRoleVoter, | ||
}, | ||
}, | ||
{ | ||
name: "DaemonNotInitialized", | ||
nodeStatusErr: api.StatusErrorf(http.StatusServiceUnavailable, "Daemon not yet initialized"), | ||
expIsBootstrapped: false, | ||
}, | ||
{ | ||
name: "RandomError", | ||
nodeStatusErr: errors.New("something went bad"), | ||
expIsBootstrapped: true, | ||
}, | ||
{ | ||
name: "ContextCanceled", | ||
nodeStatusErr: context.Canceled, | ||
expIsBootstrapped: true, | ||
}, | ||
{ | ||
name: "ContextDeadlineExceeded", | ||
nodeStatusErr: context.DeadlineExceeded, | ||
expIsBootstrapped: true, | ||
}, | ||
} | ||
|
||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
g := NewWithT(t) | ||
|
||
var ( | ||
mockClient = &k8sdmock.Mock{ | ||
NodeStatusErr: test.nodeStatusErr, | ||
NodeStatusResult: test.nodeStatusResult, | ||
} | ||
env = cmdutil.ExecutionEnvironment{ | ||
Getuid: func() int { return 0 }, | ||
Snap: &snapmock.Snap{ | ||
Mock: snapmock.Mock{ | ||
K8sdClient: mockClient, | ||
}, | ||
}, | ||
} | ||
) | ||
|
||
status, isBootstrapped, err := cmdutil.GetNodeStatus(context.TODO(), mockClient, env) | ||
|
||
g.Expect(isBootstrapped).To(Equal(test.expIsBootstrapped)) | ||
if test.nodeStatusErr == nil { | ||
g.Expect(err).To(BeNil()) | ||
} else { | ||
g.Expect(err).To(MatchError(test.nodeStatusErr)) | ||
} | ||
|
||
if err == nil { | ||
g.Expect(status).To(Equal(test.nodeStatusResult)) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters