Monty  Boehm

Monty Boehm

1678855500

Flagger: Progressive Delivery Kubernetes Operator

Flagger

Flagger is a progressive delivery tool that automates the release process for applications running on Kubernetes. It reduces the risk of introducing a new software version in production by gradually shifting traffic to the new version while measuring metrics and running conformance tests.

flagger-overview

Flagger implements several deployment strategies (Canary releases, A/B testing, Blue/Green mirroring) and integrates with various Kubernetes ingress controllers, service mesh, and monitoring solutions.

Flagger is a Cloud Native Computing Foundation project and part of the Flux family of GitOps tools.

Documentation

Flagger documentation can be found at fluxcd.io/flagger.

Adopters

Our list of production users has moved to https://fluxcd.io/adopters/#flagger.

If you are using Flagger, please submit a PR to add your organization to the list!

Canary CRD

Flagger takes a Kubernetes deployment and optionally a horizontal pod autoscaler (HPA), then creates a series of objects (Kubernetes deployments, ClusterIP services, service mesh, or ingress routes). These objects expose the application on the mesh and drive the canary analysis and promotion.

Flagger keeps track of ConfigMaps and Secrets referenced by a Kubernetes Deployment and triggers a canary analysis if any of those objects change. When promoting a workload in production, both code (container images) and configuration (config maps and secrets) are being synchronized.

For a deployment named podinfo, a canary promotion can be defined using Flagger's custom resource:

apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  # service mesh provider (optional)
  # can be: kubernetes, istio, linkerd, appmesh, nginx, skipper, contour, gloo, supergloo, traefik, osm
  # for SMI TrafficSplit can be: smi:v1alpha1, smi:v1alpha2, smi:v1alpha3
  provider: istio
  # deployment reference
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  # the maximum time in seconds for the canary deployment
  # to make progress before it is rollback (default 600s)
  progressDeadlineSeconds: 60
  # HPA reference (optional)
  autoscalerRef:
    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    name: podinfo
  service:
    # service name (defaults to targetRef.name)
    name: podinfo
    # ClusterIP port number
    port: 9898
    # container port name or number (optional)
    targetPort: 9898
    # port name can be http or grpc (default http)
    portName: http
    # add all the other container ports
    # to the ClusterIP services (default false)
    portDiscovery: true
    # HTTP match conditions (optional)
    match:
      - uri:
          prefix: /
    # HTTP rewrite (optional)
    rewrite:
      uri: /
    # request timeout (optional)
    timeout: 5s
  # promote the canary without analysing it (default false)
  skipAnalysis: false
  # define the canary analysis timing and KPIs
  analysis:
    # schedule interval (default 60s)
    interval: 1m
    # max number of failed metric checks before rollback
    threshold: 10
    # max traffic percentage routed to canary
    # percentage (0-100)
    maxWeight: 50
    # canary increment step
    # percentage (0-100)
    stepWeight: 5
    # validation (optional)
    metrics:
    - name: request-success-rate
      # builtin Prometheus check
      # minimum req success rate (non 5xx responses)
      # percentage (0-100)
      thresholdRange:
        min: 99
      interval: 1m
    - name: request-duration
      # builtin Prometheus check
      # maximum req duration P99
      # milliseconds
      thresholdRange:
        max: 500
      interval: 30s
    - name: "database connections"
      # custom metric check
      templateRef:
        name: db-connections
      thresholdRange:
        min: 2
        max: 100
      interval: 1m
    # testing (optional)
    webhooks:
      - name: "conformance test"
        type: pre-rollout
        url: http://flagger-helmtester.test/
        timeout: 5m
        metadata:
          type: "helmv3"
          cmd: "test run podinfo -n test"
      - name: "load test"
        type: rollout
        url: http://flagger-loadtester.test/
        metadata:
          cmd: "hey -z 1m -q 10 -c 2 http://podinfo.test:9898/"
    # alerting (optional)
    alerts:
      - name: "dev team Slack"
        severity: error
        providerRef:
          name: dev-slack
          namespace: flagger
      - name: "qa team Discord"
        severity: warn
        providerRef:
          name: qa-discord
      - name: "on-call MS Teams"
        severity: info
        providerRef:
          name: on-call-msteams

For more details on how the canary analysis and promotion works please read the docs.

Features

Service Mesh

FeatureApp MeshIstioLinkerdKumaOSMKubernetes CNI
Canary deployments (weighted traffic)✔️✔️✔️✔️✔️
A/B testing (headers and cookies routing)✔️✔️
Blue/Green deployments (traffic switch)✔️✔️✔️✔️✔️✔️
Blue/Green deployments (traffic mirroring)✔️
Webhooks (acceptance/load testing)✔️✔️✔️✔️✔️✔️
Manual gating (approve/pause/resume)✔️✔️✔️✔️✔️✔️
Request success rate check (L7 metric)✔️✔️✔️✔️✔️
Request duration check (L7 metric)✔️✔️✔️✔️✔️
Custom metric checks✔️✔️✔️✔️✔️✔️

