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

[ExternalNode] Implement SupportbundleCollection status on Controller #4249

Merged
merged 1 commit into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/antrea-controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ func createAPIServerConfig(kubeconfig string,

secureServing.BindPort = bindPort
secureServing.BindAddress = net.IPv4zero
// kubeconfig file is useful when antrea-controller isn't not running as a pod, like during development.
// kubeconfig file is useful when antrea-controller is not running as a pod, like during development.
if len(kubeconfig) > 0 {
authentication.RemoteKubeConfigFile = kubeconfig
authorization.RemoteKubeConfigFile = kubeconfig
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/crd/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ type SupportBundleCollectionSpec struct {

type SupportBundleCollectionStatus struct {
// The number of Nodes and ExternalNodes that have completed the SupportBundleCollection.
SucceededNodes int32 `json:"succeededNodes"`
CollectedNodes int32 `json:"collectedNodes"`
// The total number of Nodes and ExternalNodes that should process the SupportBundleCollection.
DesiredNodes int32 `json:"desiredNodes"`
// Represents the latest available observations of a SupportBundleCollection current state.
Expand Down
2 changes: 2 additions & 0 deletions pkg/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ func installAPIGroup(s *APIServer, c completedConfig) error {
nodeStatsSummaryStorage := nodestatssummary.NewREST(c.extraConfig.statsAggregator)
egressGroupStorage := egressgroup.NewREST(c.extraConfig.egressGroupStore)
bundleCollectionStorage := supportbundlecollection.NewREST(c.extraConfig.bundleCollectionStore)
bundleCollectionStatusStorage := supportbundlecollection.NewStatusREST(c.extraConfig.bundleCollectionController)
cpGroup := genericapiserver.NewDefaultAPIGroupInfo(controlplane.GroupName, Scheme, parameterCodec, Codecs)
cpv1beta2Storage := map[string]rest.Storage{}
cpv1beta2Storage["addressgroups"] = addressGroupStorage
Expand All @@ -192,6 +193,7 @@ func installAPIGroup(s *APIServer, c completedConfig) error {
cpv1beta2Storage["clustergroupmembers"] = clusterGroupMembershipStorage
cpv1beta2Storage["egressgroups"] = egressGroupStorage
cpv1beta2Storage["supportbundlecollections"] = bundleCollectionStorage
cpv1beta2Storage["supportbundlecollections/status"] = bundleCollectionStatusStorage
cpGroup.VersionedResourcesStorageMap["v1beta2"] = cpv1beta2Storage

systemGroup := genericapiserver.NewDefaultAPIGroupInfo(system.GroupName, Scheme, metav1.ParameterCodec, Codecs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
"antrea.io/antrea/pkg/controller/types"
)

// REST implements rest.Storage for NetworkPolicies.
// REST implements rest.Storage for SupportBundleCollections.
type REST struct {
supportBundleCollectionStore storage.Interface
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2022 Antrea Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package supportbundlecollection

import (
"context"
"fmt"

"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"

"antrea.io/antrea/pkg/apis/controlplane"
)

// StatusREST implements the REST endpoint for updating SupportBundleCollection's status.
type StatusREST struct {
collector statusCollector
}

// NewStatusREST returns a REST object that will work against API services.
func NewStatusREST(collector statusCollector) *StatusREST {
return &StatusREST{collector}
}

// statusCollector is the interface required by the handler.
type statusCollector interface {
UpdateStatus(status *controlplane.SupportBundleCollectionStatus) error
}

var _ rest.NamedCreater = &StatusREST{}

func (s StatusREST) New() runtime.Object {
return &controlplane.SupportBundleCollectionStatus{}
}

func (s StatusREST) Create(ctx context.Context, name string, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
status, ok := obj.(*controlplane.SupportBundleCollectionStatus)
if !ok {
return nil, errors.NewBadRequest(fmt.Sprintf("not a SupportBundleCollectionStatus object: %T", obj))
}
if name != status.Name {
return nil, errors.NewBadRequest("name in URL does not match name in SupportBundleCollectionStatus object")
}
err := s.collector.UpdateStatus(status)
if err != nil {
return nil, err
}
return &metav1.Status{Status: metav1.StatusSuccess}, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Copyright 2022 Antrea Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package supportbundlecollection

import (
"context"
"fmt"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"

"antrea.io/antrea/pkg/apis/controlplane"
)

func TestCreate(t *testing.T) {
for _, tc := range []struct {
name string
obj runtime.Object
expError error
}{
{
name: "invalid-status-type",
obj: runtime.Object(&controlplane.SupportBundleCollection{
ObjectMeta: metav1.ObjectMeta{
Name: "invalid-status-type",
},
}),
expError: errors.NewBadRequest("not a SupportBundleCollectionStatus object"),
},
{
name: "invalid-status-name",
obj: runtime.Object(&controlplane.SupportBundleCollectionStatus{
ObjectMeta: metav1.ObjectMeta{
Name: "invalid-name",
},
}),
expError: errors.NewBadRequest("name in URL does not match name in SupportBundleCollectionStatus object"),
},
{
name: "unable-update",
obj: runtime.Object(&controlplane.SupportBundleCollectionStatus{
ObjectMeta: metav1.ObjectMeta{
Name: "unable-update",
},
}),
expError: fmt.Errorf("no Nodes status is updated"),
},
{
name: "valid-status-update",
obj: runtime.Object(&controlplane.SupportBundleCollectionStatus{
ObjectMeta: metav1.ObjectMeta{
Name: "valid-status-update",
},
Nodes: []controlplane.SupportBundleCollectionNodeStatus{
{
NodeName: "n1",
NodeType: "Node",
},
},
}),
expError: nil,
},
} {
statusController := &fakeStatusCollector{
bundleCollectionStatuses: make(map[string]*controlplane.SupportBundleCollectionStatus),
}
r := NewStatusREST(statusController)
rsp, err := r.Create(context.TODO(), tc.name, tc.obj, nil, &metav1.CreateOptions{})
if tc.expError == nil {
assert.NoError(t, err)
assert.Equal(t, &metav1.Status{Status: metav1.StatusSuccess}, rsp)
expStatus := tc.obj.(*controlplane.SupportBundleCollectionStatus)
status := statusController.bundleCollectionStatuses[tc.name]
assert.Equal(t, expStatus, status)
} else {
assert.Error(t, err)
assert.True(t, strings.Contains(err.Error(), tc.expError.Error()))
}
}
}

type fakeStatusCollector struct {
bundleCollectionStatuses map[string]*controlplane.SupportBundleCollectionStatus
}

func (c *fakeStatusCollector) UpdateStatus(status *controlplane.SupportBundleCollectionStatus) error {
bundleCollectionName := status.Name
if len(status.Nodes) == 0 {
return fmt.Errorf("no Nodes status is updated")
}
c.bundleCollectionStatuses[bundleCollectionName] = status
return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2022 Antrea Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fake

import (
"context"

"antrea.io/antrea/pkg/apis/controlplane/v1beta2"
)

func (c *FakeSupportBundleCollections) UpdateStatus(ctx context.Context, name string, status *v1beta2.SupportBundleCollectionStatus) error {
return nil
}

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2022 Antrea Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package v1beta2

import (
"context"

"antrea.io/antrea/pkg/apis/controlplane/v1beta2"
)

type SupportBundleCollectionExpansion interface {
UpdateStatus(ctx context.Context, name string, status *v1beta2.SupportBundleCollectionStatus) error
}

func (c *supportBundleCollections) UpdateStatus(ctx context.Context, name string, status *v1beta2.SupportBundleCollectionStatus) error {
return c.client.Post().Resource("supportbundlecollections").Name(name).SubResource("status").Body(status).Do(ctx).Error()
}
Loading