This is an automated email from the ASF dual-hosted git repository.

friede pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new c571cf349c Add HTTPS support to Varnish cache using Hitch (#7725)
c571cf349c is described below

commit c571cf349c0d45081070b76c2614aaa75e416b96
Author: AbdelrahmanElawady 
<[email protected]>
AuthorDate: Tue Sep 5 16:55:09 2023 +0300

    Add HTTPS support to Varnish cache using Hitch (#7725)
    
    * Add Hitch config and include Hitch in CIAB
    
    * Add license
---
 cache-config/t3c-apply/t3c-apply.go              |  19 ++++
 cache-config/t3c-apply/torequest/torequest.go    |   4 +
 cache-config/t3c-generate/cfgfile/varnish.go     |  29 +++++-
 infrastructure/cdn-in-a-box/varnish/Dockerfile   |   2 +
 infrastructure/cdn-in-a-box/varnish/systemctl.sh | 109 ++++++++++++++++++-----
 lib/varnishcfg/hitch.go                          |  61 +++++++++++++
 lib/varnishcfg/hitch_test.go                     |  60 +++++++++++++
 7 files changed, 260 insertions(+), 24 deletions(-)

diff --git a/cache-config/t3c-apply/t3c-apply.go 
b/cache-config/t3c-apply/t3c-apply.go
index 75876f129a..905cc1a6f1 100644
--- a/cache-config/t3c-apply/t3c-apply.go
+++ b/cache-config/t3c-apply/t3c-apply.go
@@ -334,6 +334,25 @@ func Main() int {
                }
        }
 
+       if trops.HitchReload {
+               svcStatus, _, err := util.GetServiceStatus("hitch")
+               cmd := "start"
+               running := false
+               if err != nil {
+                       log.Errorf("not starting 'hitch', error getting 'hitch' 
run status: %s\n", err)
+               } else if svcStatus != util.SvcNotRunning {
+                       cmd = "reload"
+               }
+               running, err = util.ServiceStart("hitch", cmd)
+               if err != nil {
+                       log.Errorf("'hitch' was not %sed: %s\n", cmd, err)
+               } else if running {
+                       log.Infof("service 'hitch' %sed", cmd)
+               } else {
+                       log.Infoln("service 'hitch' already running")
+               }
+       }
+
        // reload sysctl
        if trops.SysCtlReload == true {
                runSysctl(cfg)
diff --git a/cache-config/t3c-apply/torequest/torequest.go 
b/cache-config/t3c-apply/torequest/torequest.go
index 990b71c852..ba9b443682 100644
--- a/cache-config/t3c-apply/torequest/torequest.go
+++ b/cache-config/t3c-apply/torequest/torequest.go
@@ -90,6 +90,7 @@ type RestartData struct {
        TeakdRestart         bool // a restart of teakd is required
        TrafficServerRestart bool // a trafficserver restart is required
        RemapConfigReload    bool // remap.config should be reloaded
+       HitchReload          bool // hitch should be reloaded
 }
 
 type ConfigFile struct {
@@ -520,6 +521,7 @@ func (r *TrafficOpsReq) replaceCfgFile(cfg *ConfigFile) 
(*FileRestartData, error
        trafficServerRestart := cfg.Name == "plugin.config"
        ntpdRestart := cfg.Name == "ntpd.conf"
        sysCtlReload := cfg.Name == "sysctl.conf"
+       hitchReload := cfg.Name == "hitch.conf"
 
        log.Debugf("Reload state after %s: remap.config: %t reload: %t restart: 
%t ntpd: %t sysctl: %t", cfg.Name, remapConfigReload, trafficCtlReload, 
trafficServerRestart, ntpdRestart, sysCtlReload)
 
@@ -532,6 +534,7 @@ func (r *TrafficOpsReq) replaceCfgFile(cfg *ConfigFile) 
(*FileRestartData, error
                        NtpdRestart:          ntpdRestart,
                        TrafficServerRestart: trafficServerRestart,
                        RemapConfigReload:    remapConfigReload,
+                       HitchReload:          hitchReload,
                },
        }, nil
 }
@@ -810,6 +813,7 @@ func (r *TrafficOpsReq) CheckReloadRestart(data 
[]FileRestartData) RestartData {
                rd.TeakdRestart = rd.TeakdRestart || changedFile.TeakdRestart
                rd.TrafficServerRestart = rd.TrafficServerRestart || 
changedFile.TrafficServerRestart
                rd.RemapConfigReload = rd.RemapConfigReload || 
changedFile.RemapConfigReload
+               rd.HitchReload = rd.HitchReload || changedFile.HitchReload
        }
        return rd
 }
diff --git a/cache-config/t3c-generate/cfgfile/varnish.go 
b/cache-config/t3c-generate/cfgfile/varnish.go
index 060445a75a..07a33273e0 100644
--- a/cache-config/t3c-generate/cfgfile/varnish.go
+++ b/cache-config/t3c-generate/cfgfile/varnish.go
@@ -20,6 +20,9 @@ package cfgfile
  */
 
 import (
+       "errors"
+       "path/filepath"
+
        "github.com/apache/trafficcontrol/cache-config/t3c-generate/config"
        "github.com/apache/trafficcontrol/cache-config/t3cutil"
        "github.com/apache/trafficcontrol/lib/varnishcfg"
@@ -42,5 +45,29 @@ func GetVarnishConfigs(toData *t3cutil.ConfigData, cfg 
config.Cfg) ([]t3cutil.AT
                LineComment: "//",
                Secure:      false,
        })
-       return configs, err
+       txt, hitchWarnings := 
varnishcfg.GetHitchConfig(toData.DeliveryServices, filepath.Join(cfg.Dir, 
"ssl/"))
+       warnings = append(warnings, hitchWarnings...)
+       logWarnings("Generating hitch configuration files: ", hitchWarnings)
+
+       configs = append(configs, t3cutil.ATSConfigFile{
+               Name:        "hitch.conf",
+               Text:        txt,
+               Path:        cfg.Dir,
+               ContentType: "text/plain; charset=us-ascii",
+               LineComment: "//",
+               Secure:      false,
+       })
+
+       sslConfigs, err := GetSSLCertsAndKeyFiles(toData)
+       if err != nil {
+               return nil, errors.New("getting ssl key and cert config files: 
" + err.Error())
+       }
+       for i := range sslConfigs {
+               // path changed manually because GetSSLCertsAndKeyFiles 
hardcodes the directory certs and keys are written to.
+               // will be removed once GetSSLCertsAndKeyFiles uses 
proxy.config.ssl.server.cert.path parameter.
+               sslConfigs[i].Path = filepath.Join(cfg.Dir, "ssl/")
+       }
+       configs = append(configs, sslConfigs...)
+
+       return configs, nil
 }
diff --git a/infrastructure/cdn-in-a-box/varnish/Dockerfile 
b/infrastructure/cdn-in-a-box/varnish/Dockerfile
index a67e1724b3..9b5840d7b5 100644
--- a/infrastructure/cdn-in-a-box/varnish/Dockerfile
+++ b/infrastructure/cdn-in-a-box/varnish/Dockerfile
@@ -28,6 +28,8 @@ RUN curl -s 
https://packagecloud.io/install/repositories/varnishcache/varnish73/
 
 RUN yum install varnish-7.3.0 -y
 
+RUN yum install -y hitch-1.5.2
+
 RUN dnf install -y bind-utils kyotocabinet-libs initscripts iproute net-tools 
nmap-ncat gettext autoconf automake libtool gcc-c++ cronie glibc-devel 
openssl-devel git perl && \
     dnf install -y jq logrotate findutils && \
     dnf clean all
diff --git a/infrastructure/cdn-in-a-box/varnish/systemctl.sh 
b/infrastructure/cdn-in-a-box/varnish/systemctl.sh
index cfe2a55c24..7184d78194 100755
--- a/infrastructure/cdn-in-a-box/varnish/systemctl.sh
+++ b/infrastructure/cdn-in-a-box/varnish/systemctl.sh
@@ -18,6 +18,7 @@
 # under the License.
 
 VARNISHD_EXECUTABLE="/usr/sbin/varnishd"
+HITCH_EXECUTABLE="/usr/sbin/hitch"
 
 is_varnishd_running() {
   pgrep -x "$(basename "$VARNISHD_EXECUTABLE")" >/dev/null
@@ -28,7 +29,7 @@ start_varnishd() {
     echo "varnishd is already running."
   else
     echo "Starting varnishd..."
-    "$VARNISHD_EXECUTABLE" -f /opt/cache/etc/varnish/default.vcl
+    "$VARNISHD_EXECUTABLE" -f /opt/cache/etc/varnish/default.vcl -a :80 -a 
:6081,PROXY
     echo "varnishd is now running."
   fi
 }
@@ -67,28 +68,90 @@ restart_varnishd() {
   start_varnishd
 }
 
-case "$1" in
-  enable)
-    exit 0
-    ;;
-  start)
-    start_varnishd
-    ;;
-  stop)
-    stop_varnishd
-    ;;
-  restart)
-    restart_varnishd
-    ;;
-  status)
-    if is_varnishd_running; then
-      exit 0
-    fi
-    exit 3
-    ;;
-  *)
-    echo "Usage: $0 {start|stop|restart|enable|status}"
+is_hitch_running() {
+  pgrep -x "$(basename "$HITCH_EXECUTABLE")" >/dev/null
+}
+
+
+start_hitch() {
+  if is_hitch_running; then
+    echo "hitch is already running."
+  else
+    echo "Starting hitch..."
+    "$HITCH_EXECUTABLE" --config /opt/cache/etc/varnish/hitch.conf --daemon
+    echo "hitch is now running."
+  fi
+
+}
+
+reload_hitch() {
+  if is_hitch_running; then
+    pkill -HUP "$(basename "$HITCH_EXECUTABLE")"
+  else
+    echo "hitch is not running"
     exit 1
-esac
+  fi
+}
+
+handle_varnish_service() {
+  case "$1" in
+    enable)
+      exit 0
+      ;;
+    start)
+      start_varnishd
+      ;;
+    stop)
+      stop_varnishd
+      ;;
+    restart)
+      restart_varnishd
+      ;;
+    status)
+      if is_varnishd_running; then
+        # t3c-apply looks for this specific string
+        echo "Active: active"
+        exit 0
+      fi
+      exit 3
+      ;;
+    *)
+      echo "Usage: $0 {start|stop|restart|enable|status}"
+      exit 1
+  esac
+}
+
+handle_hitch_service() {
+  case "$1" in
+    enable)
+      exit 0
+      ;;
+    start)
+      start_hitch
+      ;;
+    reload)
+      reload_hitch
+      ;;
+    status)
+      if is_hitch_running; then
+        # t3c-apply looks for this specific string
+        echo "Active: active"
+        exit 0
+      fi
+      exit 3
+      ;;
+    *)
+      echo "Usage: $0 {start|stop|restart|reload|enable|status}"
+      exit 1
+  esac
+}
+
+if [[ $2 == "varnish.service" ]]
+then
+  handle_varnish_service $1
+elif [[ $2 == "hitch.service" ]]
+then
+  handle_hitch_service $1
+fi
 
 exit 0
