Select Git revision
collector.go
-
Schneider, Angelika authoredSchneider, Angelika authored
collector.go 6.99 KiB
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019-2022 Fraunhofer AISEC
//
// 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.
//
// $$\ $$\ $$$$$$$$\ $$$$$$$\ $$$$$$\ $$\ $$\ $$$$$$\
// $$$\ $$$ |$$ _____|$$ __$$\ \_$$ _|$$$\ $$ |$$ __$$\
// $$$$\ $$$$ |$$ | $$ | $$ | $$ | $$$$\ $$ |$$ / $$ |
// $$\$$\$$ $$ |$$$$$\ $$ | $$ | $$ | $$ $$\$$ |$$$$$$$$ |
// $$ \$$$ $$ |$$ __| $$ | $$ | $$ | $$ \$$$$ |$$ __$$ |
// $$ |\$ /$$ |$$ | $$ | $$ | $$ | $$ |\$$$ |$$ | $$ |
// $$ | \_/ $$ |$$$$$$$$\ $$$$$$$ |$$$$$$\ $$ | \$$ |$$ | $$ |
// \__| \__|\________|\_______/ \______|\__| \__|\__| \__|
//
// This file is part of the MEDINA Framework.
package main
import (
"collector"
"context"
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"os"
"clouditor.io/clouditor/api/discovery"
"clouditor.io/clouditor/logging/formatter"
"clouditor.io/clouditor/rest"
"clouditor.io/clouditor/service"
service_discovery "clouditor.io/clouditor/service/discovery"
"clouditor.io/clouditor/voc"
structpb "github.com/golang/protobuf/ptypes/struct"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags"
"github.com/sirupsen/logrus"
"golang.org/x/oauth2/clientcredentials"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
var (
log *logrus.Entry
server *grpc.Server
discoveryService discovery.DiscoveryServer
assessmentUrl string
jwksURL string
config clientcredentials.Config
)
const (
grpcPort = 9091
httpPort = 8081
AssessmentUrl = "ASSESSMENT_URL"
DefaultAssessmentURL = "localhost:9092"
OAuth2ClientID = "OAUTH2_CLIENT_ID"
OAuth2ClientSecret = "OAUTH2_CLIENT_SECRET"
OAuth2TokenURL = "OAUTH2_TOKEN_URL"
JWKSURL = "AUTH_JWKS_URL"
)
func toStruct(r voc.IsCloudResource) (s *structpb.Value) {
var (
b []byte
err error
)
s = new(structpb.Value)
// this is probably not the fastest approach, but this
// way, no extra libraries are needed and no extra struct tags
// except `json` are required. there is also no significant
// speed increase in marshaling the whole resource list, because
// we first need to build it out of the map anyway
if b, err = json.Marshal(r); err != nil {
return
}
if err = json.Unmarshal(b, &s); err != nil {
return
}
return
}
func init() {
log = logrus.WithField("component", "grpc")
logrus.SetLevel(logrus.DebugLevel)
// Get URL for Clouditor Assessment from env var
var ok bool
assessmentUrl, ok = os.LookupEnv(AssessmentUrl)
if !ok {
// If no environment variable available set to default
assessmentUrl = DefaultAssessmentURL
}
// Get the JWKS URL of our auth server
jwksURL, _ = os.LookupEnv(JWKSURL)
// Get the OAuth credentials
config = clientcredentials.Config{}
config.ClientID, _ = os.LookupEnv(OAuth2ClientID)
config.ClientSecret, _ = os.LookupEnv(OAuth2ClientSecret)
config.TokenURL, _ = os.LookupEnv(OAuth2TokenURL)
}
func main() {
var textFormatter = logrus.TextFormatter{ForceColors: false, FullTimestamp: true}
log.Logger.Formatter = &textFormatter
fmt.Printf(`
$$\ $$\ $$$$$$$$\ $$$$$$$\ $$$$$$\ $$\ $$\ $$$$$$\
$$$\ $$$ |$$ _____|$$ __$$\ \_$$ _|$$$\ $$ |$$ __$$\
$$$$\ $$$$ |$$ | $$ | $$ | $$ | $$$$\ $$ |$$ / $$ |
$$\$$\$$ $$ |$$$$$\ $$ | $$ | $$ | $$ $$\$$ |$$$$$$$$ |
$$ \$$$ $$ |$$ __| $$ | $$ | $$ | $$ \$$$$ |$$ __$$ |
$$ |\$ /$$ |$$ | $$ | $$ | $$ | $$ |\$$$ |$$ | $$ |
$$ | \_/ $$ |$$$$$$$$\ $$$$$$$ |$$$$$$\ $$ | \$$ |$$ | $$ |
\__| \__|\________|\_______/ \______|\__| \__|\__| \__|
Evidence Collector 1.1 based on Clouditor framework %s
`, collector.ClouditorVersion())
log.Infof("Security Assessment URL is set to %s", assessmentUrl)
discoveryService = service_discovery.NewService(
service_discovery.WithOAuth2Authorizer(&config),
service_discovery.WithProviders([]string{service_discovery.ProviderAzure}),
service_discovery.WithAssessmentAddress(assessmentUrl),
)
// Comment in if evidence collector should collect the evidences from the CSPs. Otherwise, example evidences are used.
//Start evidence collector
_, err := discoveryService.Start(context.Background(), &discovery.StartDiscoveryRequest{})
if err != nil {
log.Errorf("could not collect evidences: %v", err)
}
grpcLogger := logrus.New()
grpcLogger.Formatter = &formatter.GRPCFormatter{TextFormatter: textFormatter}
grpcLoggerEntry := grpcLogger.WithField("component", "grpc")
// create a new socket for gRPC communication
sock, err := net.Listen("tcp", fmt.Sprintf(":%d", grpcPort))
if err != nil {
log.Errorf("could not listen: %v", err)
}
authConfig := service.ConfigureAuth(service.WithJWKSURL(jwksURL))
defer authConfig.Jwks.EndBackground()
server = grpc.NewServer(
grpc_middleware.WithUnaryServerChain(
grpc_ctxtags.UnaryServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)),
grpc_logrus.UnaryServerInterceptor(grpcLoggerEntry),
grpc_auth.UnaryServerInterceptor(authConfig.AuthFunc),
),
grpc_middleware.WithStreamServerChain(
grpc_ctxtags.StreamServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)),
grpc_logrus.StreamServerInterceptor(grpcLoggerEntry),
grpc_auth.StreamServerInterceptor(authConfig.AuthFunc),
))
discovery.RegisterDiscoveryServer(server, discoveryService)
// enable reflection, primary for testing in early stages
reflection.Register(server)
// start the gRPC-HTTP gateway
go func() {
err = rest.RunServer(context.Background(), grpcPort, httpPort)
if errors.Is(err, http.ErrServerClosed) {
os.Exit(0)
return
}
if err != nil {
log.Fatalf("failed to serve gRPC-HTTP gateway: %v", err)
}
}()
log.Infof("Starting gRPC endpoint on :%d", grpcPort)
// serve the gRPC socket
if err := server.Serve(sock); err != nil {
log.Infof("failed to serve gRPC endpoint: %s", err)
return
}
}