Ingress

FeatureContourGlooNGINXSkipperTraefikApache APISIX
Canary deployments (weighted traffic)✔️✔️✔️✔️✔️✔️
A/B testing (headers and cookies routing)✔️✔️✔️
Blue/Green deployments (traffic switch)✔️✔️✔️✔️✔️✔️
Webhooks (acceptance/load testing)✔️✔️✔️✔️✔️✔️
Manual gating (approve/pause/resume)✔️✔️✔️✔️✔️✔️
Request success rate check (L7 metric)✔️✔️✔️✔️✔️
Request duration check (L7 metric)✔️✔️✔️✔️✔️
Custom metric checks✔️✔️✔️✔️✔️✔️

Networking Interface

FeatureGateway APISMI
Canary deployments (weighted traffic)✔️✔️
A/B testing (headers and cookies routing)✔️
Blue/Green deployments (traffic switch)✔️✔️
Blue/Green deployments (traffic mirrroring)
Webhooks (acceptance/load testing)✔️✔️
Manual gating (approve/pause/resume)✔️✔️
Request success rate check (L7 metric)
Request duration check (L7 metric)
Custom metric checks✔️✔️

For all Gateway API implementations like Contour or Istio and SMI compatible service mesh solutions like Nginx Service Mesh, Prometheus MetricTemplates can be used to implement the request success rate and request duration checks.

Roadmap

GitOps Toolkit compatibility

  • Migrate Flagger to Kubernetes controller-runtime and kubebuilder
  • Make the Canary status compatible with kstatus
  • Make Flagger emit Kubernetes events compatible with Flux v2 notification API
  • Integrate Flagger into Flux v2 as the progressive delivery component

Integrations

  • Add support for ingress controllers like HAProxy, ALB, and Apache APISIX
  • Add support for Knative Serving

Contributing

Flagger is Apache 2.0 licensed and accepts contributions via GitHub pull requests. To start contributing please read the development guide.

When submitting bug reports please include as many details as possible:

  • which Flagger version
  • which Kubernetes version
  • what configuration (canary, ingress and workloads definitions)
  • what happened (Flagger and Proxy logs)

Communication

Here is a list of good entry points into our community, how we stay in touch and how you can meet us as a team.

  • Slack: Join in and talk to us in the #flagger channel on CNCF Slack.
  • Public meetings: We run weekly meetings - join one of the upcoming dev meetings from the Flux calendar.
  • Blog: Stay up to date with the latest news on the Flux blog.
  • Mailing list: To be updated on Flux and Flagger progress regularly, please join the flux-dev mailing list.

Subscribing to the flux-dev calendar

To add the meetings to your e.g. Google calendar

  1. visit the Flux calendar
  2. click on "Subscribe to Calendar" at the very bottom of the page
  3. copy the iCalendar URL
  4. open e.g. your Google calendar
  5. find the "add calendar" option
  6. choose "add by URL"
  7. paste iCalendar URL (ends with .ics)
  8. done

Download Details:

Author: fluxcd
Source Code: https://github.com/fluxcd/flagger 
License: Apache-2.0 license

#nginx #kubernetes #testing #go 

What is GEEK

Buddha Community

Flagger: Progressive Delivery Kubernetes Operator
Christa  Stehr

Christa Stehr

1602964260

50+ Useful Kubernetes Tools for 2020 - Part 2

Introduction

Last year, we provided a list of Kubernetes tools that proved so popular we have decided to curate another list of some useful additions for working with the platform—among which are many tools that we personally use here at Caylent. Check out the original tools list here in case you missed it.

According to a recent survey done by Stackrox, the dominance Kubernetes enjoys in the market continues to be reinforced, with 86% of respondents using it for container orchestration.

(State of Kubernetes and Container Security, 2020)

And as you can see below, more and more companies are jumping into containerization for their apps. If you’re among them, here are some tools to aid you going forward as Kubernetes continues its rapid growth.

(State of Kubernetes and Container Security, 2020)

