Repository: getsops/sops (language: python)

Issue:
Improve Make targets and address various issues
This improves the `Makefile` a bit more, while still not being picture perfect. Things that could still use some love:

- Testing keys should really not pollute the user their GnuPG home directory, but rather be e.g. imported to some project specific key ring.
- Binary for functional tests should not be stored in `./functional-tests/sops`. But instead put in `./bin/sops`, from where it would be used instead (while building using GoReleaser to match release build?)


Discussion / hints:

Fix patch:
diff --git a/aes/cipher.go b/aes/cipher.go
index d4ad74add..291f2fedf 100644
--- a/aes/cipher.go
+++ b/aes/cipher.go
@@ -11,11 +11,10 @@ import (
 	"fmt"
 	"regexp"
 	"strconv"
-	"strings"
 
-	"github.com/sirupsen/logrus"
 	"github.com/getsops/sops/v3"
 	"github.com/getsops/sops/v3/logging"
+	"github.com/sirupsen/logrus"
 )
 
 var log *logrus.Logger
@@ -172,7 +171,11 @@ func (c Cipher) Encrypt(plaintext interface{}, key []byte, additionalData string
 	case bool:
 		encryptedType = "bool"
 		// The Python version encodes booleans with Titlecase
-		plainBytes = []byte(strings.Title(strconv.FormatBool(value)))
+		if value {
+			plainBytes = []byte("True")
+		} else {
+			plainBytes = []byte("False")
+		}
 	case sops.Comment:
 		encryptedType = "comment"
 		plainBytes = []byte(value.Value)
diff --git a/cmd/sops/main.go b/cmd/sops/main.go
index 35dc5527f..50ec20355 100644
--- a/cmd/sops/main.go
+++ b/cmd/sops/main.go
@@ -1,6 +1,7 @@
 package main //import "github.com/getsops/sops/v3/cmd/sops"
 
 import (
+	"context"
 	encodingjson "encoding/json"
 	"fmt"
 	"net"
@@ -11,10 +12,7 @@ import (
 	"reflect"
 	"strconv"
 	"strings"
-	"time"
 
-	"github.com/sirupsen/logrus"
-	"github.com/urfave/cli"
 	"github.com/getsops/sops/v3"
 	"github.com/getsops/sops/v3/aes"
 	"github.com/getsops/sops/v3/age"
@@ -38,7 +36,10 @@ import (
 	"github.com/getsops/sops/v3/stores/dotenv"
 	"github.com/getsops/sops/v3/stores/json"
 	"github.com/getsops/sops/v3/version"
+	"github.com/sirupsen/logrus"
+	"github.com/urfave/cli"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials/insecure"
 )
 
 var log *logrus.Logger
@@ -1029,10 +1030,12 @@ func keyservices(c *cli.Context) (svcs []keyservice.KeyServiceClient) {
 			addr = url.Path
 		}
 		opts := []grpc.DialOption{
-			grpc.WithInsecure(),
-			grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
-				return net.DialTimeout(url.Scheme, addr, timeout)
-			}),
+			grpc.WithTransportCredentials(insecure.NewCredentials()),
+			grpc.WithContextDialer(
+				func(ctx context.Context, addr string) (net.Conn, error) {
+					return (&net.Dialer{}).DialContext(ctx, url.Scheme, addr)
+				},
+			),
 		}
 		log.WithField(
 			"address",
diff --git a/keyservice/server.go b/keyservice/server.go
index 85829621a..9f2b486a6 100644
--- a/keyservice/server.go
+++ b/keyservice/server.go
@@ -10,7 +10,6 @@ import (
 	"github.com/getsops/sops/v3/kms"
 	"github.com/getsops/sops/v3/pgp"
 	"golang.org/x/net/context"
-	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 )
@@ -239,7 +238,7 @@ func (ks Server) prompt(key *Key, requestType string) error {
 		}
 	}
 	if response == "n" {
-		return grpc.Errorf(codes.PermissionDenied, "Request rejected by user")
+		return status.Errorf(codes.PermissionDenied, "Request rejected by user")
 	}
 	return nil
 }
@@ -300,9 +299,9 @@ func (ks Server) Decrypt(ctx context.Context,
 			Plaintext: plaintext,
 		}
 	case nil:
-		return nil, grpc.Errorf(codes.NotFound, "Must provide a key")
+		return nil, status.Errorf(codes.NotFound, "Must provide a key")
 	default:
