#!/usr/bin/perl
#
use strict;
use warnings;

my $in = shift;
my $ssh = "ssh -o StrictHostKeyChecking=no -q -l core";
my $disk = "ls -al /dev/disk/by-id/wwn-*";
my $hostfile = "/etc/hosts";
my $tdisk = 1;
chomp(my $pwd = `pwd`);
my $lsop_yaml = "$pwd/local-storage-operator.yaml";
my $ocsop_yaml = "$pwd/ocs-operator.yaml";
my $ocscl_yaml = "$pwd/ocs-cluster-service.yaml";
my $ocssc_yaml = "$pwd/ocs-cluster-storagec.yaml";
my (@nodes,@sdc,@sdb,$data,$run,$rtn);

unless($in) {
  print "Error on cluster input\n";
  exit;
}

my @hosts = grep(/$in/,&read_file($hostfile));
@hosts = grep(/storage/,@hosts);

foreach my $h (@hosts) {
  my ($ip,$fqdn,$host) = split(/\s+/,$h);
  push(@nodes,$fqdn);
  my @d = `$ssh $ip "$disk"`;
  my ($s1,@d1) = &format_id_array(@d);
  push(@sdb,$s1);
  @sdc = (@sdc,@d1);
}

unless($nodes[2]) {
  print "3 nodes not found check input\n";
  exit;
}

unless($sdb[2]) {
  print "3 x sdb not found check nodes\n";
  exit;
}

unless($sdc[2]) {
  print "3 x sdc not found check nodes\n";
  exit;
}

my $disks = qq($sdc[0]
        $sdc[1]
        $sdc[2]);

if($sdc[5]) {
  $tdisk = 2;
  $disks = qq($sdc[0]
        $sdc[1]
        $sdc[2]
        $sdc[3]
        $sdc[4]
        $sdc[5]);
}
if($sdc[8]) {
  $tdisk = 3;
  $disks = qq($sdc[0]
        $sdc[1]
        $sdc[2]
        $sdc[3]
        $sdc[4]
        $sdc[5]
        $sdc[6]
        $sdc[7]
        $sdc[8]);
}

$data = qq(
---
apiVersion: v1
kind: Namespace
metadata:
  name: local-storage
---
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: local-storage-operatorgroup
  namespace: local-storage
spec:
  serviceAccount:
    metadata:
      creationTimestamp: null
  targetNamespaces:
  - local-storage
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: local-storage-operator
  namespace: local-storage
spec:
  channel: "4.4"
  name: local-storage-operator
  source: redhat-operators
  sourceNamespace: openshift-marketplace
);

print "Creating YAML for Local Storage Operator '$lsop_yaml'\n";

&write_file($lsop_yaml,$data);

$data = qq(
---
apiVersion: v1
kind: Namespace
metadata:
  labels:
    openshift.io/cluster-monitoring: "true"
  name: openshift-storage
spec: {}
---
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: openshift-storage-operatorgroup
  namespace: openshift-storage
spec:
  serviceAccount:
    metadata:
      creationTimestamp: null
  targetNamespaces:
  - openshift-storage
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: ocs-operator
  namespace: openshift-storage
spec:
  channel: stable-4.3
  name: ocs-operator
  source: redhat-operators
  sourceNamespace: openshift-marketplace
);

print "Creating YAML for OCS Operator '$ocsop_yaml'\n";

&write_file($ocsop_yaml,$data);

$data = qq(
---
apiVersion: "local.storage.openshift.io/v1"
kind: "LocalVolume"
metadata:
  name: "local-file"
  namespace: "local-storage"
spec:
  nodeSelector:
    nodeSelectorTerms:
    - matchExpressions:
        - key: cluster.ocs.openshift.io/openshift-storage
          operator: In
          values:
          - ""
  storageClassDevices:
    - storageClassName: "localfile"
      volumeMode: Filesystem
      devicePaths:
        $sdb[0]
        $sdb[1]
        $sdb[2]
---
apiVersion: "local.storage.openshift.io/v1"
kind: "LocalVolume"
metadata:
  name: "local-block"
  namespace: "local-storage"
spec:
  nodeSelector:
    nodeSelectorTerms:
    - matchExpressions:
        - key: cluster.ocs.openshift.io/openshift-storage
          operator: In
          values:
          - ""
  storageClassDevices:
    - storageClassName: "localblock"
      volumeMode: Block
      devicePaths:
        $disks
);

print "Creating YAML for Local Storage Class '$ocssc_yaml'\n";

&write_file($ocssc_yaml,$data);

$data = qq(
apiVersion: ocs.openshift.io/v1
kind: StorageCluster
metadata:
  name: ocs-storagecluster
  namespace: openshift-storage
spec:
  manageNodes: false
  monPVCTemplate:
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1
      storageClassName: localfile
      volumeMode: Filesystem
  storageDeviceSets:
  - count: $tdisk
    dataPVCTemplate:
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1
        storageClassName: localblock
        volumeMode: Block
    name: ocs-deviceset
    placement: {}
    portable: true
    replica: 3
    resources: {}
);

print "Creating YAML for OCS Cluster '$ocscl_yaml'\n";

&write_file($ocscl_yaml,$data);

print "Running the following Oc commands\n";

$run = qq(
oc create -f $lsop_yaml
oc create -f $ocsop_yaml
oc label node $nodes[0] cluster.ocs.openshift.io/openshift-storage=''
oc label node $nodes[1] cluster.ocs.openshift.io/openshift-storage=''
oc label node $nodes[2] cluster.ocs.openshift.io/openshift-storage=''
sleep 30
oc create -f $ocssc_yaml
sleep 30
oc adm taint nodes $nodes[0] node.ocs.openshift.io/storage=true:NoSchedule
oc adm taint nodes $nodes[1] node.ocs.openshift.io/storage=true:NoSchedule
oc adm taint nodes $nodes[2] node.ocs.openshift.io/storage=true:NoSchedule
oc create -f $ocscl_yaml
);

print "$run\n";
$rtn = `$run`;

print "Oc output\n$rtn\n";

## SUBS

sub format_id_array {
  my @d = @_;
  my ($i,@s,$s1,@d1);
  ($i) = grep(/sdb/,@d);
  if($i =~ m/\s+(\/dev\/disk\/by-id\/.*)\s+->/g) {
    $s1 = "- $1";
  }
  (@d) = grep(/sdc|sdd|sde/,@d);
  foreach my $i (@d) {
    if($i =~ m/\s+(\/dev\/disk\/by-id\/.*)\s+->/g) {
      push(@d1,"- $1");
    }
  }
  return($s1,@d1);
}

sub read_file {
  my ($file) = @_;
  my (@r,$l);
  open(FH, "<$file");
  while($l = <FH>) {
    chomp($l);
    push(@r,$l);
  }
  close(FH);
  return(@r);
}

sub write_file {
  my ($file,$data) = @_;
  open(FH, ">$file");
  print FH "$data\n";
  close(FH)
}