#blog #tools #amazon elastic kubernetes service #application security #aws kms #botkube #caylent #cli #container monitoring #container orchestration tools #container security #containers #continuous delivery #continuous deployment #continuous integration #contour #developers #development #developments #draft #eksctl #firewall #gcp #github #harbor #helm #helm charts #helm-2to3 #helm-aws-secret-plugin #helm-docs #helm-operator-get-started #helm-secrets #iam #json #k-rail #k3s #k3sup #k8s #keel.sh #keycloak #kiali #kiam #klum #knative #krew #ksniff #kube #kube-prod-runtime #kube-ps1 #kube-scan #kube-state-metrics #kube2iam #kubeapps #kubebuilder #kubeconfig #kubectl #kubectl-aws-secrets #kubefwd #kubernetes #kubernetes command line tool #kubernetes configuration #kubernetes deployment #kubernetes in development #kubernetes in production #kubernetes ingress #kubernetes interfaces #kubernetes monitoring #kubernetes networking #kubernetes observability #kubernetes plugins #kubernetes secrets #kubernetes security #kubernetes security best practices #kubernetes security vendors #kubernetes service discovery #kubernetic #kubesec #kubeterminal #kubeval #kudo #kuma #microsoft azure key vault #mozilla sops #octant #octarine #open source #palo alto kubernetes security #permission-manager #pgp #rafay #rakess #rancher #rook #secrets operations #serverless function #service mesh #shell-operator #snyk #snyk container #sonobuoy #strongdm #tcpdump #tenkai #testing #tigera #tilt #vert.x #wireshark #yaml

Hunter  Krajcik

Hunter Krajcik

1674813120

Validate Multi Step Form Using jQuery

In this article, we will see how to validate multi step form wizard using jquery. Here, we will learn to validate the multi step form using jquery. First, we create the multi step form using bootstrap. Also, in this example, we are not using any jquery plugin for multi step form wizard.

So, let's see jquery multi step form with validation, how to create multi step form, multi step form wizard with jquery validation, bootstrap 4 multi step form wizard with validation, multi step form bootstrap 5, and jQuery multi step form with validation and next previous navigation.

Add HTML:

<html lang="en">
</head>
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap" rel="stylesheet">
</head>
<body>  
    <div class="main">
      <h3>How To Validate Multi Step Form Using jQuery - Websolutionstuff</h3>
        <form id="multistep_form">
            <!-- progressbar -->
            <ul id="progress_header">
                <li class="active"></li>
                <li></li>
                <li></li>
            </ul>
            <!-- Step 01 -->
            <div class="multistep-box">
                <div class="title-box">
                    <h2>Create your account</h2>
                </div>
                <p>
                    <input type="text" name="email" placeholder="Email" id="email">
                    <span id="error-email"></span>
                </p>
                <p>
                    <input type="password" name="pass" placeholder="Password" id="pass">
                    <span id="error-pass"></span>
                </p>
                <p>
                    <input type="password" name="cpass" placeholder="Confirm Password" id="cpass">
                    <span id="error-cpass"></span>
                </p>
                <p class="nxt-prev-button"><input type="button" name="next" class="fs_next_btn action-button" value="Next" /></p>
            </div>
            <!-- Step 02 -->
            <div class="multistep-box">
                <div class="title-box">
                    <h2>Social Profiles</h2>
                </div>
                <p>
                    <input type="text" name="twitter" placeholder="Twitter" id="twitter">
                    <span id="error-twitter"></span>
                </p>
                <p>
                    <input type="text" name="facebook" placeholder="Facebook" id="facebook">
                    <span id="error-facebook"></span>
                </p>
                <p>
                    <input type="text" name="linkedin" placeholder="Linkedin" id="linkedin">
                    <span id="error-linkedin"></span>
                </p>
                <p class="nxt-prev-button">
                    <input type="button" name="previous" class="previous action-button" value="Previous" />
                    <input type="button" name="next" class="ss_next_btn action-button" value="Next" />
                </p>
            </div>
            <!-- Step 03 -->
            <div class="multistep-box">
                <div class="title-box">
                    <h2>Personal Details</h2>
                </div>
                <p>
                    <input type="text" name="fname" placeholder="First Name" id="fname">
                    <span id="error-fname"></span>
                </p>
                <p>
                    <input type="text" name="lname" placeholder="Last Name" id="lname">
                    <span id="error-lname"></span>
                </p>
                <p>
                    <input type="text" name="phone" placeholder="Phone" id="phone">
                    <span id="error-phone"></span>
                </p>
                <p>
                    <textarea name="address" placeholder="Address" id="address"></textarea>
                    <span id="error-address"></span>
                </p>
                <p class="nxt-prev-button"><input type="button" name="previous" class="previous action-button" value="Previous" />
                    <input type="submit" name="submit" class="submit_btn ts_next_btn action-button" value="Submit" />
                </p>
            </div>
        </form>
        <h1>You are successfully logged in</h1>
    </div>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.0/jquery.easing.js" type="text/javascript"></script>
</body>
</html>

Add CSS:

