diff --git a/README.md b/README.md index 9e0ecdf..61cf6d8 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,14 @@ Creates and deletes DNS records for an OpenShift cluster in AWS route 53. Specifically it creates: - api.<_cluster name_>.<_hosted zone_> +- api-int.<_cluster name_>.<_hosted zone_> (when using `--host`) - *.apps.<_cluster name_>.<_hosted zone_> By default it uses zone `Z0400818H9HMCRQLQP0V`, which is `shiftstack-dev.devcluster.openshift.com`. This can be overridden with the `--hosted-zone` option. ### Create records -To create or update a record manually: +To create or update A records for a cluster manually: ``` $ dev-cluster-dns create my-cluster --api 192.0.2.1 --ingress 192.0.2.2 @@ -20,6 +21,15 @@ $ dev-cluster-dns create my-cluster --api 192.0.2.1 --ingress 192.0.2.2 2024/06/11 14:24:20 Status: PENDING ``` +To create or update CNAME records pointing to a single host (e.g. for [SNO][sno]): + +``` +$ dev-cluster-dns create my-cluster --host my-host.example.com +2024/06/11 14:24:20 Base domain: shiftstack-dev.devcluster.openshift.com. +2024/06/11 14:24:20 Create or update records: api.my-cluster.shiftstack-dev.devcluster.openshift.com. api-int.my-cluster.shiftstack-dev.devcluster.openshift.com. *.apps.my-cluster.shiftstack-dev.devcluster.openshift.com. +2024/06/11 14:24:20 Status: PENDING +``` + Alternatively, to create or update from an `install-config.yaml` file: ``` @@ -35,6 +45,8 @@ Note that the status is `PENDING`, meaning that the records are not published ye The default TTL for the records is 60 seconds. It can be changed with the `--ttl` flag. +[sno]: https://docs.redhat.com/en/documentation/openshift_container_platform/4.22/html/installing_on_a_single_node/index + ### List records ``` diff --git a/cmd/create.go b/cmd/create.go index 9b20068..bdfa5fc 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -37,6 +37,7 @@ var ( type CreateClusterRecordsOpts struct { APIIP string IngressIP string + Host string TTL int64 WaitSeconds int64 } @@ -47,7 +48,8 @@ var createCmd = &cobra.Command{ Short: "Create or update records for a cluster", Long: `Create or update DNS records for an OpenShift cluster in an existing HostedZone. -$ dev-cluster-dns create my-cluster --api 1.2.3.4 --ingress 1.2.3.5`, +$ dev-cluster-dns create my-cluster --api 1.2.3.4 --ingress 1.2.3.5 +$ dev-cluster-dns create my-cluster --host my-host.example.com`, Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), Run: func(cmd *cobra.Command, args []string) { ctx := context.TODO() @@ -69,7 +71,10 @@ func init() { createCmd.Flags().StringVar(&createClusterRecordsOpts.APIIP, "api", "", "IP address of the api server endpoint") createCmd.Flags().StringVar(&createClusterRecordsOpts.IngressIP, "ingress", "", "IP address of the ingress endpoint") - createCmd.MarkFlagsOneRequired("api", "ingress") + createCmd.Flags().StringVar(&createClusterRecordsOpts.Host, "host", "", "Target hostname for CNAME records") + createCmd.MarkFlagsOneRequired("api", "ingress", "host") + createCmd.MarkFlagsMutuallyExclusive("host", "api") + createCmd.MarkFlagsMutuallyExclusive("host", "ingress") createCmd.Flags().Int64Var(&createClusterRecordsOpts.TTL, "ttl", 60, "TTL of created records, in seconds") createCmd.Flags().Int64Var(&createClusterRecordsOpts.WaitSeconds, "wait", 0, "Seconds to wait for records to be active. Set to zero to disable waiting") @@ -95,16 +100,24 @@ func createClusterRecords(ctx context.Context, client *route53.Client, hostedZon } var records []string - if opts.APIIP != "" { - name := "api." + clusterName + "." + baseDomain - records = append(records, name) - change.ChangeBatch.Changes = append(change.ChangeBatch.Changes, genClusterRecord(name, opts.TTL, opts.APIIP)) - } + if opts.Host != "" { + for _, prefix := range []string{"api.", "api-int.", "*.apps."} { + name := prefix + clusterName + "." + baseDomain + records = append(records, name) + change.ChangeBatch.Changes = append(change.ChangeBatch.Changes, genClusterRecord(name, types.RRTypeCname, opts.TTL, opts.Host)) + } + } else { + if opts.APIIP != "" { + name := "api." + clusterName + "." + baseDomain + records = append(records, name) + change.ChangeBatch.Changes = append(change.ChangeBatch.Changes, genClusterRecord(name, types.RRTypeA, opts.TTL, opts.APIIP)) + } - if opts.IngressIP != "" { - name := "*.apps." + clusterName + "." + baseDomain - records = append(records, name) - change.ChangeBatch.Changes = append(change.ChangeBatch.Changes, genClusterRecord(name, opts.TTL, opts.IngressIP)) + if opts.IngressIP != "" { + name := "*.apps." + clusterName + "." + baseDomain + records = append(records, name) + change.ChangeBatch.Changes = append(change.ChangeBatch.Changes, genClusterRecord(name, types.RRTypeA, opts.TTL, opts.IngressIP)) + } } log.Printf("Create or update records: %s", strings.Join(records, " ")) @@ -133,19 +146,18 @@ func createClusterRecords(ctx context.Context, client *route53.Client, hostedZon return nil } -func genClusterRecord(name string, ttl int64, ip string) types.Change { +func genClusterRecord(name string, rrType types.RRType, ttl int64, target string) types.Change { return types.Change{ Action: types.ChangeActionUpsert, ResourceRecordSet: &types.ResourceRecordSet{ Name: &name, - Type: types.RRTypeA, + Type: rrType, TTL: &ttl, ResourceRecords: []types.ResourceRecord{ { - Value: &ip, + Value: &target, }, }, }, } - } diff --git a/cmd/delete.go b/cmd/delete.go index 7ad2bc9..e1d7cc6 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -72,7 +72,7 @@ func deleteClusterRecords(ctx context.Context, client *route53.Client, hostedZon name := aws.ToString(rrs.Name) // Wildcard becomes "\052" - if strings.HasPrefix(name, "api."+clusterName+".") || strings.HasPrefix(name, "\\052.apps."+clusterName+".") { + if strings.HasPrefix(name, "api."+clusterName+".") || strings.HasPrefix(name, "api-int."+clusterName+".") || strings.HasPrefix(name, "\\052.apps."+clusterName+".") { deleteRRS = append(deleteRRS, rrs) deleteNames = append(deleteNames, name) } diff --git a/cmd/list.go b/cmd/list.go index 65d4d79..16d4b7a 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -69,7 +69,7 @@ func listClusterRecords(ctx context.Context, client *route53.Client, hostedZoneI // The wildcard is ASCII encoded // https://github.com/fog/fog/issues/1093 name = strings.Replace(name, "\\052", "*", 1) - if strings.HasPrefix(name, "api.") || strings.HasPrefix(name, "*.apps.") { + if strings.HasPrefix(name, "api.") || strings.HasPrefix(name, "api-int.") || strings.HasPrefix(name, "*.apps.") { fmt.Printf("name: %s\n", name) for _, resourceRecord := range resourceRecordSet.ResourceRecords { fmt.Printf("\tvalue: %s\n", *resourceRecord.Value)