-		return nil, grpc.Errorf(codes.NotFound, "Unknown key type")
+		return nil, status.Errorf(codes.NotFound, "Unknown key type")
 	}
 	if ks.Prompt {
 		err := ks.prompt(key, "decrypt")
diff --git a/kms/keysource.go b/kms/keysource.go
index 09a26a326..47c369b36 100644
--- a/kms/keysource.go
+++ b/kms/keysource.go
@@ -70,11 +70,11 @@ type MasterKey struct {
 	// using CredentialsProvider.ApplyToMasterKey. If nil, the default client is used
 	// which utilizes runtime environmental values.
 	credentialsProvider aws.CredentialsProvider
-	// epResolver can be used to override the endpoint the AWS client resolves
+	// baseEndpoint can be used to override the endpoint the AWS client resolves
 	// to by default. This is mostly used for testing purposes as it can not be
 	// injected using e.g. an environment variable. The field is not publicly
 	// exposed, nor configurable.
-	epResolver aws.EndpointResolverWithOptions
+	baseEndpoint string
 }
 
 // NewMasterKey creates a new MasterKey from an ARN, role and context, setting
@@ -197,7 +197,7 @@ func (key *MasterKey) Encrypt(dataKey []byte) error {
 		log.WithField("arn", key.Arn).Error("Encryption failed")
 		return err
 	}
-	client := kms.NewFromConfig(*cfg)
+	client := key.createClient(cfg)
 	input := &kms.EncryptInput{
 		KeyId:             &key.Arn,
 		Plaintext:         dataKey,
@@ -245,7 +245,7 @@ func (key *MasterKey) Decrypt() ([]byte, error) {
 		log.WithField("arn", key.Arn).Error("Decryption failed")
 		return nil, err
 	}
-	client := kms.NewFromConfig(*cfg)
+	client := key.createClient(cfg)
 	input := &kms.DecryptInput{
 		KeyId:             &key.Arn,
 		CiphertextBlob:    k,
@@ -309,11 +309,6 @@ func (key MasterKey) createKMSConfig() (*aws.Config, error) {
 			lo.SharedConfigProfile = key.AwsProfile
 		}
 		lo.Region = region
-
-		// Set the epResolver, if present. Used ONLY for tests.
-		if key.epResolver != nil {
-			lo.EndpointResolverWithOptions = key.epResolver
-		}
 		return nil
 	})
 	if err != nil {
@@ -326,6 +321,15 @@ func (key MasterKey) createKMSConfig() (*aws.Config, error) {
 	return &cfg, nil
 }
 
+// createClient creates a new AWS KMS client with the provided config.
+func (key MasterKey) createClient(config *aws.Config) *kms.Client {
+	return kms.NewFromConfig(*config, func(o *kms.Options) {
+		if key.baseEndpoint != "" {
+			o.BaseEndpoint = aws.String(key.baseEndpoint)
+		}
+	})
+}
+
 // createSTSConfig uses AWS STS to assume a role and returns a config
 // configured with that role's credentials. It returns an error if
 // it fails to construct a session name, or assume the role.
diff --git a/sops.go b/sops.go
index 71b08f23e..ae0ecfc24 100644
--- a/sops.go
+++ b/sops.go
@@ -46,12 +46,12 @@ import (
 	"strings"
 	"time"
 
-	"github.com/sirupsen/logrus"
 	"github.com/getsops/sops/v3/audit"
 	"github.com/getsops/sops/v3/keys"
 	"github.com/getsops/sops/v3/keyservice"
 	"github.com/getsops/sops/v3/logging"
 	"github.com/getsops/sops/v3/shamir"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -727,7 +727,11 @@ func ToBytes(in interface{}) ([]byte, error) {
 	case float64:
 		return []byte(strconv.FormatFloat(in, 'f', -1, 64)), nil
 	case bool:
-		return []byte(strings.Title(strconv.FormatBool(in))), nil
+		boolB := []byte("True")
+		if !in {
+			boolB = []byte("False")
+		}
+		return boolB, nil
 	case []byte:
 		return in, nil
 	case Comment:


Test patch:
diff --git a/gcpkms/keysource_test.go b/gcpkms/keysource_test.go
index 2904eb34b..153bfb260 100644
--- a/gcpkms/keysource_test.go
+++ b/gcpkms/keysource_test.go
@@ -7,9 +7,10 @@ import (
 	"testing"
 	"time"
 
+	"cloud.google.com/go/kms/apiv1/kmspb"
 	"github.com/stretchr/testify/assert"
-	kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials/insecure"
 )
 
 var (
@@ -158,7 +159,7 @@ func newGRPCServer(port string) *grpc.ClientConn {
 	}
 	go serv.Serve(lis)
 
-	conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure())
+	conn, err := grpc.Dial(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))
 	if err != nil {
 		log.Fatal(err)
 	}
diff --git a/gcpkms/mock_kms_server_test.go b/gcpkms/mock_kms_server_test.go
index 91b474747..bd2f30d60 100644
--- a/gcpkms/mock_kms_server_test.go
+++ b/gcpkms/mock_kms_server_test.go
@@ -23,12 +23,11 @@ import (
 	"io"
 	"strings"
 
-	kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
-	"google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/types/known/anypb"
-
+	"cloud.google.com/go/kms/apiv1/kmspb"
 	"google.golang.org/genproto/googleapis/rpc/status"
 	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/types/known/anypb"
 )
 
 var _ = io.EOF
diff --git a/kms/keysource_test.go b/kms/keysource_test.go
index f558197ea..81cd9bbd8 100644
--- a/kms/keysource_test.go
+++ b/kms/keysource_test.go
@@ -549,7 +549,7 @@ func createTestMasterKey(arn string) MasterKey {
 	return MasterKey{
 		Arn:                 arn,
 		credentialsProvider: credentials.NewStaticCredentialsProvider("id", "secret", ""),
-		epResolver:          epResolver{},
+		baseEndpoint:        testKMSServerURL,
 	}
 }
 
@@ -560,16 +560,7 @@ func createTestKMSClient(key MasterKey) (*kms.Client, error) {
 	if err != nil {
 		return nil, err
 	}
-	cfg.EndpointResolverWithOptions = epResolver{}
-	return kms.NewFromConfig(*cfg), nil
-}
-
-// epResolver is a dummy resolver that points to the local test KMS server.
-type epResolver struct{}
-
-// ResolveEndpoint always resolves to testKMSServerURL.
-func (e epResolver) ResolveEndpoint(_, _ string, _ ...interface{}) (aws.Endpoint, error) {
-	return aws.Endpoint{
-		URL: testKMSServerURL,
-	}, nil
+	return kms.NewFromConfig(*cfg, func(options *kms.Options) {
+		options.BaseEndpoint = aws.String(testKMSServerURL)
+	}), nil
 }