Merge tag 'v1.6.0-rc6' into master
This commit is contained in:
commit
e6ce61fdf0
48 changed files with 1115 additions and 472 deletions
|
@ -52,6 +52,7 @@ func (s *LocalStore) get() (*StoredData, error) {
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Check if ACME Account is in ACME V1 format
|
||||
if s.storedData.Account != nil && s.storedData.Account.Registration != nil {
|
||||
isOldRegistration, err := regexp.MatchString(RegistrationURLPathV1Regexp, s.storedData.Account.Registration.URI)
|
||||
|
@ -63,6 +64,21 @@ func (s *LocalStore) get() (*StoredData, error) {
|
|||
s.SaveDataChan <- s.storedData
|
||||
}
|
||||
}
|
||||
|
||||
// Delete all certificates with no value
|
||||
var certificates []*Certificate
|
||||
for _, certificate := range s.storedData.Certificates {
|
||||
if len(certificate.Certificate) == 0 || len(certificate.Key) == 0 {
|
||||
log.Debugf("Delete certificate %v for domains %v which have no value.", certificate, certificate.Domain.ToStrArray())
|
||||
continue
|
||||
}
|
||||
certificates = append(certificates, certificate)
|
||||
}
|
||||
|
||||
if len(certificates) < len(s.storedData.Certificates) {
|
||||
s.storedData.Certificates = certificates
|
||||
s.SaveDataChan <- s.storedData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ type Configuration struct {
|
|||
Storage string `description:"Storage to use."`
|
||||
EntryPoint string `description:"EntryPoint to use."`
|
||||
OnHostRule bool `description:"Enable certificate generation on frontends Host rules."`
|
||||
OnDemand bool `description:"Enable on demand certificate generation. This will request a certificate from Let's Encrypt during the first TLS handshake for a hostname that does not yet have a certificate."` //deprecated
|
||||
OnDemand bool `description:"Enable on demand certificate generation. This will request a certificate from Let's Encrypt during the first TLS handshake for a hostname that does not yet have a certificate."` // Deprecated
|
||||
DNSChallenge *DNSChallenge `description:"Activate DNS-01 Challenge"`
|
||||
HTTPChallenge *HTTPChallenge `description:"Activate HTTP-01 Challenge"`
|
||||
Domains []types.Domain `description:"CN and SANs (alternative domains) to each main domain using format: --acme.domains='main.com,san1.com,san2.com' --acme.domains='*.main.net'. No SANs for wildcards domain. Wildcard domains only accepted with DNSChallenge"`
|
||||
|
@ -225,11 +225,17 @@ func (p *Provider) resolveCertificate(domain types.Domain, domainFromConfigurati
|
|||
}
|
||||
|
||||
bundle := true
|
||||
|
||||
certificate, failures := client.ObtainCertificate(uncheckedDomains, bundle, nil, OSCPMustStaple)
|
||||
if len(failures) > 0 {
|
||||
return nil, fmt.Errorf("cannot obtain certificates %+v", failures)
|
||||
}
|
||||
log.Debugf("Certificates obtained for domain %+v", uncheckedDomains)
|
||||
|
||||
if len(certificate.Certificate) == 0 || len(certificate.PrivateKey) == 0 {
|
||||
return nil, fmt.Errorf("domains %v generate certificate with no value: %v", uncheckedDomains, certificate)
|
||||
}
|
||||
log.Debugf("Certificates obtained for domains %+v", uncheckedDomains)
|
||||
|
||||
if len(uncheckedDomains) > 1 {
|
||||
domain = types.Domain{Main: uncheckedDomains[0], SANs: uncheckedDomains[1:]}
|
||||
} else {
|
||||
|
@ -446,16 +452,25 @@ func (p *Provider) renewCertificates() {
|
|||
log.Infof("Error renewing certificate from LE : %+v, %v", certificate.Domain, err)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Infof("Renewing certificate from LE : %+v", certificate.Domain)
|
||||
|
||||
renewedCert, err := client.RenewCertificate(acme.CertificateResource{
|
||||
Domain: certificate.Domain.Main,
|
||||
PrivateKey: certificate.Key,
|
||||
Certificate: certificate.Certificate,
|
||||
}, true, OSCPMustStaple)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("Error renewing certificate from LE: %v, %v", certificate.Domain, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(renewedCert.Certificate) == 0 || len(renewedCert.PrivateKey) == 0 {
|
||||
log.Errorf("domains %v renew certificate with no value: %v", certificate.Domain.ToStrArray(), certificate)
|
||||
continue
|
||||
}
|
||||
|
||||
p.addCertificateForDomain(certificate.Domain, renewedCert.Certificate, renewedCert.PrivateKey)
|
||||
}
|
||||
}
|
||||
|
@ -473,6 +488,7 @@ func (p *Provider) AddRoutes(router *mux.Router) {
|
|||
log.Debugf("Unable to split host and port: %v. Fallback to request host.", err)
|
||||
domain = req.Host
|
||||
}
|
||||
|
||||
tokenValue := getTokenValue(token, domain, p.Store)
|
||||
if len(tokenValue) > 0 {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
|
|
|
@ -67,12 +67,13 @@ func (p *Provider) buildConfigurationV2(containersInspected []dockerData) *types
|
|||
container.SegmentLabels = labels
|
||||
container.SegmentName = segmentName
|
||||
|
||||
// Frontends
|
||||
if _, exists := serviceNames[container.ServiceName+segmentName]; !exists {
|
||||
serviceNamesKey := getServiceNameKey(container, p.SwarmMode, segmentName)
|
||||
|
||||
if _, exists := serviceNames[serviceNamesKey]; !exists {
|
||||
frontendName := p.getFrontendName(container, idx)
|
||||
frontends[frontendName] = append(frontends[frontendName], container)
|
||||
if len(container.ServiceName+segmentName) > 0 {
|
||||
serviceNames[container.ServiceName+segmentName] = struct{}{}
|
||||
if len(serviceNamesKey) > 0 {
|
||||
serviceNames[serviceNamesKey] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,6 +105,16 @@ func (p *Provider) buildConfigurationV2(containersInspected []dockerData) *types
|
|||
return configuration
|
||||
}
|
||||
|
||||
func getServiceNameKey(container dockerData, swarmMode bool, segmentName string) string {
|
||||
serviceNameKey := container.ServiceName
|
||||
|
||||
if values, err := label.GetStringMultipleStrict(container.Labels, labelDockerComposeProject, labelDockerComposeService); !swarmMode && err == nil {
|
||||
serviceNameKey = values[labelDockerComposeService] + values[labelDockerComposeProject]
|
||||
}
|
||||
|
||||
return serviceNameKey + segmentName
|
||||
}
|
||||
|
||||
func (p *Provider) containerFilter(container dockerData) bool {
|
||||
if !label.IsEnabled(container.Labels, p.ExposedByDefault) {
|
||||
log.Debugf("Filtering disabled container %s", container.Name)
|
||||
|
|
|
@ -311,6 +311,95 @@ func TestDockerBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when docker compose scale with different compose service names",
|
||||
containers: []docker.ContainerJSON{
|
||||
containerJSON(
|
||||
name("test_0"),
|
||||
labels(map[string]string{
|
||||
labelDockerComposeProject: "myProject",
|
||||
labelDockerComposeService: "myService",
|
||||
}),
|
||||
ports(nat.PortMap{
|
||||
"80/tcp": {},
|
||||
}),
|
||||
withNetwork("bridge", ipv4("127.0.0.1")),
|
||||
),
|
||||
containerJSON(
|
||||
name("test_1"),
|
||||
labels(map[string]string{
|
||||
labelDockerComposeProject: "myProject",
|
||||
labelDockerComposeService: "myService",
|
||||
}),
|
||||
|
||||
ports(nat.PortMap{
|
||||
"80/tcp": {},
|
||||
}),
|
||||
|
||||
withNetwork("bridge", ipv4("127.0.0.2")),
|
||||
),
|
||||
containerJSON(
|
||||
name("test_2"),
|
||||
labels(map[string]string{
|
||||
labelDockerComposeProject: "myProject",
|
||||
labelDockerComposeService: "myService2",
|
||||
}),
|
||||
|
||||
ports(nat.PortMap{
|
||||
"80/tcp": {},
|
||||
}),
|
||||
|
||||
withNetwork("bridge", ipv4("127.0.0.3")),
|
||||
),
|
||||
},
|
||||
expectedFrontends: map[string]*types.Frontend{
|
||||
"frontend-Host-myService-myProject-docker-localhost-0": {
|
||||
Backend: "backend-myService-myProject",
|
||||
PassHostHeader: true,
|
||||
EntryPoints: []string{},
|
||||
BasicAuth: []string{},
|
||||
Routes: map[string]types.Route{
|
||||
"route-frontend-Host-myService-myProject-docker-localhost-0": {
|
||||
Rule: "Host:myService.myProject.docker.localhost",
|
||||
},
|
||||
},
|
||||
},
|
||||
"frontend-Host-myService2-myProject-docker-localhost-2": {
|
||||
Backend: "backend-myService2-myProject",
|
||||
PassHostHeader: true,
|
||||
EntryPoints: []string{},
|
||||
BasicAuth: []string{},
|
||||
Routes: map[string]types.Route{
|
||||
"route-frontend-Host-myService2-myProject-docker-localhost-2": {
|
||||
Rule: "Host:myService2.myProject.docker.localhost",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedBackends: map[string]*types.Backend{
|
||||
"backend-myService-myProject": {
|
||||
Servers: map[string]types.Server{
|
||||
"server-test-0": {
|
||||
URL: "http://127.0.0.1:80",
|
||||
Weight: label.DefaultWeight,
|
||||
}, "server-test-1": {
|
||||
URL: "http://127.0.0.2:80",
|
||||
Weight: label.DefaultWeight,
|
||||
},
|
||||
},
|
||||
CircuitBreaker: nil,
|
||||
},
|
||||
"backend-myService2-myProject": {
|
||||
Servers: map[string]types.Server{
|
||||
"server-test-2": {
|
||||
URL: "http://127.0.0.3:80",
|
||||
Weight: label.DefaultWeight,
|
||||
},
|
||||
},
|
||||
CircuitBreaker: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
|
|
@ -125,11 +125,14 @@ func (p *Provider) buildConfigurationV1(containersInspected []dockerData) *types
|
|||
servers := map[string][]dockerData{}
|
||||
serviceNames := make(map[string]struct{})
|
||||
for idx, container := range filteredContainers {
|
||||
if _, exists := serviceNames[container.ServiceName]; !exists {
|
||||
|
||||
serviceNamesKey := getServiceNameKey(container, p.SwarmMode, "")
|
||||
|
||||
if _, exists := serviceNames[serviceNamesKey]; !exists {
|
||||
frontendName := p.getFrontendNameV1(container, idx)
|
||||
frontends[frontendName] = append(frontends[frontendName], container)
|
||||
if len(container.ServiceName) > 0 {
|
||||
serviceNames[container.ServiceName] = struct{}{}
|
||||
if len(serviceNamesKey) > 0 {
|
||||
serviceNames[serviceNamesKey] = struct{}{}
|
||||
}
|
||||
}
|
||||
backendName := getBackendNameV1(container)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue