Skip to content

Commit

Permalink
Merge branch 'main' of github.com:letsencrypt/boulder into user-agent…
Browse files Browse the repository at this point in the history
…-in-ra
  • Loading branch information
jsha committed Jan 6, 2025
2 parents 6f89c98 + 9b3c882 commit 7137605
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 21 deletions.
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
runs-on: ubuntu-20.04
permissions:
contents: write
packages: write
steps:
- uses: actions/checkout@v4
with:
Expand Down
15 changes: 12 additions & 3 deletions sa/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,8 @@ type orderModelv1 struct {
BeganProcessing bool
}

// orderModelv2 represents one row in the orders table. The
// CertificateProfileName column is a pointer because the column is NULL-able.
type orderModelv2 struct {
ID int64
RegistrationID int64
Expand All @@ -400,7 +402,7 @@ type orderModelv2 struct {
Error []byte
CertificateSerial string
BeganProcessing bool
CertificateProfileName string
CertificateProfileName *string
}

type orderToAuthzModel struct {
Expand Down Expand Up @@ -457,14 +459,17 @@ func modelToOrderv1(om *orderModelv1) (*corepb.Order, error) {
}

func orderToModelv2(order *corepb.Order) (*orderModelv2, error) {
// Make a local copy so we can take a reference to it below.
profile := order.CertificateProfileName

om := &orderModelv2{
ID: order.Id,
RegistrationID: order.RegistrationID,
Expires: order.Expires.AsTime(),
Created: order.Created.AsTime(),
BeganProcessing: order.BeganProcessing,
CertificateSerial: order.CertificateSerial,
CertificateProfileName: order.CertificateProfileName,
CertificateProfileName: &profile,
}

if order.Error != nil {
Expand All @@ -481,14 +486,18 @@ func orderToModelv2(order *corepb.Order) (*orderModelv2, error) {
}

func modelToOrderv2(om *orderModelv2) (*corepb.Order, error) {
profile := ""
if om.CertificateProfileName != nil {
profile = *om.CertificateProfileName
}
order := &corepb.Order{
Id: om.ID,
RegistrationID: om.RegistrationID,
Expires: timestamppb.New(om.Expires),
Created: timestamppb.New(om.Created),
CertificateSerial: om.CertificateSerial,
BeganProcessing: om.BeganProcessing,
CertificateProfileName: om.CertificateProfileName,
CertificateProfileName: profile,
}
if len(om.Error) > 0 {
var problem corepb.ProblemDetails
Expand Down
2 changes: 1 addition & 1 deletion sa/sa.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ func (ssa *SQLStorageAuthority) NewOrderAndAuthzs(ctx context.Context, req *sapb
RegistrationID: req.NewOrder.RegistrationID,
Expires: req.NewOrder.Expires.AsTime(),
Created: created,
CertificateProfileName: req.NewOrder.CertificateProfileName,
CertificateProfileName: &req.NewOrder.CertificateProfileName,
}
err = tx.Insert(ctx, &omv2)
orderID = omv2.ID
Expand Down
96 changes: 80 additions & 16 deletions sa/sa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1354,29 +1354,17 @@ func TestOrderWithOrderModelv1(t *testing.T) {
}

func TestOrderWithOrderModelv2(t *testing.T) {
// This test requires the config-next db schema to run.
if !strings.Contains(os.Getenv("BOULDER_CONFIG_DIR"), "test/config-next") {
t.Skip()
}

// The feature must be set before the SA is constructed because of a
// conditional on this feature in //sa/database.go.
sa, fc, cleanup := initSA(t)
defer cleanup()

features.Set(features.Config{MultipleCertificateProfiles: true})
defer features.Reset()

fc := clock.NewFake()
fc.Set(time.Date(2015, 3, 4, 5, 0, 0, 0, time.UTC))

dbMap, err := DBMapForTest(vars.DBConnSA)
test.AssertNotError(t, err, "Couldn't create dbMap")

saro, err := NewSQLStorageAuthorityRO(dbMap, nil, metrics.NoopRegisterer, 1, 0, fc, log)
test.AssertNotError(t, err, "Couldn't create SARO")

sa, err := NewSQLStorageAuthorityWrapping(saro, dbMap, metrics.NoopRegisterer)
test.AssertNotError(t, err, "Couldn't create SA")
defer test.ResetBoulderTestDatabase(t)

// Create a test registration to reference
reg := createWorkingRegistration(t, sa)
authzExpires := fc.Now().Add(time.Hour)
authzID := createPendingAuthorization(t, sa, "example.com", authzExpires)
Expand Down Expand Up @@ -1482,6 +1470,82 @@ func TestOrderWithOrderModelv2(t *testing.T) {
test.AssertDeepEquals(t, storedOrderNoName, expectedOrderNoName)
}

func TestOrderModelMigration(t *testing.T) {
// This test requires the config-next db schema to run.
if !strings.Contains(os.Getenv("BOULDER_CONFIG_DIR"), "test/config-next") {
t.Skip()
}

sa, fc, cleanup := initSA(t)
defer cleanup()

reg := createWorkingRegistration(t, sa)

// Create an order using the v1 model
authzID := createPendingAuthorization(t, sa, "example.com", fc.Now().Add(time.Hour))
order, err := sa.NewOrderAndAuthzs(context.Background(), &sapb.NewOrderAndAuthzsRequest{
NewOrder: &sapb.NewOrderRequest{
RegistrationID: reg.Id,
Expires: timestamppb.New(fc.Now().Add(2 * time.Hour)),
DnsNames: []string{"example.com"},
V2Authorizations: []int64{authzID},
},
})
if err != nil {
t.Fatalf("failed to insert order using orderModelv1: %s", err)
}

// Retrieve that order using the v2 model
features.Set(features.Config{MultipleCertificateProfiles: true})
defer features.Reset()
storedOrder, err := sa.GetOrder(context.Background(), &sapb.OrderRequest{Id: order.Id})
if err != nil {
t.Fatalf("failed to retrieve order using orderModelv2: %s", err)
}
if storedOrder.CertificateProfileName != "" {
t.Errorf("order inserted with v1 schema should have empty profilename, instead got %q", storedOrder.CertificateProfileName)
}
}

func TestOrderModelMigrationRollback(t *testing.T) {
// This test requires the config-next db schema to run.
if !strings.Contains(os.Getenv("BOULDER_CONFIG_DIR"), "test/config-next") {
t.Skip()
}

sa, fc, cleanup := initSA(t)
defer cleanup()

reg := createWorkingRegistration(t, sa)

// Create an order using the v2 model
features.Set(features.Config{MultipleCertificateProfiles: true})
defer features.Reset()
authzID := createPendingAuthorization(t, sa, "example.com", fc.Now().Add(time.Hour))
order, err := sa.NewOrderAndAuthzs(context.Background(), &sapb.NewOrderAndAuthzsRequest{
NewOrder: &sapb.NewOrderRequest{
RegistrationID: reg.Id,
Expires: timestamppb.New(fc.Now().Add(2 * time.Hour)),
DnsNames: []string{"example.com"},
V2Authorizations: []int64{authzID},
CertificateProfileName: "asdf",
},
})
if err != nil {
t.Fatalf("failed to insert order using orderModelv2: %s", err)
}

// Retrieve that order using the v1 model
features.Reset()
storedOrder, err := sa.GetOrder(context.Background(), &sapb.OrderRequest{Id: order.Id})
if err != nil {
t.Fatalf("failed to retrieve order using orderModelv1: %s", err)
}
if storedOrder.CertificateProfileName != "" {
t.Errorf("order retrieved with v1 schema should have empty profilename, instead got %q", storedOrder.CertificateProfileName)
}
}

// TestGetAuthorization2NoRows ensures that the GetAuthorization2 function returns
// the correct error when there are no results for the provided ID.
func TestGetAuthorization2NoRows(t *testing.T) {
Expand Down
7 changes: 6 additions & 1 deletion tools/make-assets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ $(dirname -- "${0}")/fetch-and-verify-go.sh "${GO_VERSION}"
sudo tar -C /usr/local -xzf go.tar.gz
export PATH=/usr/local/go/bin:$PATH

# Install fpm, this is used in our Makefile to package Boulder as a deb.
# Install fpm. This is used in our Makefile to package Boulder as a deb.
# We install specific versions of some dependencies because these are the last versions
# supported by the Ruby / RubyGems that ships on ubuntu-20.04, which this script runs on in CI.
sudo gem install --no-document -v 1.8.0 rchardet
sudo gem install --no-document -v 5.1.1 public_suffix
sudo gem install --no-document -v 2.8.1 dotenv
sudo gem install --no-document -v 1.14.0 fpm

#
Expand Down

0 comments on commit 7137605

Please sign in to comment.