github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/autocertcache.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/mgo/v3"
    11  	"golang.org/x/crypto/acme/autocert"
    12  
    13  	"github.com/juju/juju/mongo"
    14  )
    15  
    16  // AutocertCache returns an implementation
    17  // of autocert.Cache backed by the state.
    18  func (st *State) AutocertCache() autocert.Cache {
    19  	return autocertCache{st}
    20  }
    21  
    22  type autocertCache struct {
    23  	st *State
    24  }
    25  
    26  type autocertCacheDoc struct {
    27  	Name string `bson:"_id"`
    28  	Data []byte `bson:"data"`
    29  }
    30  
    31  // Put implements autocert.Cache.Put.
    32  func (cache autocertCache) Put(ctx context.Context, name string, data []byte) error {
    33  	coll, closeColl := cache.coll()
    34  	defer closeColl()
    35  	_, err := coll.UpsertId(name, autocertCacheDoc{
    36  		Name: name,
    37  		Data: data,
    38  	})
    39  	if err != nil {
    40  		return errors.Annotatef(err, "cannot store autocert key %q", name)
    41  	}
    42  	return nil
    43  }
    44  
    45  // Get implements autocert.Cache.Get.
    46  func (cache autocertCache) Get(ctx context.Context, name string) ([]byte, error) {
    47  	coll, closeColl := cache.coll()
    48  	defer closeColl()
    49  	var doc autocertCacheDoc
    50  	err := coll.FindId(name).One(&doc)
    51  	if err == nil {
    52  		return doc.Data, nil
    53  	}
    54  	if errors.Cause(err) == mgo.ErrNotFound {
    55  		return nil, autocert.ErrCacheMiss
    56  	}
    57  	return nil, errors.Annotatef(err, "cannot get autocert key %q", name)
    58  }
    59  
    60  // Delete implements autocert.Cache.Delete.
    61  func (cache autocertCache) Delete(ctx context.Context, name string) error {
    62  	coll, closeColl := cache.coll()
    63  	defer closeColl()
    64  	err := coll.RemoveId(name)
    65  	if err == nil || errors.Cause(err) == mgo.ErrNotFound {
    66  		return nil
    67  	}
    68  	return errors.Annotatef(err, "cannot delete autocert key %q", name)
    69  }
    70  
    71  func (cache autocertCache) coll() (mongo.WriteCollection, func()) {
    72  	coll, closer := cache.st.db().GetCollection(autocertCacheC)
    73  	return coll.Writeable(), closer
    74  }