Skip to content

Commit

Permalink
Implement antctl agent-info
Browse files Browse the repository at this point in the history
  • Loading branch information
lzhecheng committed Jan 16, 2020
1 parent 36e5e35 commit ccf0031
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 0 deletions.
17 changes: 17 additions & 0 deletions pkg/antctl/antctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ type transformedVersionResponse struct {
AntctlVersion string `json:"antctlVersion" yaml:"antctlVersion"`
}

type transformedAgentInfoResponse struct {
handlers.ComponentAgentInfoResponse `json:",inline" yaml:",inline"`
}

// versionTransform is the AddonTransform for the version command. This function
// will try to parse the response as a ComponentVersionResponse and then populate
// it with the version of antctl to a transformedVersionResponse object.
Expand Down Expand Up @@ -76,6 +80,19 @@ var CommandList = &commandList{
CommandGroup: flat,
AddonTransform: versionTransform,
},
{
Use: "agent-info",
Short: "Print agent's information",
Long: "Print agent's information of the antctl.",
HandlerFactory: new(handlers.AgentInfo),
GroupVersion: &systemGroup,
TransformedResponse: reflect.TypeOf(transformedAgentInfoResponse{}),
Agent: true,
Controller: false,
SingleObject: true,
CommandGroup: flat,
AddonTransform: nil,
},
},
codec: scheme.Codecs,
}
57 changes: 57 additions & 0 deletions pkg/antctl/handlers/agentinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2020 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 handlers

import (
"encoding/json"
"net/http"

"k8s.io/klog"

"github.com/vmware-tanzu/antrea/pkg/monitor"
)

var _ Factory = new(AgentInfo)

// ComponentAgentInfoResponse describes the internal response struct of agent-info command.
// It only contains agent's node subnet and connection status of controller, OVSDB and openflow.
type ComponentAgentInfoResponse struct {
ControllerConn string `json:"controllerConn,omitempty" yaml:"controllerConn,omitempty"`
OVSDBConn string `json:"ovsdbConn,omitempty" yaml:"ovsdbConn,omitempty"`
OFConn string `json:"ofConn,omitempty" yaml:"ofConn,omitempty"`
Subnet string `json:"subnet,omitempty" yaml:"subnet,omitempty"`
}

// AgentInfo is the implementation of the Factory interface for the agent-info command.
type AgentInfo struct{}

// Handler returns the function which can handle queries issued by agent-info commands,
// the handler function populate component's agnet-info to the ComponentAgentInfoResponse.
func (v *AgentInfo) Handler(aq monitor.AgentQuerier, cq monitor.ControllerQuerier) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var m ComponentAgentInfoResponse
if aq != nil {
m.ControllerConn = aq.GetControllerConnection()
m.OVSDBConn = aq.GetOVSDBConnection()
m.OFConn = aq.GetOFConnection()
m.Subnet = aq.GetNodeSubnet()
}
err := json.NewEncoder(w).Encode(m)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
klog.Errorf("Error when encoding ComponentAgentInfoResponse to json: %v", err)
}
}
}
64 changes: 64 additions & 0 deletions pkg/antctl/handlers/agentinfo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2020 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 handlers

import (
"net/http"
"net/http/httptest"
"testing"

mockmonitor "github.com/vmware-tanzu/antrea/pkg/monitor/testing"

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
)

func TestAgentInfo(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

testcases := map[string]struct {
controllerConn string
ovsdbConn string
ofConn string
subent string
expectedOutput string
expectedStatusCode int
}{
"AgentInfo": {
controllerConn: "UP",
ovsdbConn: "UP",
ofConn: "UP",
subent: "192.168.1.0/24",
expectedOutput: "{\"controllerConn\":\"UP\",\"ovsdbConn\":\"UP\",\"ofConn\":\"UP\",\"subnet\":\"192.168.1.0/24\"}\n",
expectedStatusCode: http.StatusOK,
},
}
for k, tc := range testcases {
t.Run(k, func(t *testing.T) {
req, err := http.NewRequest("GET", "/", nil)
assert.Nil(t, err)
recorder := httptest.NewRecorder()
aq := mockmonitor.NewMockAgentQuerier(ctrl)
aq.EXPECT().GetControllerConnection().Return(tc.controllerConn)
aq.EXPECT().GetOVSDBConnection().Return(tc.ovsdbConn)
aq.EXPECT().GetOFConnection().Return(tc.ofConn)
aq.EXPECT().GetNodeSubnet().Return(tc.subent)
new(AgentInfo).Handler(aq, nil).ServeHTTP(recorder, req)
assert.Equal(t, tc.expectedStatusCode, recorder.Code, k)
assert.Equal(t, tc.expectedOutput, recorder.Body.String(), k)
})
}
}
33 changes: 33 additions & 0 deletions pkg/monitor/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ type AgentQuerier interface {
Querier
GetOVSFlowTable() map[string]int32
GetLocalPodNum() int32
GetOVSDBConnection() string
GetOFConnection() string
GetControllerConnection() string
GetNodeSubnet() string
}

type ControllerQuerier interface {
Expand Down Expand Up @@ -151,6 +155,35 @@ func (monitor *agentMonitor) GetAgentConditions(ovsConnected bool) []v1beta1.Age
}
}

// GetOVSDBConnection tells if OVSDB is connected.
func (monitor *agentMonitor) GetOVSDBConnection() string {
if _, err := monitor.ovsBridgeClient.GetOVSVersion(); err != nil {
return "DOWN"
}
return "UP"
}

// GetOFConnection tells if openflow is connected.
func (monitor *agentMonitor) GetOFConnection() string {
if monitor.ofClient.IsConnected() {
return "UP"
}
return "DOWN"
}

// GetControllerConnection tells if controller is connected.
func (monitor *agentMonitor) GetControllerConnection() string {
if !monitor.networkPolicyInfoQuerier.GetControllerConnectionStatus() {
return "DOWN"
}
return "UP"
}

// GetNodeSubnet gets the node subnet.
func (monitor *agentMonitor) GetNodeSubnet() string {
return monitor.nodeSubnet
}

func (monitor *agentMonitor) GetVersion() string {
return version.GetFullVersion()
}
Expand Down
56 changes: 56 additions & 0 deletions pkg/monitor/testing/mock_monitor.go

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

0 comments on commit ccf0031

Please sign in to comment.