mirror of https://github.com/kubernetes/kops.git
Merge pull request #1378 from justinsb/fix_1374
Fix double initialization of DNSZone
This commit is contained in:
commit
7e34812659
|
@ -19,6 +19,7 @@ package model
|
||||||
import (
|
import (
|
||||||
"k8s.io/kops/upup/pkg/fi"
|
"k8s.io/kops/upup/pkg/fi"
|
||||||
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
|
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DNSModelBuilder builds DNS related model objects
|
// DNSModelBuilder builds DNS related model objects
|
||||||
|
@ -29,16 +30,29 @@ type DNSModelBuilder struct {
|
||||||
var _ fi.ModelBuilder = &DNSModelBuilder{}
|
var _ fi.ModelBuilder = &DNSModelBuilder{}
|
||||||
|
|
||||||
func (b *DNSModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
func (b *DNSModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
||||||
if b.UsePrivateDNS() {
|
// Add a HostedZone if we are going to publish a dns record that depends on it
|
||||||
// This is only exposed as a feature flag currently
|
if b.UsePrivateDNS() || b.UsesBastionDns() {
|
||||||
|
// UsePrivateDNS is only exposed as a feature flag currently
|
||||||
// TODO: We may still need a public zone to publish an ELB
|
// TODO: We may still need a public zone to publish an ELB
|
||||||
|
|
||||||
|
// Check to see if we are using a bastion DNS record that points to the hosted zone
|
||||||
|
// If we are, we need to make sure we include the hosted zone as a task
|
||||||
|
|
||||||
// Configuration for a DNS zone, attached to our VPC
|
// Configuration for a DNS zone, attached to our VPC
|
||||||
dnsZone := &awstasks.DNSZone{
|
dnsZone := &awstasks.DNSZone{
|
||||||
Name: s(b.Cluster.Spec.DNSZone),
|
Name: s("private-" + b.Cluster.Spec.DNSZone),
|
||||||
Private: fi.Bool(true),
|
Private: fi.Bool(true),
|
||||||
PrivateVPC: b.LinkToVPC(),
|
PrivateVPC: b.LinkToVPC(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(b.Cluster.Spec.DNSZone, ".") {
|
||||||
|
// Looks like a hosted zone ID
|
||||||
|
dnsZone.ZoneID = s(b.Cluster.Spec.DNSZone)
|
||||||
|
} else {
|
||||||
|
// Looks like a normal ddns name
|
||||||
|
dnsZone.DNSName = s(b.Cluster.Spec.DNSZone)
|
||||||
|
}
|
||||||
|
|
||||||
c.AddTask(dnsZone)
|
c.AddTask(dnsZone)
|
||||||
} else if b.UseLoadBalancerForAPI() {
|
} else if b.UseLoadBalancerForAPI() {
|
||||||
// This will point our DNS to the load balancer, and put the pieces
|
// This will point our DNS to the load balancer, and put the pieces
|
||||||
|
@ -49,6 +63,15 @@ func (b *DNSModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
||||||
Name: s(b.Cluster.Spec.DNSZone),
|
Name: s(b.Cluster.Spec.DNSZone),
|
||||||
Private: fi.Bool(false),
|
Private: fi.Bool(false),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(b.Cluster.Spec.DNSZone, ".") {
|
||||||
|
// Looks like a hosted zone ID
|
||||||
|
dnsZone.ZoneID = s(b.Cluster.Spec.DNSZone)
|
||||||
|
} else {
|
||||||
|
// Looks like a normal ddns name
|
||||||
|
dnsZone.DNSName = s(b.Cluster.Spec.DNSZone)
|
||||||
|
}
|
||||||
|
|
||||||
c.AddTask(dnsZone)
|
c.AddTask(dnsZone)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,16 +88,5 @@ func (b *DNSModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
||||||
c.AddTask(dnsName)
|
c.AddTask(dnsName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check and see if we are using a bastion DNS record that points to the hosted zone
|
|
||||||
// If we are, we need to make sure we include the hosted zone as a task
|
|
||||||
if b.UsesBastionDns() {
|
|
||||||
dnsZone := &awstasks.DNSZone{
|
|
||||||
Name: s(b.Cluster.Spec.DNSZone),
|
|
||||||
Private: fi.Bool(true),
|
|
||||||
PrivateVPC: b.LinkToVPC(),
|
|
||||||
}
|
|
||||||
c.AddTask(dnsZone)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ func (e *DNSName) Find(c *fi.Context) (*DNSName, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
request := &route53.ListResourceRecordSetsInput{
|
request := &route53.ListResourceRecordSetsInput{
|
||||||
HostedZoneId: e.Zone.ID,
|
HostedZoneId: e.Zone.ZoneID,
|
||||||
// TODO: Start at correct name?
|
// TODO: Start at correct name?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ func (_ *DNSName) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *DNSName) error
|
||||||
changeBatch.Changes = []*route53.Change{change}
|
changeBatch.Changes = []*route53.Change{change}
|
||||||
|
|
||||||
request := &route53.ChangeResourceRecordSetsInput{}
|
request := &route53.ChangeResourceRecordSetsInput{}
|
||||||
request.HostedZoneId = e.Zone.ID
|
request.HostedZoneId = e.Zone.ZoneID
|
||||||
request.ChangeBatch = changeBatch
|
request.ChangeBatch = changeBatch
|
||||||
|
|
||||||
glog.V(2).Infof("Updating DNS record %q", *e.Name)
|
glog.V(2).Infof("Updating DNS record %q", *e.Name)
|
||||||
|
|
|
@ -33,8 +33,9 @@ import (
|
||||||
|
|
||||||
//go:generate fitask -type=DNSZone
|
//go:generate fitask -type=DNSZone
|
||||||
type DNSZone struct {
|
type DNSZone struct {
|
||||||
Name *string
|
Name *string
|
||||||
ID *string
|
DNSName *string
|
||||||
|
ZoneID *string
|
||||||
|
|
||||||
Private *bool
|
Private *bool
|
||||||
PrivateVPC *VPC
|
PrivateVPC *VPC
|
||||||
|
@ -60,7 +61,10 @@ func (e *DNSZone) Find(c *fi.Context) (*DNSZone, error) {
|
||||||
|
|
||||||
actual := &DNSZone{}
|
actual := &DNSZone{}
|
||||||
actual.Name = e.Name
|
actual.Name = e.Name
|
||||||
actual.ID = z.HostedZone.Id
|
if z.HostedZone.Name != nil {
|
||||||
|
actual.DNSName = fi.String(strings.TrimSuffix(*z.HostedZone.Name, "."))
|
||||||
|
}
|
||||||
|
actual.ZoneID = z.HostedZone.Id
|
||||||
actual.Private = z.HostedZone.Config.PrivateZone
|
actual.Private = z.HostedZone.Config.PrivateZone
|
||||||
|
|
||||||
// If the zone is private, but we don't want it to be, that will be an error
|
// If the zone is private, but we don't want it to be, that will be an error
|
||||||
|
@ -77,8 +81,11 @@ func (e *DNSZone) Find(c *fi.Context) (*DNSZone, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.ID == nil {
|
if e.ZoneID == nil {
|
||||||
e.ID = actual.ID
|
e.ZoneID = actual.ZoneID
|
||||||
|
}
|
||||||
|
if e.DNSName == nil {
|
||||||
|
e.DNSName = actual.DNSName
|
||||||
}
|
}
|
||||||
|
|
||||||
return actual, nil
|
return actual, nil
|
||||||
|
@ -86,24 +93,15 @@ func (e *DNSZone) Find(c *fi.Context) (*DNSZone, error) {
|
||||||
|
|
||||||
func (e *DNSZone) findExisting(cloud awsup.AWSCloud) (*route53.GetHostedZoneOutput, error) {
|
func (e *DNSZone) findExisting(cloud awsup.AWSCloud) (*route53.GetHostedZoneOutput, error) {
|
||||||
findID := ""
|
findID := ""
|
||||||
if e.ID != nil {
|
if e.ZoneID != nil {
|
||||||
findID = *e.ID
|
|
||||||
} else if e.Name != nil && !strings.Contains(*e.Name, ".") {
|
|
||||||
// Looks like a hosted zone ID
|
|
||||||
findID = *e.Name
|
|
||||||
}
|
|
||||||
if findID != "" {
|
|
||||||
request := &route53.GetHostedZoneInput{
|
request := &route53.GetHostedZoneInput{
|
||||||
Id: aws.String(findID),
|
Id: e.ZoneID,
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := cloud.Route53().GetHostedZone(request)
|
response, err := cloud.Route53().GetHostedZone(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if awsup.AWSErrorCode(err) == "NoSuchHostedZone" {
|
if awsup.AWSErrorCode(err) == "NoSuchHostedZone" {
|
||||||
if e.ID != nil {
|
return nil, nil
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
// Otherwise continue ... maybe the name was not an id after all...
|
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("error fetching DNS HostedZone %q: %v", findID, err)
|
return nil, fmt.Errorf("error fetching DNS HostedZone %q: %v", findID, err)
|
||||||
}
|
}
|
||||||
|
@ -112,7 +110,7 @@ func (e *DNSZone) findExisting(cloud awsup.AWSCloud) (*route53.GetHostedZoneOutp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findName := fi.StringValue(e.Name)
|
findName := fi.StringValue(e.DNSName)
|
||||||
if findName == "" {
|
if findName == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -165,10 +163,10 @@ func (s *DNSZone) CheckChanges(a, e, changes *DNSZone) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ *DNSZone) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *DNSZone) error {
|
func (_ *DNSZone) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *DNSZone) error {
|
||||||
name := aws.StringValue(e.Name)
|
name := aws.StringValue(e.DNSName)
|
||||||
if a == nil {
|
if a == nil {
|
||||||
request := &route53.CreateHostedZoneInput{}
|
request := &route53.CreateHostedZoneInput{}
|
||||||
request.Name = e.Name
|
request.Name = e.DNSName
|
||||||
nonce := rand.Int63()
|
nonce := rand.Int63()
|
||||||
request.CallerReference = aws.String(strconv.FormatInt(nonce, 10))
|
request.CallerReference = aws.String(strconv.FormatInt(nonce, 10))
|
||||||
|
|
||||||
|
@ -186,11 +184,11 @@ func (_ *DNSZone) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *DNSZone) error
|
||||||
return fmt.Errorf("error creating DNS HostedZone %q: %v", name, err)
|
return fmt.Errorf("error creating DNS HostedZone %q: %v", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.ID = response.HostedZone.Id
|
e.ZoneID = response.HostedZone.Id
|
||||||
} else {
|
} else {
|
||||||
if changes.PrivateVPC != nil {
|
if changes.PrivateVPC != nil {
|
||||||
request := &route53.AssociateVPCWithHostedZoneInput{
|
request := &route53.AssociateVPCWithHostedZoneInput{
|
||||||
HostedZoneId: a.ID,
|
HostedZoneId: a.ZoneID,
|
||||||
VPC: &route53.VPC{
|
VPC: &route53.VPC{
|
||||||
VPCId: e.PrivateVPC.ID,
|
VPCId: e.PrivateVPC.ID,
|
||||||
VPCRegion: aws.String(t.Cloud.Region()),
|
VPCRegion: aws.String(t.Cloud.Region()),
|
||||||
|
@ -227,10 +225,12 @@ type terraformRoute53Zone struct {
|
||||||
func (_ *DNSZone) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *DNSZone) error {
|
func (_ *DNSZone) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *DNSZone) error {
|
||||||
cloud := t.Cloud.(awsup.AWSCloud)
|
cloud := t.Cloud.(awsup.AWSCloud)
|
||||||
|
|
||||||
|
dnsName := fi.StringValue(e.DNSName)
|
||||||
|
|
||||||
// As a special case, we check for an existing zone
|
// As a special case, we check for an existing zone
|
||||||
// It is really painful to have TF create a new one...
|
// It is really painful to have TF create a new one...
|
||||||
// (you have to reconfigure the DNS NS records)
|
// (you have to reconfigure the DNS NS records)
|
||||||
glog.Infof("Check for existing route53 zone to re-use with name %q", *e.Name)
|
glog.Infof("Check for existing route53 zone to re-use with name %q", dnsName)
|
||||||
z, err := e.findExisting(cloud)
|
z, err := e.findExisting(cloud)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -239,7 +239,7 @@ func (_ *DNSZone) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *D
|
||||||
if z != nil {
|
if z != nil {
|
||||||
glog.Infof("Existing zone %q found; will configure TF to reuse", aws.StringValue(z.HostedZone.Name))
|
glog.Infof("Existing zone %q found; will configure TF to reuse", aws.StringValue(z.HostedZone.Name))
|
||||||
|
|
||||||
e.ID = z.HostedZone.Id
|
e.ZoneID = z.HostedZone.Id
|
||||||
}
|
}
|
||||||
|
|
||||||
if z == nil {
|
if z == nil {
|
||||||
|
@ -271,9 +271,9 @@ func (_ *DNSZone) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *D
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *DNSZone) TerraformLink() *terraform.Literal {
|
func (e *DNSZone) TerraformLink() *terraform.Literal {
|
||||||
if e.ID != nil {
|
if e.ZoneID != nil {
|
||||||
glog.V(4).Infof("reusing existing route53 zone with id %q", *e.ID)
|
glog.V(4).Infof("reusing existing route53 zone with id %q", *e.ZoneID)
|
||||||
return terraform.LiteralFromStringValue(*e.ID)
|
return terraform.LiteralFromStringValue(*e.ZoneID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return terraform.LiteralSelfLink("aws_route53_zone", *e.Name)
|
return terraform.LiteralSelfLink("aws_route53_zone", *e.Name)
|
||||||
|
|
Loading…
Reference in New Issue