body {
    display: inline-block;
    width: 100%;
    height: 100vh;
    overflow: hidden;
    background-image: url("https://img1.akspic.com/image/80377-gadget-numeric_keypad-input_device-electronic_device-space_bar-3840x2160.jpg");
    background-repeat: no-repeat;
    background-size: cover;
    position: relative;
    margin: 0;
    font-weight: 400;
    font-family: 'Roboto', sans-serif;
}
body:before {
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    background: rgba(0,0,0,0.5);
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}
.main {
    position: absolute;
    left: 0;
    right: 0;
    top: 30px;
    margin: 0 auto;
    height: 515px;
}
input:-internal-autofill-selected {
    background-color: #fff !important;
}
#multistep_form {
    width: 550px;
    margin: 0 auto;
    text-align: center;
    position: relative;
    height: 100%;
    z-index: 999;
    opacity: 1; 
    visibility: visible; 
}
/*progress header*/
#progress_header {
    overflow: hidden;
    margin: 0 auto 30px;
    padding: 0;
}
#progress_header li {
    list-style-type: none;
    width: 33.33%;
    float: left;
    position: relative;
    font-size: 16px;
    font-weight: bold;
    font-family: monospace;
    color: #fff;
    text-transform: uppercase;
}
#progress_header li:after {
    width: 35px;
    line-height: 35px;
    display: block;
    font-size: 22px;
    color: #888;
    font-family: monospace;
    background-color: #fff;
    border-radius: 100px;
    margin: 0 auto;
    background-repeat: no-repeat;
    font-family: 'Roboto', sans-serif;
}
#progress_header li:nth-child(1):after {
    content: "1";
}
#progress_header li:nth-child(2):after {
    content: "2";
}
#progress_header li:nth-child(3):after {
    content: "3";
}
#progress_header li:before {
    content: '';
    width: 100%;
    height: 5px;
    background: #fff;
    position: absolute;
    left: -50%;
    top: 50%;
    z-index: -1;
}
#progress_header li:first-child:before {
    content: none;
}
#progress_header li.active:before, 
#progress_header li.active:after {
    background-image: linear-gradient(to right top, #35e8c3, #36edbb, #3df2b2, #4af7a7, #59fb9b) !important;
    color: #fff !important;
    transition: all 0.5s;
}
/*title*/
.title-box {
    width: 100%;
    margin: 0 0 30px 0;
}
.title-box h2 {
    font-size: 22px;
    text-transform: uppercase;
    color: #2C3E50;
    margin: 0;
    font-family: cursive;
    display: inline-block;
    position: relative;
    padding: 0 0 10px 0;
    font-family: 'Roboto', sans-serif;
}
.title-box h2:before {
    content: "";
    background: #6ddc8b;
    width: 70px;
    height: 2px;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    margin: 0 auto;
    display: block;
}
.title-box h2:after {
    content: "";
    background: #6ddc8b;
    width: 50px;
    height: 2px;
    position: absolute;
    bottom: -5px;
    left: 0;
    right: 0;
    margin: 0 auto;
    display: block;
}
/*Input and Button*/
.multistep-box {
    background: white;
    border: 0 none;
    border-radius: 3px;
    box-shadow: 1px 1px 55px 3px rgba(255, 255, 255, 0.4);
    padding: 30px 30px;
    box-sizing: border-box;
    width: 80%;
    margin: 0 10%;
    position: absolute;
}
.multistep-box:not(:first-of-type) {
    display: none;
}
.multistep-box p {
    margin: 0 0 12px 0;
    text-align: left;
}
.multistep-box span {
    font-size: 12px;
    color: #FF0000;
}
input, textarea {
    padding: 15px;
    border: 1px solid #ccc;
    border-radius: 3px;
    margin: 0;
    width: 100%;
    box-sizing: border-box;
    font-family: 'Roboto', sans-serif;
    color: #2C3E50;
    font-size: 13px;
    transition: all 0.5s;
    outline: none;
}
input:focus, textarea:focus {
    box-shadow: inset 0px 0px 50px 2px rgb(0,0,0,0.1);
}
input.box_error, textarea.box_error {
    border-color: #FF0000;
    box-shadow: inset 0px 0px 50px 2px rgb(255,0,0,0.1);
}
input.box_error:focus, textarea.box_error:focus {
    box-shadow: inset 0px 0px 50px 2px rgb(255,0,0,0.1);
}
p.nxt-prev-button {
    margin: 25px 0 0 0;
    text-align: center;
}
.action-button {
    width: 100px;
    font-weight: bold;
    color: white;
    border: 0 none;
    border-radius: 1px;
    cursor: pointer;
    padding: 10px 5px;
    margin: 0 5px;
    background-image: linear-gradient(to right top, #35e8c3, #36edbb, #3df2b2, #4af7a7, #59fb9b);
    transition: all 0.5s;
}
.action-button:hover, 
.action-button:focus {
    box-shadow: 0 0 0 2px white, 0 0 0 3px #6ce199;
}
.form_submited #multistep_form {
    opacity: 0; 
    visibility: hidden; 
}
.form_submited h1 {
    -webkit-background-clip: text;
    transform: translate(0%, 0%);
    -webkit-transform: translate(0%, 0%);
    transition: all 0.3s ease;
    opacity: 1;
    visibility: visible;
}
h1 {
    margin: 0;
    text-align: center;
    font-size: 90px;
    background-image: linear-gradient(to right top, #35e8c3, #36edbb, #3df2b2, #4af7a7, #59fb9b) !important;
    background-image: linear-gradient(to right top, #35e8c3, #36edbb, #3df2b2, #4af7a7, #59fb9b) !important;
    color: transparent;
    -webkit-background-clip: text;
    -webkit-background-clip: text;
    transform: translate(0%, -80%);
    -webkit-transform: translate(0%, -80%);
    transition: all 0.3s ease;
    opacity: 0;
    visibility: hidden;
    position: absolute;
    left: 0;
    right: 0;
    margin: 0 auto;
    text-align: center;
    top: 50%;
}
h3{
  color:#fff;
  text-align:center;
  margin-bottom:20px;
}

Add jQuery:

var current_slide, next_slide, previous_slide;
var left, opacity, scale;
var animation;

var error = false;

// email validation
$("#email").keyup(function() {
    var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
    if (!emailReg.test($("#email").val())) {
        $("#error-email").text('Please enter an Email addres.');
        $("#email").addClass("box_error");
        error = true;
    } else {
        $("#error-email").text('');
        error = false;
        $("#email").removeClass("box_error");
    }
});
// password validation
$("#pass").keyup(function() {
    var pass = $("#pass").val();
    var cpass = $("#cpass").val();

    if (pass != '') {
        $("#error-pass").text('');
        error = false;
        $("#pass").removeClass("box_error");
    }
    if (pass != cpass && cpass != '') {
        $("#error-cpass").text('Password and Confirm Password is not matched.');
        error = true;
    } else {
        $("#error-cpass").text('');
        error = false;
    }
});
// confirm password validation
$("#cpass").keyup(function() {
    var pass = $("#pass").val();
    var cpass = $("#cpass").val();

    if (pass != cpass) {
        $("#error-cpass").text('Please enter the same Password as above.');
        $("#cpass").addClass("box_error");
        error = true;
    } else {
        $("#error-cpass").text('');
        error = false;
        $("#cpass").removeClass("box_error");
    }
});
// twitter
$("#twitter").keyup(function() {
    var twitterReg = /https?:\/\/twitter\.com\/(#!\/)?[a-z0-9_]+$/;
    if (!twitterReg.test($("#twitter").val())) {
        $("#error-twitter").text('Twitter link is not valid.');
        $("#twitter").addClass("box_error");
        error = true;
    } else {
        $("#error-twitter").text('');
        error = false;
        $("#twitter").removeClass("box_error");
    }
});
// facebook
$("#facebook").keyup(function() {
    var facebookReg = /^(https?:\/\/)?(www\.)?facebook.com\/[a-zA-Z0-9(\.\?)?]/;
    if (!facebookReg.test($("#facebook").val())) {
        $("#error-facebook").text('Facebook link is not valid.');
        $("#facebook").addClass("box_error");
        error = true;
    } else {
        $("#error-facebook").text('');
        error = false;
        $("#facebook").removeClass("box_error");
    }
});
// linkedin
$("#linkedin").keyup(function() {
    var linkedinReg = /(ftp|http|https):\/\/?(?:www\.)?linkedin.com(\w+:{0,1}\w*@)?(\S+)(:([0-9])+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
    if (!linkedinReg.test($("#linkedin").val())) {
        $("#error-linkedin").text('Linkedin link is not valid.');
        $("#linkedin").addClass("box_error");
        error = true;
    } else {
        $("#error-linkedin").text('');
        error = false;
        $("#linkedin").removeClass("box_error");
    }
});
// first name
$("#fname").keyup(function() {
    var fname = $("#fname").val();
    if (fname == '') {
        $("#error-fname").text('Enter your First name.');
        $("#fname").addClass("box_error");
        error = true;
    } else {
        $("#error-fname").text('');
        error = false;
    }
    if ((fname.length <= 2) || (fname.length > 20)) {
        $("#error-fname").text("User length must be between 2 and 20 Characters.");
        $("#fname").addClass("box_error");
        error = true;
    }
    if (!isNaN(fname)) {
        $("#error-fname").text("Only Characters are allowed.");
        $("#fname").addClass("box_error");
        error = true;
    } else {
        $("#fname").removeClass("box_error");
    }
});
// last name
$("#lname").keyup(function() {
    var lname = $("#lname").val();
    if (lname != lname) {
        $("#error-lname").text('Enter your Last name.');
        $("#lname").addClass("box_error");
        error = true;
    } else {
        $("#error-lname").text('');
        error = false;
    }
    if ((lname.length <= 2) || (lname.length > 20)) {
        $("#error-lname").text("User length must be between 2 and 20 Characters.");
        $("#lname").addClass("box_error");
        error = true;
    }
    if (!isNaN(lname)) {
        $("#error-lname").text("Only Characters are allowed.");
        $("#lname").addClass("box_error");
        error = true;
    } else {
        $("#lname").removeClass("box_error");
    }
});
// phone
$("#phone").keyup(function() {
    var phone = $("#phone").val();
    if (phone != phone) {
        $("#error-phone").text('Enter your Phone number.');
        $("#phone").addClass("box_error");
        error = true;
    } else {
        $("#error-phone").text('');
        error = false;
    }
    if (phone.length != 10) {
        $("#error-phone").text("Mobile number must be of 10 Digits only.");
        $("#phone").addClass("box_error");
        error = true;
    } else {
        $("#phone").removeClass("box_error");
    }
});
// address
$("#address").keyup(function() {
    var address = $("#address").val();
    if (address != address) {
        $("#error-address").text('Enter your Address.');
        $("#address").addClass("box_error");
        error = true;
    } else {
        $("#error-address").text('');
        error = false;
        $("#address").removeClass("box_error");
    }
});

// first step validation
$(".fs_next_btn").click(function() {
    // email
    if ($("#email").val() == '') {
        $("#error-email").text('Please enter an email address.');
        $("#email").addClass("box_error");
        error = true;
    } else {
        var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
        if (!emailReg.test($("#email").val())) {
            $("#error-email").text('Please insert a valid email address.');
            error = true;
        } else {
            $("#error-email").text('');
            $("#email").removeClass("box_error");
        }
    }
    // password
    if ($("#pass").val() == '') {
        $("#error-pass").text('Please enter a password.');
        $("#pass").addClass("box_error");
        error = true;
    }
    if ($("#cpass").val() == '') {
        $("#error-cpass").text('Please enter a Confirm password.');
        $("#cpass").addClass("box_error");
        error = true;
    } else {
        var pass = $("#pass").val();
        var cpass = $("#cpass").val();

        if (pass != cpass) {
            $("#error-cpass").text('Please enter the same password as above.');
            error = true;
        } else {
            $("#error-cpass").text('');
            $("#pass").removeClass("box_error");
            $("#cpass").removeClass("box_error");
        }
    }
    // animation
    if (!error) {
        if (animation) return false;
        animation = true;

        current_slide = $(this).parent().parent();
        next_slide = $(this).parent().parent().next();

        $("#progress_header li").eq($(".multistep-box").index(next_slide)).addClass("active");

        next_slide.show();
        current_slide.animate({
            opacity: 0
        }, {
            step: function(now, mx) {
                scale = 1 - (1 - now) * 0.2;
                left = (now * 50) + "%";
                opacity = 1 - now;
                current_slide.css({
                    'transform': 'scale(' + scale + ')'
                });
                next_slide.css({
                    'left': left,
                    'opacity': opacity
                });
            },
            duration: 800,
            complete: function() {
                current_slide.hide();
                animation = false;
            },
            easing: 'easeInOutBack'
        });
    }
});
// second step validation
$(".ss_next_btn").click(function() {
    // twitter
    if ($("#twitter").val() == '') {
        $("#error-twitter").text('twitter link is required.');
        $("#twitter").addClass("box_error");
        error = true;
    } else {
        var twitterReg = /https?:\/\/twitter\.com\/(#!\/)?[a-z0-9_]+$/;
        if (!twitterReg.test($("#twitter").val())) {
            $("#error-twitter").text('Twitter link is not valid.');
            error = true;
        } else {
            $("#error-twitter").text('');
            $("#twitter").removeClass("box_error");
        }
    }
    // facebook
    if ($("#facebook").val() == '') {
        $("#error-facebook").text('Facebook link is required.');
        $("#facebook").addClass("box_error");
        error = true;
    } else {
        var facebookReg = /^(https?:\/\/)?(www\.)?facebook.com\/[a-zA-Z0-9(\.\?)?]/;
        if (!facebookReg.test($("#facebook").val())) {
            $("#error-facebook").text('Facebook link is not valid.');
            error = true;
            $("#facebook").addClass("box_error");
        } else {
            $("#error-facebook").text('');
        }
    }
    // linkedin
    if ($("#linkedin").val() == '') {
        $("#error-linkedin").text('Linkedin link is required.');
        $("#linkedin").addClass("box_error");
        error = true;
    } else {
        var linkedinReg = /(ftp|http|https):\/\/?(?:www\.)?linkedin.com(\w+:{0,1}\w*@)?(\S+)(:([0-9])+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
        if (!linkedinReg.test($("#linkedin").val())) {
            $("#error-linkedin").text('Linkedin link is not valid.');
            error = true;
        } else {
            $("#error-linkedin").text('');
            $("#linkedin").removeClass("box_error");
        }
    }

    if (!error) {
        if (animation) return false;
        animation = true;

        current_slide = $(this).parent().parent();
        next_slide = $(this).parent().parent().next();

        $("#progress_header li").eq($(".multistep-box").index(next_slide)).addClass("active");

        next_slide.show();
        current_slide.animate({
            opacity: 0
        }, {
            step: function(now, mx) {
                scale = 1 - (1 - now) * 0.2;
                left = (now * 50) + "%";
                opacity = 1 - now;
                current_slide.css({
                    'transform': 'scale(' + scale + ')'
                });
                next_slide.css({
                    'left': left,
                    'opacity': opacity
                });
            },
            duration: 800,
            complete: function() {
                current_slide.hide();
                animation = false;
            },
            easing: 'easeInOutBack'
        });
    }

});

// third step validation
$(".ts_next_btn").click(function() {
    // first name
    if ($("#fname").val() == '') {
        $("#error-fname").text('Enter your First name.');
        $("#fname").addClass("box_error");
        error = true;
    } else {
        var fname = $("#fname").val();
        if (fname != fname) {
            $("#error-fname").text('First name is required.');
            error = true;
        } else {
            $("#error-fname").text('');
            error = false;
            $("#fname").removeClass("box_error");
        }
        if ((fname.length <= 2) || (fname.length > 20)) {
            $("#error-fname").text("User length must be between 2 and 20 Characters.");
            error = true;
        }
        if (!isNaN(fname)) {
            $("#error-fname").text("Only Characters are allowed.");
            error = true;
        } else {
            $("#fname").removeClass("box_error");
        }
    }
    // last name
    if ($("#lname").val() == '') {
        $("#error-lname").text('Enter your Last name.');
        $("#lname").addClass("box_error");
        error = true;
    } else {
        var lname = $("#lname").val();
        if (lname != lname) {
            $("#error-lname").text('Last name is required.');
            error = true;
        } else {
            $("#error-lname").text('');
            error = false;
        }
        if ((lname.length <= 2) || (lname.length > 20)) {
            $("#error-lname").text("User length must be between 2 and 20 Characters.");
            error = true;
        } 
        if (!isNaN(lname)) {
            $("#error-lname").text("Only Characters are allowed.");
            error = true;
        } else {
            $("#lname").removeClass("box_error");
        }
    }
    // phone
    if ($("#phone").val() == '') {
        $("#error-phone").text('Enter your Phone number.');
        $("#phone").addClass("box_error");
        error = true;
    } else {
        var phone = $("#phone").val();
        if (phone != phone) {
            $("#error-phone").text('Phone number is required.');
            error = true;
        } else {
            $("#error-phone").text('');
            error = false;
        }
        if (phone.length != 10) {
            $("#error-phone").text("Mobile number must be of 10 Digits only.");
            error = true;
        } else {
            $("#phone").removeClass("box_error");
        }
    }
    // address
    if ($("#address").val() == '') {
        $("#error-address").text('Enter your Address.');
        $("#address").addClass("box_error");
        error = true;
    } else {
        var address = $("#address").val();
        if (address != address) {
            $("#error-address").text('Address is required.');
            error = true;
        } else {
            $("#error-address").text('');
            $("#address").removeClass("box_error");
            error = false;
        }
    }

    if (!error) {
        if (animation) return false;
        animation = true;

        current_slide = $(this).parent().parent();
        next_slide = $(this).parent().parent().next();

        $("#progress_header li").eq($(".multistep-box").index(next_slide)).addClass("active");

        next_slide.show();
        current_slide.animate({
            opacity: 0
        }, {
            step: function(now, mx) {
                scale = 1 - (1 - now) * 0.2;
                left = (now * 50) + "%";
                opacity = 1 - now;
                current_slide.css({
                    'transform': 'scale(' + scale + ')'
                });
                next_slide.css({
                    'left': left,
                    'opacity': opacity
                });
            },
            duration: 800,
            complete: function() {
                current_slide.hide();
                animation = false;
            },
            easing: 'easeInOutBack'
        });
    }
});
// previous
$(".previous").click(function() {
    if (animation) return false;
    animation = true;

    current_slide = $(this).parent().parent();
    previous_slide = $(this).parent().parent().prev();

    $("#progress_header li").eq($(".multistep-box").index(current_slide)).removeClass("active");

    previous_slide.show();
    current_slide.animate({
        opacity: 0
    }, {
        step: function(now, mx) {
            scale = 0.8 + (1 - now) * 0.2;
            left = ((1 - now) * 50) + "%";
            opacity = 1 - now;
            current_slide.css({
                'left': left
            });
            previous_slide.css({
                'transform': 'scale(' + scale + ')',
                'opacity': opacity
            });
        },
        duration: 800,
        complete: function() {
            current_slide.hide();
            animation = false;
        },
        easing: 'easeInOutBack'
    });
});

$(".submit_btn").click(function() {
    if (!error){
        $(".main").addClass("form_submited");
    }
    return false;
})

 

Output:

how_to_validate_multi_step_form_using_jquery_output

Original article source at: https://websolutionstuff.com/

#jquery #validate #step 

Understanding Kubernetes Operators

Automation is one of the fundamental components that makes Kubernetes so robust as a containerization engine. Even complex cloud infrastructure creation can be automated in order to simplify the process of managing cloud deployments. Despite the capability of leveraging so many resources and components to support an application, your cloud environment can still be fairly manageable.

Despite the many tools available on Kubernetes, the effort to make cloud infrastructure management more scalable and automated is ongoing. Kubernetes operator is one of the tools designed to push automation past its limits. You can do so much more without having to rely on manual inputs every time.

Getting to Know Kubernetes Operators

A Kubernetes operator, by definition, is an orchestration framework. It is a tool that lets you orchestrate and maintain cloud infrastructures with little to no human input. Kubernetes define operators as software extensions designed to utilize custom resources to manage applications and their components.

Kubernetes operators are not complex at all. Operators use controllers and the Kubernetes API to handle packaging, deployment, management, and maintenance of applications and the custom resources that they need. The whole process is fully automated, plus you can still rely on _kubectl _tooling for commands and operations.

In other words, an operator is basically a custom Kubernetes controller that integrates custom resources for management purposes. You can define parameters and configurations inside the custom resources directly, and then let the operators translate those parameters and run autonomously. Kubernetes operators’ continuous nature is their defining factor.

#blog #kubernetes #automation #kubernetes api #kubernetes deployment #kubernetes operators

Iliana  Welch

Iliana Welch

1598403960

What Is a Kubernetes Operator and Why it Matters for SRE

Kubernetes is an open-source project that “containerizes” workloads and services and manages deployment and configurations. Released by Google in 2015, Kubernetes is now maintained by the  Cloud Native Computing Foundation. Since its release, it has become a worldwide phenomenon. The majority of cloud-native  companies use it, SaaS vendors offer commercial prebuilt versions, and there’s even an annual  convention!

What has made Kubernetes become such a fundamental service? A major factor is its automation capabilities. Kubernetes can automatically make changes to the configuration of deployed containers or even deploy new containers based on metrics it tracks or requests made by engineers. Having Kubernetes handle these processes saves time, eliminates toil, and increases consistency.

If these benefits sound familiar, it might be because they overlap with the philosophies of SRE. But how do you incorporate the automation of Kubernetes into your SRE practices? In this blog post, we’ll explain the Kubernetes Operator—the Kubernetes function at the heart of customized automation—and discuss how it can evolve your SRE solution.

What the Kubernetes Operator Can Do

In Kubernetes Operators: Automating the Container Orchestration Platform, authors Jason Dobies and Joshua Wood describe an Operator as “an automated Site Reliability Engineer for its application.” Given an SRE’s multifaceted experience and diverse workload, this is a bold statement. So what exactly can the Operator do?

#tutorial #devops #kubernetes #site reliability engineering #site reliability #site reliability engineer #site reliability engineering tools #kubernetes operators #kubernetes operator

Maud  Rosenbaum

Maud Rosenbaum

1601051854

Kubernetes in the Cloud: Strategies for Effective Multi Cloud Implementations

Kubernetes is a highly popular container orchestration platform. Multi cloud is a strategy that leverages cloud resources from multiple vendors. Multi cloud strategies have become popular because they help prevent vendor lock-in and enable you to leverage a wide variety of cloud resources. However, multi cloud ecosystems are notoriously difficult to configure and maintain.

This article explains how you can leverage Kubernetes to reduce multi cloud complexities and improve stability, scalability, and velocity.

Kubernetes: Your Multi Cloud Strategy

Maintaining standardized application deployments becomes more challenging as your number of applications and the technologies they are based on increase. As environments, operating systems, and dependencies differ, management and operations require more effort and extensive documentation.

In the past, teams tried to get around these difficulties by creating isolated projects in the data center. Each project, including its configurations and requirements were managed independently. This required accurately predicting performance and the number of users before deployment and taking down applications to update operating systems or applications. There were many chances for error.

Kubernetes can provide an alternative to the old method, enabling teams to deploy applications independent of the environment in containers. This eliminates the need to create resource partitions and enables teams to operate infrastructure as a unified whole.

In particular, Kubernetes makes it easier to deploy a multi cloud strategy since it enables you to abstract away service differences. With Kubernetes deployments you can work from a consistent platform and optimize services and applications according to your business needs.

The Compelling Attributes of Multi Cloud Kubernetes

Multi cloud Kubernetes can provide multiple benefits beyond a single cloud deployment. Below are some of the most notable advantages.

Stability

In addition to the built-in scalability, fault tolerance, and auto-healing features of Kubernetes, multi cloud deployments can provide service redundancy. For example, you can mirror applications or split microservices across vendors. This reduces the risk of a vendor-related outage and enables you to create failovers.

#kubernetes #multicloud-strategy #kubernetes-cluster #kubernetes-top-story #kubernetes-cluster-install #kubernetes-explained #kubernetes-infrastructure #cloud