diff --git a/lib/varnishcfg/hitch.go b/lib/varnishcfg/hitch.go
new file mode 100644
index 0000000000..2727feb96e
--- /dev/null
+++ b/lib/varnishcfg/hitch.go
@@ -0,0 +1,61 @@
+package varnishcfg
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import (
+       "path/filepath"
+       "strings"
+
+       "github.com/apache/trafficcontrol/lib/go-atscfg"
+)
+
+// GetHitchConfig returns Hitch config using TO data
+func GetHitchConfig(deliveryServices []atscfg.DeliveryService, sslDir string) 
(string, []string) {
+       warnings := make([]string, 0)
+       lines := []string{
+               `frontend = {`,
+               `       host = "*"`,
+               `       port = "443"`,
+               `}`,
+               `backend = "[127.0.0.1]:6081"`,
+               `write-proxy-v2 = on`,
+               // TODO: change root user
+               `user = "root"`,
+       }
+
+       dses, dsWarns := 
atscfg.DeliveryServicesToSSLMultiCertDSes(deliveryServices)
+       warnings = append(warnings, dsWarns...)
+
+       dses = atscfg.GetSSLMultiCertDotConfigDeliveryServices(dses)
+
+       for dsName, ds := range dses {
+               cerName, keyName := 
atscfg.GetSSLMultiCertDotConfigCertAndKeyName(dsName, ds)
+               lines = append(lines, []string{
+                       `pem-file = {`,
+                       `       cert = "` + filepath.Join(sslDir, cerName) + 
`"`,
+                       `       private-key = "` + filepath.Join(sslDir, 
keyName) + `"`,
+                       `}`,
+               }...)
+       }
+
+       txt := strings.Join(lines, "\n")
+       txt += "\n"
+       return txt, warnings
+}
diff --git a/lib/varnishcfg/hitch_test.go b/lib/varnishcfg/hitch_test.go
new file mode 100644
index 0000000000..b9a6699579
--- /dev/null
+++ b/lib/varnishcfg/hitch_test.go
@@ -0,0 +1,60 @@
+package varnishcfg
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import (
+       "strings"
+       "testing"
+
+       "github.com/apache/trafficcontrol/lib/go-atscfg"
+       "github.com/apache/trafficcontrol/lib/go-tc"
+       "github.com/apache/trafficcontrol/lib/go-util"
+)
+
+func TestGetHitchConfig(t *testing.T) {
+       ds1 := &atscfg.DeliveryService{}
+       ds1.XMLID = util.StrPtr("ds1")
+       ds1.Protocol = util.IntPtr(1)
+       ds1Type := tc.DSTypeHTTP
+       ds1.Type = &ds1Type
+       ds1.ExampleURLs = []string{"https://ds1.example.org"}
+       deliveryServices := []atscfg.DeliveryService{*ds1}
+       txt, warnings := GetHitchConfig(deliveryServices, "/ssl")
+       expectedTxt := strings.Join([]string{
+               `frontend = {`,
+               `       host = "*"`,
+               `       port = "443"`,
+               `}`,
+               `backend = "[127.0.0.1]:6081"`,
+               `write-proxy-v2 = on`,
+               `user = "root"`,
+               `pem-file = {`,
+               `       cert = "/ssl/ds1_example_org_cert.cer"`,
+               `       private-key = "/ssl/ds1.example.org.key"`,
+               `}`,
+       }, "\n")
+       expectedTxt += "\n"
+       if len(warnings) != 0 {
+               t.Errorf("expected no warnings got %v", warnings)
+       }
+       if txt != expectedTxt {
+               t.Errorf("expected: %s got: %s", expectedTxt, txt)
+       }
+}

Reply via email to