<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: shema-surge</title>
    <description>The latest articles on DEV Community by shema-surge (@shemasurge).</description>
    <link>https://dev.to/shemasurge</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F427605%2F2d1a4b2b-2b8a-4a6e-a9da-74e61f816d8b.jpeg</url>
      <title>DEV Community: shema-surge</title>
      <link>https://dev.to/shemasurge</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shemasurge"/>
    <language>en</language>
    <item>
      <title>Errors as values (Go)</title>
      <dc:creator>shema-surge</dc:creator>
      <pubDate>Tue, 15 Apr 2025 18:42:10 +0000</pubDate>
      <link>https://dev.to/shemasurge/errors-as-values-go-pj6</link>
      <guid>https://dev.to/shemasurge/errors-as-values-go-pj6</guid>
      <description>&lt;h3&gt;
  
  
  How Go's error handling is better
&lt;/h3&gt;

&lt;p&gt;In programming languages like java and javascript, errors are special. They are handled using fancy syntax like try and catch statements but  often end up becoming messy and confusing.&lt;/p&gt;

&lt;p&gt;Here is an example a file copying program written in javascript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fs = require("node:fs")
const { argv } = require("node:process")
try {
    const data = fs.readFileSync(argv[2], "utf-8")
    fs.writeFileSync(argv[3],data)
} catch (err) {
    console.error(err)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above program we try to read a text file whose name is provided as an stdin argument to the program and write its contents to a second file whose name is also provided as the second argument&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; node copy.js file1.txt file2.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem with this program is that if it crashed, we would not know where the error occurred from. Would it be from the readFileSync function or writeFileSync? In this scenario we are left to speculate about where error could have been thrown. &lt;/p&gt;

&lt;p&gt;We could try and handle errors using callbacks for Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fs.readFile(argv[2], "utf-8",(err, data)=&amp;gt;{
    if (err){
        console.error(err)
    }
    fs.writeFile(argv[3], data, err=&amp;gt;{
       if (err){
        console.error(err)
       }
    })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but this approach quickly leads to callback hell when working with multiple risky functions.&lt;/p&gt;

&lt;p&gt;However when it comes to Go, we are forced to think about the errors returned on each step of the way. Here is the same program now written Go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "log"
    "os"
)

func main() {
    data, readErr := os.ReadFile(os.Args[1])
    if readErr != nil {
        //do something with the read error
        log.Fatal(readErr)
    }
    writeErr := os.WriteFile(os.Args[2], data, 0600)
    if writeErr != nil {
        //do something with the write error
        log.Fatal(writeErr)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Go, we handle errors like any other value. This provides clarity into where the errors are coming from and how to handle them.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The DIY Movement</title>
      <dc:creator>shema-surge</dc:creator>
      <pubDate>Tue, 02 Apr 2024 16:20:51 +0000</pubDate>
      <link>https://dev.to/shemasurge/the-diy-movement-1b5k</link>
      <guid>https://dev.to/shemasurge/the-diy-movement-1b5k</guid>
      <description>&lt;p&gt;The DIY movement is a movement of self-sufficiency. It's core tenet and goal is literally in it's name "Do it yourself". &lt;/p&gt;

&lt;p&gt;If every person had the ability to build their own house, fix their own car, write their own operating system and make their own beer, the world would be a significantly better place. we wouldn't need giant polluting factories to mass-produce useless products when people can produce all of their material needs on an individual scale.&lt;/p&gt;

&lt;p&gt;This movement has made some significant strides in recent times, 3D printing is one of many examples of technologies that allow people to make their own tools and objects instead of relying on industrial manufacturing. This movement promises a future of abundance and freedom from corporations that destroy human ingenuity.&lt;/p&gt;

&lt;p&gt;The only limiting factor is the availability of knowledge. People can't make things without guides and manuals. With the modern internet getting bloated with paywalls and human knowledge getting swallowed up by an avalanche of useless social media content and AI generated articles, A platform that democratizes knowledge would help ensure that the DIY movement does not die out.&lt;/p&gt;

</description>
      <category>diy</category>
    </item>
    <item>
      <title>How to create a simple high availability apache webserver cluster</title>
      <dc:creator>shema-surge</dc:creator>
      <pubDate>Sun, 23 Apr 2023 10:16:25 +0000</pubDate>
      <link>https://dev.to/shemasurge/how-to-create-a-simple-high-availability-apache-webserver-cluster-11pp</link>
      <guid>https://dev.to/shemasurge/how-to-create-a-simple-high-availability-apache-webserver-cluster-11pp</guid>
      <description>&lt;p&gt;A high availability (HA) cluster is a group of interconnected computers, servers or nodes, that work together to ensure that an application or service remains available even if one or more of the nodes in the cluster fails. The primary goal of an HA cluster is to provide continuous availability and minimize downtime by distributing the workload across multiple nodes.&lt;/p&gt;

&lt;p&gt;In an HA cluster, each node is responsible for a specific task, and if one node fails, another node in the cluster takes over that task automatically.&lt;/p&gt;

&lt;p&gt;This article assumes that you have setup two identical centos vms or physical machines, each running apache web servers that host the same website. In this article, node1 has ip address 192.168.1.2/24 and node2 has 192.168.1.3/24. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ON BOTH NODES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yum install ricci luci ccs cman modcluster cluster* -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;start the ricci service&lt;/p&gt;

&lt;p&gt;&lt;code&gt;service ricci start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;set a password for ricci user on both nodes&lt;/p&gt;

&lt;p&gt;&lt;code&gt;passwd ricci&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IN THE MASTER NODE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;create the cluster&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --createcluster mycluster&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;add nodes to the cluster&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --addnode 192.168.1.2&lt;/code&gt;&lt;br&gt;
&lt;code&gt;ccs -h 192.168.1.2 --addnode 192.168.1.3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --lsnodes&lt;/code&gt; lists all nodes added in the cluster&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add Fencing to Cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fencing is the disconnection of a node from shared storage. Fencing cuts off I/O from shared storage, thus ensuring data integrity.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --setfencedaemon post_fail_delay=0&lt;/code&gt;&lt;br&gt;
&lt;code&gt;ccs -h 192.168.1.2 --setfencedaemon post_join_delay=0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a fence device&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A fence device is a hardware device that can be used to cut a node off from shared storage.&lt;/p&gt;

&lt;p&gt;A fence agent is a software program that connects to a fence device in order to ask the fence device to cut off access to a node’s shared storage (via powering off the node or removing access to the shared storage by other means).&lt;/p&gt;

&lt;p&gt;There are different types of fencing devices available. If you are using virtual machine to build a cluster, use fence_virt device as shown below.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --addfencedev myfence agent=fence_virt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;create fence method and add nodes to it&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --addmethod mymethod 192.168.1.2&lt;/code&gt;&lt;br&gt;
&lt;code&gt;ccs -h 192.168.1.2 --addethod mymethod 192.168.1.3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;add fence method to fence device&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --addfenceinst myfence 192.168.1.2 mymethod&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;css -h 192.168.1.2 --addfenceinst myfence 192.168.1.3 mymethod&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;create a failover domain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A failover domain is an ordered subset of cluster members to which a resource group or service may be bound.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --addfailoverdomain mywebserverdomain ordered&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;add both nodes to the failover domain&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --addfailoverdomainnode mywebserverdomain 192.168.1.2 1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --addfailoverdomainnode mywebserverdomain 192.168.1.3 2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --lsfailoverdomain&lt;/code&gt; shows the nodes and their priorities&lt;/p&gt;

&lt;p&gt;add apache webserver service to the cluster setup&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --addservice apache domain=mywebserverdomain recovery=relocate autostart=1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;sync cluster configurations across all cluster nodes&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.2 --sync --activate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;check cluster configuration&lt;/p&gt;

&lt;p&gt;ccs -h 192.168.1.2 --checkconf&lt;/p&gt;

&lt;p&gt;OUTPUT: All nodes in sync&lt;/p&gt;

&lt;p&gt;Disable NetworkManager on all nodes because it stops cman service from starting&lt;/p&gt;

&lt;p&gt;&lt;code&gt;service NetworkManager stop&lt;/code&gt;&lt;br&gt;
&lt;code&gt;chkconfig NetworkManager off&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;start the cman service on all nodes&lt;/p&gt;

&lt;p&gt;&lt;code&gt;service cman start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;use clustat to check status of all cluster nodes&lt;/p&gt;

&lt;p&gt;&lt;code&gt;clustat&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OUTPUT&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cluster Status for mycluster @ Fri Apr 21 14:00:22

Member Status: Quorate

Member Name             ID   Status
------ ----             ---- ------
192.168.1.2                    1 Online, Local
192.168.1.3                2 Online
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;TESTING CLUSTER NODES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;bring down a node&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.3 --stop&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Do &lt;code&gt;clustat&lt;/code&gt; to check status of all nodes&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OUTPUT&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cluster Status for mycluster @ Fri Apr 21 14:00:22

Member Status: Inquorate

Member Name             ID   Status
------ ----             ---- ------
192.168.1.2                1 Online, Local
192.168.1.3                2 Offline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the node that is down, clustat give an error saying: "Could not connect to CMAN: No such file or directory"&lt;/p&gt;

&lt;p&gt;start the offline node&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ccs -h 192.168.1.3 --start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;THE END&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>clustering</category>
      <category>centos</category>
      <category>highavailability</category>
    </item>
    <item>
      <title>Setup a simple DNS server in CentOS</title>
      <dc:creator>shema-surge</dc:creator>
      <pubDate>Mon, 10 Apr 2023 14:28:47 +0000</pubDate>
      <link>https://dev.to/shemasurge/setup-a-simple-dns-server-in-centos-3ecc</link>
      <guid>https://dev.to/shemasurge/setup-a-simple-dns-server-in-centos-3ecc</guid>
      <description>&lt;p&gt;Let's Begin with a simple question,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WHAT IS DNS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DNS (Domain Name System) is like a phonebook for the internet. It is very difficult to remember the phone number of all your contacts but it is easy to remember their names.&lt;br&gt;
To make calling people easier, a phonebook matches your contact's name or alias to their phone number so that you don't have to remember their numbers.&lt;/p&gt;

&lt;p&gt;Same goes for the internet, it is easy to remember the domain name of a website like &lt;a href="https://dev.to"&gt;https://dev.to&lt;/a&gt; than it is to remember its IP address. But computers do not recognize each other on a network using domain names, they use IP adresses. Therefore, the primary role of the DNS is to translate a domain name to an IP address.&lt;/p&gt;

&lt;p&gt;For a more detailed explanation of how DNS works, checkout this link &lt;a href="https://www.cloudflare.com/learning/dns/what-is-dns/" rel="noopener noreferrer"&gt;https://www.cloudflare.com/learning/dns/what-is-dns/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will be using bind, a suite of software for interacting with DNS&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Login as root&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

su


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Install Bind&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;BIND (Berkeley Internet Name Domain) is the most widely used DNS (Domain Name System) server software on the Internet. It is an open-source implementation of the DNS protocol, originally developed at the University of California, Berkeley, and now maintained by the Internet Systems Consortium.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

yum install bind bind-utils -y


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Change ip address to static&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After installing bind, we will change the dynamically allocated ip address to a static one, 192.168.1.2/24.&lt;/p&gt;

&lt;p&gt;To do this, edit the ifcfg file for your network interface (enp0s3 or eth0 or ....):&lt;/p&gt;

&lt;p&gt;Note: Network interfaces can vary in naming, my centos came with enp0s3 so i'll stick with it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

vim /etc/sysconfig/network-scripts/ifcfg-enp0s3


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, we'll add the ip address,network mask, and a default gateway and a DNS server address:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

IPADDR=192.168.1.2
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=192.168.1.2


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Notice that the DNS i gave it matches the ip address of the server such that it can query itself.&lt;/p&gt;

&lt;p&gt;Now edit BOOTPROTO and change it from dhcp to none,since we no longer optain an ip address from a dhcpd server.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

BOOTPROTO=none


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0r4gadve1mmnyjvs23z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0r4gadve1mmnyjvs23z.png" alt="IP configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, we'll need to restart NetworkManager&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

systemctl restart NetworkManager


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and bing up our network interface&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ifup enp0s3


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To test if it works ping yourself&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ping 192.168.1.2


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 4: DNS Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, we'll edit the named.conf file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

vim /etc/named.conf


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;in the vim editor do &lt;code&gt;:set number&lt;/code&gt; to show line numbers&lt;/p&gt;

&lt;p&gt;In the options section on line 13, add your the server ip address to the list of ip addresses bind listens to.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;listen-on port 53 {127.0.0.1; 192.168.1.2; };&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And add the 192.168.1.0/24 subnet to the list of ip addresses allowed to query our DNS on line 21:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;allow-query {localhost; 192.168.1.0/24; };&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now all clients with an ip address in 192.168.1.0/24 subnet can query our DNS&lt;/p&gt;

&lt;p&gt;After line 57, add the following lines,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

zone "example.com" {
    type master;
    file "forward.example.zone";
    allow-update {none;};
};


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsuclkm3xmqukzg3vx1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsuclkm3xmqukzg3vx1g.png" alt="named.conf sample"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This specifies our domain to be example.com, type master signifies that the DNS Server has autority over this zone and can allow or block queries to this zone &lt;/p&gt;

&lt;p&gt;forward.example.zone is a forward zone file for example.com, it contains information that allows the DNS to resolve example.com to 192.168.1.2&lt;/p&gt;

&lt;p&gt;Now we'll create the forward zone file for example.com,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

cp /var/named/named.localhost /var/named/forward.example.zone


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;change the forward zone file's group to named group&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

chgrp named /var/named/forward.example.zone


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now edit your forward zone file,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

vim /var/named/forward.example.com


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdy8omkzngmxjtxrnxpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdy8omkzngmxjtxrnxpc.png" alt="forward zone file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NOTE: please remember to end every domain name with a "." in the zone file, or else you'll get errors.&lt;/p&gt;

&lt;p&gt;To check if the named.conf file does not have errors,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

named-checkconf /etc/named.conf


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;No output means there are not errors.&lt;/p&gt;

&lt;p&gt;To check if the zone file is correctly configured,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

named-checkzone example.com /var/named/forward.example.com


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When the output says &lt;code&gt;zone example.com/IN: loaded serial 0, OK&lt;/code&gt;, then it was configured correctly.&lt;/p&gt;

&lt;p&gt;Note: named-checkzone takes the domain specified in the /etc/named.conf file as a parameter.&lt;/p&gt;

&lt;p&gt;Now we'll need to restart named.service&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

systemctl restart named.service


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step5: testing our DNS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;nslookup&lt;/strong&gt; is a command-line tool used to query the Domain Name System (DNS) to obtain information about DNS records for a specific domain name or IP address&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

nslookup example.com


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The output should like this,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1a0o9gx659mtbhrvttln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1a0o9gx659mtbhrvttln.png" alt="nslookup output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dig&lt;/strong&gt; command-line tool is used to query DNS servers to obtain information about domain names, IP addresses, and DNS records. "dig" is short for "domain information groper".&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

dig example.com


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above command should provide details about the DNS Server&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4w0ytzxrf6rbwzoa64z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4w0ytzxrf6rbwzoa64z.png" alt="DIG output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope you learnt something, until next time.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>dns</category>
      <category>centos</category>
    </item>
    <item>
      <title>Writing custom middleware functions in NodeJS</title>
      <dc:creator>shema-surge</dc:creator>
      <pubDate>Tue, 12 Jul 2022 19:19:03 +0000</pubDate>
      <link>https://dev.to/shemasurge/writing-custom-middleware-functions-in-nodejs-26ee</link>
      <guid>https://dev.to/shemasurge/writing-custom-middleware-functions-in-nodejs-26ee</guid>
      <description>&lt;p&gt;Middleware is any code that runs on the server between getting a request and a response. Middleware functions in NodeJS have access to the request object, the response object and the next function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function middleFunc(req,res,next){
    req.message:'Hello'
    next()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the function middleFunc is a middleware function that takes three parameters: req,res,and next. The function sets a req.message to 'Hello'.&lt;/p&gt;

&lt;p&gt;Middleware functions do not end the request-response cycle but they have to call &lt;code&gt;next()&lt;/code&gt; to either pass execution to the next middleware function or the request handler itself. If &lt;code&gt;next()&lt;/code&gt; function is not called, the request will hang.&lt;/p&gt;

&lt;p&gt;A middleware function can be run by passing it between the path and callback function of the request handler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.get('/',middleFunc,(req,res)=&amp;gt;{
    res.json(req.message)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, middleFunc will run first then when next() is called, the execution is passed to the request handler which prints the message.&lt;/p&gt;

&lt;p&gt;It is also possible to rewrite the middleware function as an Application-level middleware like this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.use((req,res,next)=&amp;gt;{
    req.message = 'Hello'
    next()
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
