shim-mgmt: Add endpoint handler for interacting with iptables

Add two endpoints: ip6tables, iptables.

Each url handler supports GET and PUT operations. PUT expects
the requests' data to be []bytes, and to contain iptable information in
format to be consumed by iptables-restore.

Signed-off-by: Eric Ernst <eric_ernst@apple.com>
This commit is contained in:
Eric Ernst 2022-04-25 04:31:25 -07:00
parent 0136be22ca
commit 640173cfc2

View File

@ -29,6 +29,7 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go" dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt" "github.com/prometheus/common/expfmt"
"github.com/sirupsen/logrus"
) )
const ( const (
@ -36,6 +37,8 @@ const (
DirectVolumeStatUrl = "/direct-volume/stats" DirectVolumeStatUrl = "/direct-volume/stats"
DirectVolumeResizeUrl = "/direct-volume/resize" DirectVolumeResizeUrl = "/direct-volume/resize"
IPTablesUrl = "/iptables"
IP6TablesUrl = "/ip6tables"
) )
var ( var (
@ -195,6 +198,48 @@ func (s *service) serveVolumeResize(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("")) w.Write([]byte(""))
} }
func (s *service) ip6TablesHandler(w http.ResponseWriter, r *http.Request) {
s.genericIPTablesHandler(w, r, true)
}
func (s *service) ipTablesHandler(w http.ResponseWriter, r *http.Request) {
s.genericIPTablesHandler(w, r, false)
}
func (s *service) genericIPTablesHandler(w http.ResponseWriter, r *http.Request, isIPv6 bool) {
logger := shimMgtLog.WithFields(logrus.Fields{"handler": "iptables", "ipv6": isIPv6})
switch r.Method {
case http.MethodPut:
body, err := ioutil.ReadAll(r.Body)
if err != nil {
logger.WithError(err).Error("failed to read request body")
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
if err = s.sandbox.SetIPTables(context.Background(), isIPv6, body); err != nil {
logger.WithError(err).Error("failed to set IPTables")
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
}
w.Write([]byte(""))
case http.MethodGet:
buf, err := s.sandbox.GetIPTables(context.Background(), isIPv6)
if err != nil {
logger.WithError(err).Error("failed to get IPTables")
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
}
w.Write(buf)
default:
w.WriteHeader(http.StatusNotImplemented)
return
}
}
func (s *service) startManagementServer(ctx context.Context, ociSpec *specs.Spec) { func (s *service) startManagementServer(ctx context.Context, ociSpec *specs.Spec) {
// metrics socket will under sandbox's bundle path // metrics socket will under sandbox's bundle path
metricsAddress := SocketAddress(s.id) metricsAddress := SocketAddress(s.id)
@ -219,6 +264,8 @@ func (s *service) startManagementServer(ctx context.Context, ociSpec *specs.Spec
m.Handle("/agent-url", http.HandlerFunc(s.agentURL)) m.Handle("/agent-url", http.HandlerFunc(s.agentURL))
m.Handle(DirectVolumeStatUrl, http.HandlerFunc(s.serveVolumeStats)) m.Handle(DirectVolumeStatUrl, http.HandlerFunc(s.serveVolumeStats))
m.Handle(DirectVolumeResizeUrl, http.HandlerFunc(s.serveVolumeResize)) m.Handle(DirectVolumeResizeUrl, http.HandlerFunc(s.serveVolumeResize))
m.Handle(IPTablesUrl, http.HandlerFunc(s.ipTablesHandler))
m.Handle(IP6TablesUrl, http.HandlerFunc(s.ip6TablesHandler))
s.mountPprofHandle(m, ociSpec) s.mountPprofHandle(m, ociSpec)
// register shim metrics // register shim metrics